漫画网站建设教程,关于网站建设需要了解什么东西,一个人怎么做网站,中企动力科技股份有限公司是国企吗1. 引言
量化的本质#xff1a;通过将模型参数从高精度#xff08;例如32位#xff09;降低到低精度#xff08;例如8位#xff09;#xff0c;来缩小模型体积。
本文将采用一种训练后量化方法GPTQ#xff0c;对前文已经训练并合并过的模型文件进行量化#xff0c;通…1. 引言
量化的本质通过将模型参数从高精度例如32位降低到低精度例如8位来缩小模型体积。
本文将采用一种训练后量化方法GPTQ对前文已经训练并合并过的模型文件进行量化通过比较模型量化前后的评测指标来测试量化对模型性能的影响。
GPTQ的核心思想在于将所有权重压缩到8位或4位量化中通过最小化与原始权重的均方误差来实现。在推理过程中它将动态地将权重解量化为float16以提高性能同时保持较低的内存占用率。 注均方误差是评估两个数值数据集之间差异的一种常用方法它通过计算量化后权重与原始权重之间的均方误差并使之最小化来减少量化过程中引入的误差以保持模型在推理时的性能。 2. 量化过程
2.1 加载量化模型
首先引入必要的包其中
auto_gptq: 一个用于模型量化的库通常用于减少模型的内存占用和计算消耗。AutoGPTQForCausalLM: 用于加载和使用经过量化的因果语言模型。BaseQuantizeConfig: 定义量化模型时所需的参数例如量化精度。AutoTokenizertransformers库提供的分词器用于处理文本分词。
import os
import json
import torch
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
from transformers import AutoTokenizer定义量化任务要使用的设备并指定模型的原始路径model_path。
os.environ[CUDA_VISIBLE_DEVICES] 1
device cuda
model_path /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0配置量化参数。
quantize_config BaseQuantizeConfig(bits8, group_size128, # 分组量化damp_percent0.01,desc_actFalse, static_groupsFalse,symTrue,true_sequentialTrue,model_name_or_pathNone,model_file_base_namemodel
)参数释义如下
bits: 指定量化的位数为8位。group_size量化时的分组大小分组量化可以提高计算效率通常设置为 128 是一个合理的选择适合大多数模型。damp_percent控制量化过程中对权重的平滑处理防止过度量化导致的性能下降。默认值 0.01 通常是一个良好的起点如果量化不佳可以增加此值。desc_act控制是否使用描述性激活设置为 False 可以加速推理如果模型的精度更重要可以设置为 True。static_groups 是否使用静态分组。静态分组可以提高推理效率 如果模型结构固定且不需要动态调整可以设置为 True。否则保持为 False 以支持动态分组。sym 指定是否使用对称量化。对称量化可以简化计算如果模型对称性较好可以设置为 True。true_sequential 控制是否使用真实的顺序量化。真实顺序量化可以提高模型的表现但可能会增加计算复杂性。如果模型对顺序敏感可以设置为 True。model_file_base_name指定生成的量化模型文件名称最终体现在输出文件的命名上。
加载分词器并根据配置quantize_config指定的量化位数来加载模型。
tokenizer AutoTokenizer.from_pretrained(model_path)
model AutoGPTQForCausalLM.from_pretrained(model_path, quantize_config)2.2 准备校准数据集
GPTQ采用权重分组量化如上面的配置中128列为一组一个分组内的参数采用逐个进行量化如下图所示在每个参数被量化后需要适当调整这个 block 内其他未量化的参数以弥补量化造成的精度损失。 因此GPTQ 量化需要准备校准数据集我们这里采用一个以前生成的测试数据集作为校准数据。
def load_jsonl(path):conversations []with open(path, r) as file:data [json.loads(line) for line in file]conversations [dialog[messages] for dialog in data]return conversationseval_data_path /data2/anti_fraud/dataset/test_chatml_0815.jsonl
conversations load_jsonl(eval_data_path)
conversations[0]校验数据集的数据格式是一个标准的聊天模板示例如下
[{role: system, content: You are a helpful assistant.},{role: user,content: \n下面是一段对话文本, 请分析对话内容是否有诈骗风险以json格式输出你的判断结果(is_fraud: true/false)。\n\n\n发言人3: 那就是说看上半年我们的三四月份会不会有一些这个相关的一些这个缓解就是说这方面的一些矛盾的一些缓解债务的一个情况的一些缓解那我们还要继续观察。\n发言人2: 好的蒋总那我们看一下那个其他投资者有没有什么其他问题。\n发言人1: 大家好通过网络端接入的投资者可点击举手连麦等候提问或在文字交流区提交您的问题通过电话端接入的投资者请按星一键提问。先按星号键再按一键谢谢。大家好通过网络端接入的投资者可点击举手连麦然后提问或在文字交流区提交您的问题。通过电话端接入的投资者请按星一键提问。\n发言人1: 先按星号键再按数字一键谢谢。},{role: assistant, content: {is_fraud: false}}]定义一个预处理函数将文本数据预处理为张量数据。
def preprocess(dataset, max_len1024):data []for msg in dataset:text tokenizer.apply_chat_template(msg, tokenizeFalse, add_generation_promptFalse)model_inputs tokenizer([text])input_ids torch.tensor(model_inputs.input_ids[:max_len], dtypetorch.int)data.append(dict(input_idsinput_ids, attention_maskinput_ids.ne(tokenizer.pad_token_id)))return datadataset preprocess(conversations)tokenizer.apply_chat_template负责将消息格式转化为Qwen模型需要的提示词格式。tokenizer([text])使用tokenizer对文本进行分词并将token转换为ID值。torch.tensor将token_id转换为tensor张量。
配置日志显示格式
import logginglogging.basicConfig(format%(asctime)s %(levelname)s [%(name)s] %(message)s, levellogging.INFO, datefmt%Y-%m-%d %H:%M:%S
)2.3 开始量化
使用校准数据集来动态调整量化参数使模型在量化时学习并适应数据分布。
%%time
model.quantize(dataset, cache_examples_on_gpuFalse)INFO - Start quantizing layer 1/28
INFO - Quantizing self_attn.k_proj in layer 1/28...
INFO - Quantizing self_attn.v_proj in layer 1/28...
INFO - Quantizing self_attn.q_proj in layer 1/28...
INFO - Quantizing self_attn.o_proj in layer 1/28...
INFO - Quantizing mlp.up_proj in layer 1/28...
INFO - Quantizing mlp.gate_proj in layer 1/28...
INFO - Quantizing mlp.down_proj in layer 1/28...
INFO - Start quantizing layer 2/28
……
INFO - Start quantizing layer 28/28
INFO - Quantizing self_attn.k_proj in layer 28/28...
INFO - Quantizing self_attn.v_proj in layer 28/28...
INFO - Quantizing self_attn.q_proj in layer 28/28...
INFO - Quantizing self_attn.o_proj in layer 28/28...
INFO - Quantizing mlp.up_proj in layer 28/28...
INFO - Quantizing mlp.gate_proj in layer 28/28...
INFO - Quantizing mlp.down_proj in layer 28/28...CPU times: user 30min 52s, sys: 3min 40s, total: 34min 32s
Wall time: 27min 23s由于内容太长中间作了省略不过仍然可以看出量化是一层一层逐个对每个矩阵分别进行量化的一个1.5B的模型量化过程耗时达27分钟。 保存量化后的模型和分词器状态。
quant_path指定了量化模型的保存路径use_safetensorsTrue 参数表示使用安全张量格式SafeTensors进行保存具有更好的安全性和性能。tokenizer.save_pretrained为量化后的模型保存一份分词器配置。
quant_path /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8
model.save_quantized(quant_path, use_safetensorsTrue)
tokenizer.save_pretrained(quant_path)输出保存的分词器配置。 (/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/tokenizer_config.json,/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/special_tokens_map.json,/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/vocab.json,/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/merges.txt,/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/added_tokens.json,/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8/tokenizer.json)2.4 4位量化
上面是采用8位量化作为对比我们也量化一个4位模型与8位量化的区别只在于量化配置时的参数bits改成了4其它都不作改变.
quantize_config_int4 BaseQuantizeConfig(bits4, # 4位量化group_size128, # 分组量化damp_percent0.01,desc_actFalse, static_groupsFalse,symTrue,true_sequentialTrue,model_name_or_pathNone,model_file_base_namemodel
)采用4位量化配置来加载模型。
model_int4 AutoGPTQForCausalLM.from_pretrained(model_path, quantize_config_int4)对4位参数进行量化校验校准数据集复用前面8位量化时生成的数据。
%%time
model_int4.quantize(dataset, cache_examples_on_gpuFalse)INFO - Start quantizing layer 1/28
INFO - Quantizing self_attn.k_proj in layer 1/28...
INFO - Quantizing self_attn.v_proj in layer 1/28...
INFO - Quantizing self_attn.q_proj in layer 1/28...
INFO - Quantizing self_attn.o_proj in layer 1/28...
INFO - Quantizing mlp.up_proj in layer 1/28...
INFO - Quantizing mlp.gate_proj in layer 1/28...
INFO - Quantizing mlp.down_proj in layer 1/28...
INFO - Start quantizing layer 2/28
……
INFO - Start quantizing layer 28/28
INFO - Quantizing self_attn.k_proj in layer 28/28...
INFO - Quantizing self_attn.v_proj in layer 28/28...
INFO - Quantizing self_attn.q_proj in layer 28/28...
INFO - Quantizing self_attn.o_proj in layer 28/28...
INFO - Quantizing mlp.up_proj in layer 28/28...
INFO - Quantizing mlp.gate_proj in layer 28/28...
INFO - Quantizing mlp.down_proj in layer 28/28...CPU times: user 37min 11s, sys: 3min 2s, total: 40min 13s
Wall time: 31min 56s保存量化后的模型和分词器配置。
quant_int4_path /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4
model_int4.save_quantized(quant_int4_path, use_safetensorsTrue)
tokenizer.save_pretrained(quant_int4_path)(/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/tokenizer_config.json,/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/special_tokens_map.json,/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/vocab.json,/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/merges.txt,/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/added_tokens.json,/data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4/tokenizer.json)3. 评测
与前文不同这里统一采用测试数据集进行评测以评估模型的最终性能。
原始模型评测16位
%run evaluate.py
testdata_path /data2/anti_fraud/dataset/test0819.jsonl
evaluate(model_path, , testdata_path, device, batchTrue, debugTrue)progress: 100%|██████████| 2349/2349 [01:5200:00, 20.87it/s]tn1136, fp:31, fn:162, tp:1020
precision: 0.9705042816365367, recall: 0.8629441624365483这时的召回率recall0.8629和前文的测评结果0.9129有差异前文用的验证集这里用的是测试集可能是这两个数据集的数据分布不均匀导致两者结果有较大差异。 量化8位模型评测
%run evaluate.py
testdata_path /data2/anti_fraud/dataset/test0819.jsonl
model_int8_path /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8
evaluate(model_gptq_path, , testdata_path, device, batchTrue, debugTrue)tn1134, fp:33, fn:158, tp:1024
precision: 0.9687795648060549, recall: 0.86632825719120138位量化模型的评测结果与原始模型基本一致说明8位量化依然保持了原始模型的推理表现。
量化4位模型评测
%run evaluate.py
testdata_path /data2/anti_fraud/dataset/test0819.jsonl
model_int4_path /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4
tokenizer AutoTokenizer.from_pretrained(model_int4_path)
model_int4_reload AutoModelForCausalLM.from_pretrained(model_int4_path, device_mapdevice)
evaluate_with_model(model_int4_reload, tokenizer, testdata_path, device, batchTrue, debugTrue)注4位量化模型这里之所以要单独加载model是因为GPTQ量化的4位模型有个限制——只能在GPU上运行我们原先的加载方式会报错详情可以参看本文最后的附4位量化模型加载错误。 tn1081, fp:86, fn:50, tp:1132
precision: 0.9293924466338259, recall: 0.9576988155668359从这个结果来看4位量化模型与原始模型的性能差别较大具体体现在
精确率下降明显表明模型在检测欺诈文本时误报false positives数量增加模型可能会将更多的非欺诈文本错误地分类为欺诈文本。召回率上升模型在检测欺诈时漏报false negatives的数量减少这意味着模型在检测欺诈文本时更加激进尽可能减少漏报哪怕误报增加。
4位量化比8位量化引入更多的信息丢失和噪声模型权重和激活值的精度显著下降最终导致分类效果的明显差异。
4. 模型文件差异
原始模型文件列表信息
!ls -l /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0total 3026376-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 80 Aug 29 11:30 added_tokens.json-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 748 Aug 29 11:30 config.json-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 242 Aug 29 11:30 generation_config.json-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1671853 Aug 29 11:30 merges.txt-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1975314632 Aug 29 11:30 model-00001-of-00002.safetensors-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1112152304 Aug 29 11:30 model-00002-of-00002.safetensors-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 27693 Aug 29 11:30 model.safetensors.index.json-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 367 Aug 29 11:30 special_tokens_map.json-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1532 Aug 29 11:30 tokenizer_config.json-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 7028043 Aug 29 11:30 tokenizer.json-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 2776833 Aug 29 11:30 vocab.json8位量化模型的文件列表信息
!ls -l /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int8total 2235860
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 80 Sep 10 11:53 added_tokens.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1062 Sep 10 11:53 config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1671853 Sep 10 11:53 merges.txt
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 2278014312 Sep 10 11:53 model.safetensors
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 269 Sep 10 11:53 quantize_config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 367 Sep 10 11:53 special_tokens_map.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1532 Sep 10 11:53 tokenizer_config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 7028043 Sep 10 11:53 tokenizer.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 2776833 Sep 10 11:53 vocab.json4位量化模型的文件列表信息
!ls -l /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4total 1591120
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 80 Sep 10 12:50 added_tokens.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1088 Sep 10 18:12 config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1671853 Sep 10 12:50 merges.txt
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1617798120 Sep 10 12:50 model.safetensors
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 269 Sep 10 12:50 quantize_config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 367 Sep 10 12:50 special_tokens_map.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 1532 Sep 10 12:50 tokenizer_config.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 7028043 Sep 10 12:50 tokenizer.json
-rw-rw-r-- 1 xiaoguanghua xiaoguanghua 2776833 Sep 10 12:50 vocab.json可以看到原始模型、8位量化、4位量化三者的模型文件大小分别3.08GB、2.27GB、1.61GB量化位数越小模型文件相应也越小。
另外还可以看到模型文件大小与量化位宽的比例并不完全是线性关系。因为除了模型参数本身之外还有模型架构、框架开销pytorch、优化器的动量和梯度信息等这些都会影响着模型文件的总大小。
小结本文通过gptq方法分别对微调后的模型进行了8位量化和4位量化并对比了量化前后模型的性能指标差异8位量化模型的性能指标变化小而4位量化模型的性能指标变异较大。就我们这个场景来说更适合采用8位量化模型。
附14位量化模型加载错误
使用如下代码进行先CPU加载再移到目标GPU时会报Found modules on cpu/disk错误
model AutoModelForCausalLM.from_pretrained(model_path, torch_dtypetorch.bfloat16).eval().to(device)错误详情
ValueError: Found modules on cpu/disk. Using Exllama or Exllamav2 backend requires all the modules to be on GPU.You can deactivate exllama backend by setting disable_exllamaTrue in the quantization config object原因使用GPTQ方式量化int4模型时使用了exllama这是一种高效的kernel实现但需要所有模型参数在GPU上因此对于GPTQ的4位量化模型先使用CPU加载再移到GPU这种做法行不通。
解法
在模型目录下的config.json文件中在quantization_config配置块中设置disable_exllamatrue或者use_exllamafalse来禁用exllama不过可能会影响推理速度。在加载模型时直接加载到GPU上类似from_disk AutoModelForCausalLM.from_pretrained(path, device_mapcuda:0)
附2偏置参数未使用警告
在加载4位量化模型时会报此警告详细信息如下
Some weights of the model checkpoint at /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud-gptq-int4 were not used when initializing Qwen2ForCausalLM: [model.layers.0.mlp.down_proj.bias, model.layers.0.mlp.gate_proj.bias, model.layers.0.mlp.up_proj.bias,
……
model.layers.9.self_attn.o_proj.bias]此问题的原因暂时未找到哪位小伙伴知道原因有劳告知。 这个网页上有人报类似问题但未说明原因https://github.com/QwenLM/Qwen2/issues/239
参考资料
欺诈文本分类检测十一LLamaFactory多卡微调欺诈文本分类检测十二模型导出与部署大模型量化技术原理Found modules on cpu/disk错误讨论