ChatGLM2-6B icon indicating copy to clipboard operation
ChatGLM2-6B copied to clipboard

[Help] 如果最终准备量化部署,是应该从int4的模型开始训练吗?

Open bash99 opened this issue 2 years ago • 13 comments

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那样的高质量或者高速量化方法?

bash99 avatar Jun 30 '23 10:06 bash99

请问您是使用了整个252K 的数据集进行LORA 微调吗? LR是脚本中默认值吗?我这边只有4K微调语料,LORA微调训练了10个epoch 感觉基本没学到东西。

valkryhx avatar Jul 01 '23 13:07 valkryhx

请问您是使用了整个252K 的数据集进行LORA 微调吗? LR是脚本中默认值吗?我这边只有4K微调语料,LORA微调训练了10个epoch 感觉基本没学到东西。

嗯,我把训练限制从1000放到310000,eval限制从100放到500(如果换成1000会爆V100的32G显存),batchsize只能调整到2

bash99 avatar Jul 03 '23 02:07 bash99

请问您是使用了整个252K 的数据集进行LORA 微调吗? LR是脚本中默认值吗?我这边只有4K微调语料,LORA微调训练了10个epoch 感觉基本没学到东西。

嗯,我把训练限制从1000放到310000,eval限制从100放到500(如果换成1000会爆V100的32G显存),batchsize只能调整到2

好的 感谢您的指导

valkryhx avatar Jul 03 '23 08:07 valkryhx

我在训练时用qlora把base model固定在4bit,然后训练lora model,lora model训练好是fp的,训练完再把lora model和base model进行合并,最后再量化合并后的模型,好像没有出现很大的损失 https://github.com/shuxueslpi/chatGLM-6B-QLoRA

shuxueslpi avatar Jul 04 '23 02:07 shuxueslpi

不过,目前官方的量化方法,显存占用会减少,但推理速度是有所下降的,属于用空间换时间的方法,可以看我链接里的测试结果

shuxueslpi avatar Jul 04 '23 02:07 shuxueslpi

我在训练时用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 avatar Jul 04 '23 02:07 bash99

@bash99 我看了官方的model.quantize(4)的方法,好像和bitsandbytes的还有点不一样,官方的是直接量化的,bitsandbytes这种参考:https://huggingface.co/blog/zh/hf-bitsandbytes-integration

shuxueslpi avatar Jul 04 '23 03:07 shuxueslpi

@bash99 期待你测试的结果

shuxueslpi avatar Jul 04 '23 03:07 shuxueslpi

期待你测试的结果 @shuxueslpi

我测试下来效果确实好很多,几乎和不量化差不多了。不过因为我中间也调整了训练的prompt,暂时还没有和参照https://github.com/shibing624/MedicalGPT 方法直接PEFT训练做对比。

另外我用PEFT直接训练后,似乎没法用同样的nf4去量化再加载lora进行推理,报"RuntimeError: mat1 and mat2 must have the same dtype" 这类错误。

bash99 avatar Jul 06 '23 04:07 bash99

@bash99 你是怎么合并lora的?我那里面有个合并lora model和base model的脚本

shuxueslpi avatar Jul 06 '23 08:07 shuxueslpi

@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 avatar Jul 07 '23 08:07 bash99

@bash99 先加载base_model (nf4量化),再model = PeftModel.from_pretrained(base_model, peft_model_path) 去加载lora然后推理了,这样不会报错的吧? 然后你是这样加载后想直接量化?这样加载后,base model一侧是4bit的,另一侧lora层都是fp的,就会这样报错吧。 你试试用我那个合并的脚本,直接合并一个模型,再量化看看效果。

shuxueslpi avatar Jul 07 '23 10:07 shuxueslpi

@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的方式加载

shuxueslpi avatar Jul 07 '23 12:07 shuxueslpi

@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,必须先合并再加载。

bash99 avatar Jul 12 '23 03:07 bash99

如果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: @.***>

shuxueslpi avatar Jul 12 '23 03:07 shuxueslpi

@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来实现

valkryhx avatar Jul 12 '23 16:07 valkryhx

我想请问下方案4 是不是加载merge后的模型时需要向from pretrain函数传入包含nf4在内的qconfig来实现 对,就是下面这样 base_model = AutoModel.from_pretrained(config.base_model_name_or_path, quantization_config=q_config 我始终找不到 加载完 lora 后再用nf4这样的模式量化的方法,就成了我说的必须先合并再nf4量化了。

bash99 avatar Jul 13 '23 07:07 bash99