[Help] 如果最终准备量化部署,是应该从int4的模型开始训练吗?
Is there an existing issue for this?
- [X] I have searched the existing issues
Current Behavior
我用peft的lora在 chatglm2 训练了一个Lora(参考了 @shibing624 https://github.com/shibing624/MedicalGPT 里面的方法),只训练了一个epoch。
训练后测试效果,发现如果缺省模式(fp16)输出,效果很稳定。 如果加载lora后,量化到8bit或者4bit运行,则结果非常不稳定,有时达到了部分训练后的效果,有时候和完全没训练的原始模型输出一样。
Expected Behavior
4bit量化效果的质量损失有这么大吗?而且8bit似乎也没什么优势?
我本来以为只会有一点点差异的。
还是我的训练方法错误,应该从4bit直接训练? 或者我应该多训练几个epoch?
Steps To Reproduce
用 https://huggingface.co/datasets/shibing624/CSC 的语料库,如下代码生成 alpaca 格式的训练数据
import json
import random
import sys
f = open('train.json',)
data = json.load(f)
for line in data:
input_text = line['original_text']
wrong_ids = line['wrong_ids']
target_text = line['correct_text'] + '\n错误字:' + ','.join([input_text[i] for i in wrong_ids])
output_item = {
"instruction": "对下面中文拼写纠错:",
"input": input_text,
"output": target_text,
}
print(json.dumps(output_item, ensure_ascii=False))
# Closing file
f.close()
Environment
- OS: Ubuntu 20.04
- Python: 3.10
- Transformers: 4.30.2
- PyTorch: 2.0.0
- CUDA Support (`python -c "import torch; print(torch.cuda.is_available())"`) : True
Anything else?
另外未来有没有可能实现类似ggml q5_1或者 gptq那样的高质量或者高速量化方法?
请问您是使用了整个252K 的数据集进行LORA 微调吗? LR是脚本中默认值吗?我这边只有4K微调语料,LORA微调训练了10个epoch 感觉基本没学到东西。
请问您是使用了整个252K 的数据集进行LORA 微调吗? LR是脚本中默认值吗?我这边只有4K微调语料,LORA微调训练了10个epoch 感觉基本没学到东西。
嗯,我把训练限制从1000放到310000,eval限制从100放到500(如果换成1000会爆V100的32G显存),batchsize只能调整到2
请问您是使用了整个252K 的数据集进行LORA 微调吗? LR是脚本中默认值吗?我这边只有4K微调语料,LORA微调训练了10个epoch 感觉基本没学到东西。
嗯,我把训练限制从1000放到310000,eval限制从100放到500(如果换成1000会爆V100的32G显存),batchsize只能调整到2
好的 感谢您的指导
我在训练时用qlora把base model固定在4bit,然后训练lora model,lora model训练好是fp的,训练完再把lora model和base model进行合并,最后再量化合并后的模型,好像没有出现很大的损失 https://github.com/shuxueslpi/chatGLM-6B-QLoRA
不过,目前官方的量化方法,显存占用会减少,但推理速度是有所下降的,属于用空间换时间的方法,可以看我链接里的测试结果
我在训练时用qlora把base model固定在4bit,然后训练lora model,lora model训练好是fp的,训练完再把lora model和base model进行合并,最后再量化合并后的模型,好像没有出现很大的损失 https://github.com/shuxueslpi/chatGLM-6B-QLoRA
CSC中文纠错数据集我这边比较明显,就是那个测试例子:”少先队员因该为老人让坐“,里面有两个错别字,不量化基本上100%识别出来,量化后50%机率”坐“没识别(改成座)。
我什么时候试试你的先量化后训练模式,跑一个epoch看看。
另外求救你推理代码里面:
q_config = BitsAndBytesConfig(load_in_4bit=True,
bnb_4bit_quant_type='nf4',
bnb_4bit_use_double_quant=True,
bnb_4bit_compute_dtype=torch.float32)
这个我原来理解BitSandBytes就是Transformer底层用的,官网量化到4的代码也就是 Model.quantize(4) 和你这个有什么区别吗? 缺省的bnb_4bit_quant_type应该也是nf4吧?
@bash99 我看了官方的model.quantize(4)的方法,好像和bitsandbytes的还有点不一样,官方的是直接量化的,bitsandbytes这种参考:https://huggingface.co/blog/zh/hf-bitsandbytes-integration
@bash99 期待你测试的结果
期待你测试的结果 @shuxueslpi
我测试下来效果确实好很多,几乎和不量化差不多了。不过因为我中间也调整了训练的prompt,暂时还没有和参照https://github.com/shibing624/MedicalGPT 方法直接PEFT训练做对比。
另外我用PEFT直接训练后,似乎没法用同样的nf4去量化再加载lora进行推理,报"RuntimeError: mat1 and mat2 must have the same dtype" 这类错误。
@bash99 你是怎么合并lora的?我那里面有个合并lora model和base model的脚本
@bash99 你是怎么合并lora的?我那里面有个合并lora model和base model的脚本
哦,我没做合并,直接用你推理代码的例子,先加载base_model (nf4量化),再model = PeftModel.from_pretrained(base_model, peft_model_path) 去加载lora然后推理了
你是说提前合并可能可以避免 "mat1 and mat2 must have the same dtype" 错误?
@bash99 先加载base_model (nf4量化),再model = PeftModel.from_pretrained(base_model, peft_model_path) 去加载lora然后推理了,这样不会报错的吧? 然后你是这样加载后想直接量化?这样加载后,base model一侧是4bit的,另一侧lora层都是fp的,就会这样报错吧。 你试试用我那个合并的脚本,直接合并一个模型,再量化看看效果。
@bash99 我觉得现在有几种模式,可能要测一下: 1、base model + lora model,不合并的模式,也就是你试验过的 2、base model 和 lora model做merge,但不量化(我那个脚本支持这种) 3、base model和 lora model做merge,用官方的量化方法到4bit(我那个脚本就是这样的量化) 4、base model和lora model做merge,不量化,加载的时候用BitsAndBytesConfig,即nf4的方式加载
@bash99 我觉得现在有几种模式,可能要测一下: 1、base model + lora model,不合并的模式,也就是你试验过的 2、base model 和 lora model做merge,但不量化(我那个脚本支持这种) 3、base model和 lora model做merge,用官方的量化方法到4bit(我那个脚本就是这样的量化) 4、base model和lora model做merge,不量化,加载的时候用BitsAndBytesConfig,即nf4的方式加载
3和1就是我之前对比的,推理质量(可靠性)大幅度下降的问题。1和2对比推理时无区别。 4我刚刚测了,对比1 推理质量下降很轻微(或者不可见)。
对比了两种训练方式(lora和qlora),两种量化加载方式,用的CSC数据集,测试用例暂时比较有限。 lora比qlora,劣势:训练内存占用高、速度似乎稍慢、后期加载时必须合并;优势:可并行GPU加速;loss下降更快,3个epoch后的最低loss也更好;推理结果更好
量化加载方式,nf4推理质量优势明显,但是不够灵活,对于lora训练(而非qlora量化训练)的adapter_model.bin,必须先合并再加载。
如果lora或qlora的3和1对比都明显下降,说明官方的量化方法不是最优选择。 4的方式应该是保持了训练和推理的量化方法一致了。 感觉推理这块,还没有一个比较完美的方案(显存小,速度快)。
---- 回复的原邮件 ---- | 发件人 | Ben @.> | | 日期 | 2023年07月12日 11:09 | | 收件人 | @.> | | 抄送至 | @.>@.> | | 主题 | Re: [THUDM/ChatGLM2-6B] [Help] 如果最终准备量化部署,是应该从int4的模型开始训练吗? (Issue #141) |
@bash99 我觉得现在有几种模式,可能要测一下: 1、base model + lora model,不合并的模式,也就是你试验过的 2、base model 和 lora model做merge,但不量化(我那个脚本支持这种) 3、base model和 lora model做merge,用官方的量化方法到4bit(我那个脚本就是这样的量化) 4、base model和lora model做merge,不量化,加载的时候用BitsAndBytesConfig,即nf4的方式加载
3和1就是我之前对比的,推理质量(可靠性)大幅度下降的问题。1和2对比推理时无区别。 4我刚刚测了,对比1 推理质量下降很轻微(或者不可见)。
对比了两种训练方式(lora和qlora),两种量化加载方式,用的CSC数据集,测试用例暂时比较有限。 lora比qlora,劣势:训练内存占用高、速度似乎稍慢、后期加载时必须合并;优势:可并行GPU加速;loss下降更快,3个epoch后的最低loss也更好;推理结果更好
量化加载方式,nf4推理质量优势明显,但是不够灵活,对于lora训练(而非qlora量化训练)的adapter_model.bin,必须先合并再加载。
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>
@bash99 我觉得现在有几种模式,可能要测一下: 1、base model + lora model,不合并的模式,也就是你试验过的 2、base model 和 lora model做merge,但不量化(我那个脚本支持这种) 3、base model和 lora model做merge,用官方的量化方法到4bit(我那个脚本就是这样的量化) 4、base model和lora model做merge,不量化,加载的时候用BitsAndBytesConfig,即nf4的方式加载
3和1就是我之前对比的,推理质量(可靠性)大幅度下降的问题。1和2对比推理时无区别。 4我刚刚测了,对比1 推理质量下降很轻微(或者不可见)。
对比了两种训练方式(lora和qlora),两种量化加载方式,用的CSC数据集,测试用例暂时比较有限。 lora比qlora,劣势:训练内存占用高、速度似乎稍慢、后期加载时必须合并;优势:可并行GPU加速;loss下降更快,3个epoch后的最低loss也更好;推理结果更好
量化加载方式,nf4推理质量优势明显,但是不够灵活,对于lora训练(而非qlora量化训练)的adapter_model.bin,必须先合并再加载。
我想请问下方案4 是不是加载merge后的模型时需要向from pretrain函数传入包含nf4在内的qconfig来实现
我想请问下方案4 是不是加载merge后的模型时需要向from pretrain函数传入包含nf4在内的qconfig来实现 对,就是下面这样 base_model = AutoModel.from_pretrained(config.base_model_name_or_path, quantization_config=q_config 我始终找不到 加载完 lora 后再用nf4这样的模式量化的方法,就成了我说的必须先合并再nf4量化了。