[特殊字符] Transformers 模型量化实战指南:GPTQ 与 bitsandbytes 集成深度解析

📅 发布时间:2026/9/11 8:11:07
[特殊字符] Transformers 模型量化实战指南:GPTQ 与 bitsandbytes 集成深度解析
Transformers 模型量化实战指南GPTQ 与 bitsandbytes 集成深度解析【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers导读本文基于 Transformers 官方文档中关于模型量化的技术指南系统讲解两大主流量化集成的完整使用链路基于optimumGPTQModel的 GPTQ 量化支持 2/3/4/8 位与基于bitsandbytes的 8 位LLM.int8()/ 4 位FP4/NF4量化。读完本文你将掌握从「配置量化参数 → 加载并量化模型 → 保存 / 推送 Hub → 从 Hub 加载量化模型」的完整实战闭环并理解device_map设备映射、ExLlama 推理内核、双重量化、CPU offload、离群值阈值等底层配置项的源码级原理能够在显存受限的单卡或 Colab 环境中直接落地运行大模型推理与微调。一、为什么需要模型量化从 GPTQ 与 bitsandbytes 说起大模型推理与微调的主要瓶颈在于显存。以 FP16 精度加载一个 70B 参数模型仅权重就需要约 140GB 显存远超绝大多数单卡与云端免费环境的上限。量化Quantization通过降低权重表示的位宽来压缩模型体积、减少显存占用是部署大模型最实用的手段之一。 Transformers 在from_pretrained加载链路中统一集成了多种量化后端。本文聚焦官方文档重点讲解的两条主线量化方案位宽后端依赖核心机制GPTQ2 / 3 / 4 / 8 位gptqmodeloptimum基于二阶信息Hessian的权重逐层校准量化推理前需要校准数据集bitsandbytes 8 位8 位bitsandbytesaccelerateLLM.int8() 混合精度分解离群值列保留 FP16bitsandbytes 4 位4 位FP4 / NF4bitsandbytes0.39.0accelerate线性层替换为 4 位量化层支持双重量化嵌套量化需要特别说明本文描述的行为与参数以当前仓库源码为准。两类集成的核心配置类GPTQConfig与BitsAndBytesConfig都定义在 quantization_config.py模型加载时由from_pretrained见 modeling_utils.py解析并调用对应的量化器完成权重量化与模块替换实际替换逻辑位于 bitsandbytes.py。二、GPTQ 集成基于optimum的低比特量化GPTQGenerative Pretrained Transformer Quantization是目前大模型低比特量化的事实标准方法它利用 Hessian 矩阵的二阶信息逐层最小化量化误差能在几乎不损失性能的前提下把模型压缩到 4 位甚至 2 位。 Transformers 通过optimumAPI 集成 GPTQ后端为GPTQModel库。注意GPTQ 集成目前仅支持文本模型视觉、语音与多模态模型可能出现预期之外的行为使用时需格外谨慎。2.1 环境要求要运行 GPTQ 相关代码需要依次安装以下组件对应文档 Requirements 小节# 1. 最新版 GPTQModel 库务必使用 --no-build-isolation 以避免编译依赖冲突 pip install gptqmodel --no-build-isolation # 2. 从源码安装最新版 optimum pip install githttps://github.com/huggingface/optimum.git # 3. 从源码安装最新版 transformers pip install githttps://github.com/huggingface/transformers.git # 4. 升级 accelerate pip install --upgrade accelerate需要强调的是这些命令面向的是「从源码获取最新特性」的开发场景日常使用亦可直接pip install --upgrade transformers optimum gptqmodel accelerate但须保证版本不低于本文描述功能所需的最低版本。2.2 创建 GPTQConfig位宽、数据集与 TokenizerGPTQ 是一种需要校准的量化方法在量化权重之前需要用代表性数据统计各层激活分布。因此创建GPTQConfig时除了位宽bits还必须提供校准数据集dataset与处理数据集的tokenizerfrom transformers import AutoTokenizer, GPTQConfig model_id facebook/opt-125m tokenizer AutoTokenizer.from_pretrained(model_id) gptq_config GPTQConfig(bits4, datasetc4, tokenizertokenizer)其中dataset既可以是内置数据集名称也可以是自定义字符串列表dataset [gptqmodel is an easy-to-use model quantization library with user-friendly apis, based on the GPTQ algorithm.] quantization_config GPTQConfig(bits4, datasetdataset, tokenizertokenizer)从源码 quantization_config.py 可以看到GPTQConfig.post_init()的校验逻辑bits仅支持[2, 3, 4, 8]传入其他值直接抛ValueErrordataset为字符串时只接受 GPTQ 论文使用的wikitext2、c4、c4-new三个内置数据集group_size必须大于 0 或等于-1-1表示逐列量化damp_percent必须落在(0, 1)区间默认0.1。更多GPTQConfig参数可参考下表参数默认值说明group_size128量化分组大小推荐 128-1为逐列量化damp_percent0.1Hessian 对角线的阻尼百分比用于数值稳定desc_actFalse是否按激活幅度降序量化列即 act-order关闭可显著提速但困惑度可能略升act_group_awareTrue使用 GARgroup aware activation order提升量化质量仅当desc_actFalse时生效symTrue是否使用对称量化true_sequentialTrue在 Transformer 块内部也进行逐层顺序量化formatgptq权重格式gptqv1与gptq_v2backendauto控制使用哪个内核auto、auto_trainable等见 GPTQModel backendsbatch_size1处理数据集时的批大小pad_token_idNone当batch_size1时准备数据集所需max_input_lengthNone最大输入长度exllama 后端配合 act-order 时用于初始化缓冲区modules_in_block_to_quantizeNone指定块内需要量化的模块列表需 optimum1.15.0用于排除某些线性层2.3 执行量化从零量化与两种使用场景GPTQ 量化需要 GPU 参与CPU 上无法完成因为量化过程中模型会在 CPU 与 GPU 之间来回搬运。用from_pretrained传入quantization_config即可触发量化from transformers import AutoModelForCausalLM model AutoModelForCausalLM.from_pretrained(model_id, quantization_configgptq_config)文档明确给出两种典型使用场景直接加载他人已量化好的模型从 Hub 上加载社区已发布的 GPTQ 模型省去校准耗时从零量化并保存 / 推送自己量化模型并保存或推送到 Hub 供他人使用。从零量化相当耗时——文档给出参照在 Google Colab 上量化facebook/opt-350m约需 5 分钟而 175B 级别的模型在 NVIDIA A100 上约需 4 GPU 小时。因此在动手量化前务必先到 Hub 检索是否已存在该模型的 GPTQ 版本。配合 device_map 最大化 GPU 利用率量化过程属于「算力密集 显存敏感」任务若希望充分利用显存可显式指定device_mapauto让accelerate自动把各模块调度到可用设备from transformers import AutoModelForCausalLM model AutoModelForCausalLM.from_pretrained( model_id, device_mapauto, quantization_configgptq_config )注意事项源码与文档双重印证磁盘 offload 不受支持模型必须完整驻留在 GPU/CPU 内存中若因校准数据集导致内存不足可在from_pretrained中传入max_memory参数如max_memory{0: 10GiB, cpu: 30GiB}限制各设备内存上限量化过程整体偏慢属正常现象这与校准数据集规模、模型大小和硬件直接相关。2.4 保存与推送 GPTQ 量化模型与其他 模型一样量化模型可以通过push_to_hub推送到 Hub量化配置会随模型一起保存quantized_model.push_to_hub(opt-125m-gptq) tokenizer.push_to_hub(opt-125m-gptq)本地保存则使用save_pretrainedquantized_model.save_pretrained(opt-125m-gptq) tokenizer.save_pretrained(opt-125m-gptq)⚠️ 若量化时使用了device_map保存前必须先把模型整体搬回 GPU 或cpu否则分片状态下的保存可能出现一致性问题quantized_model.to(cpu) quantized_model.save_pretrained(opt-125m-gptq)2.5 从 Hub 加载已量化模型加载时同样只需from_pretrained无需再传quantization_config——前提是模型配置对象中存在quantization_config属性这是确认权重确已量化的标志from transformers import AutoModelForCausalLM model AutoModelForCausalLM.from_pretrained({your_username}/opt-125m-gptq)希望更快加载且不浪费多余显存时可叠加device_map需安装acceleratefrom transformers import AutoModelForCausalLM model AutoModelForCausalLM.from_pretrained({your_username}/opt-125m-gptq, device_mapauto)2.6 ExLlama 内核4 位模型的推理加速对 4 位模型GPTQ 集成默认启用 ExLlama 内核以提升推理速度。可通过GPTQConfig的disable_exllama参数覆盖这一行为import torch from transformers import AutoModelForCausalLM, GPTQConfig gptq_config GPTQConfig(bits4, disable_exllamaFalse) model AutoModelForCausalLM.from_pretrained( {your_username}/opt-125m-gptq, device_mapauto, quantization_configgptq_config, )使用 ExLlama 内核有三个前提目前仅支持 4 位模型模型必须完整放置在 GPU 上若通过 PEFT 微调量化模型建议关闭 ExLlama 内核微调阶段内核与梯度计算存在兼容性问题。此外GPTQConfig中的disable_exllama只覆盖与内核相关的属性其余量化配置仍以模型配置文件中的保存值为准。仓库测试 test_gptq.py 中即可看到GPTQConfig(bits4, backendBACKEND.EXLLAMA_V2)这类显式指定 ExLlama 后端的使用方式。2.7 微调量化模型PEFT 集成得益于 Hugging Face 生态对适配器的官方支持GPTQ 量化模型可配合peft库进行参数高效微调LoRA 等细节可参考peft库文档。Google Colab 上也有结合 GPTQ 量化与 PEFT 微调的完整示例笔记本可供参考。三、bitsandbytes 集成8 位与 4 位即插即用量化与 GPTQ 不同bitsandbytes集成无需校准数据只需几行代码即可把模型加载为 8 位或 4 位精度。8 位支持源自bitsandbytes0.37.0LLM.int8() 方法4 位FP4/NF4支持自0.39.0起且 4 位量化支持任何可配合device_map的模型。3.1 通用用法load_in_8bit 与 load_in_4bit只要模型支持 Accelerate 加载且包含torch.nn.Linear层就可以在from_pretrained时通过quantization_config直接量化且适用于任何模态文本、视觉、语音、多模态from transformers import AutoModelForCausalLM, BitsAndBytesConfig model_8bit AutoModelForCausalLM.from_pretrained( facebook/opt-350m, quantization_configBitsAndBytesConfig(load_in_8bitTrue) ) model_4bit AutoModelForCausalLM.from_pretrained( facebook/opt-350m, quantization_configBitsAndBytesConfig(load_in_4bitTrue) )其底层实现位于 bitsandbytes.py 的replace_with_bnb_linear遍历模型所有模块将nn.Linear及部分模型的Conv1D替换为bnb.nn.Linear8bitLt8 位或bnb.nn.Linear4bit4 位其余模块如torch.nn.LayerNorm默认转为torch.float16。该 dtype 可通过dtype参数覆盖import torch from transformers import AutoModelForCausalLM model_8bit AutoModelForCausalLM.from_pretrained( facebook/opt-350m, quantization_configBitsAndBytesConfig(load_in_8bitTrue), dtypetorch.float32, ) print(model_8bit.model.decoder.layers[-1].final_layer_norm.weight.dtype) # torch.float32需要说明的是当前仓库中from_pretrained的 dtype 覆盖行为与文档示例保持一致具体参数名以所用 transformers 版本的 API 签名为准。3.2 4 位量化FP4 / NF4环境要求pip install bitsandbytes0.39.0 pip install --upgrade accelerate pip install --upgrade transformers技巧与最佳实践文档 Tips 小节高级用法完整参数组合的 4 位量化高级用法可参考官方 Colab 笔记本batch_size1 快速推理自bitsandbytes0.40.0起batch_size1场景可享受快速推理收益请确保版本不低于0.40.0训练QLoRA根据 QLoRA 论文建议用 4 位基座模型做训练如 LoRA 适配器时应使用bnb_4bit_quant_typenf4推理bnb_4bit_quant_type对推理性能影响不大但为保持与权重的一致性务必使用与加载时相同的bnb_4bit_compute_dtype与dtype参数。以 4 位加载大模型# pip install transformers accelerate bitsandbytes from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig model_id bigscience/bloom-1b7 tokenizer AutoTokenizer.from_pretrained(model_id) model AutoModelForCausalLM.from_pretrained( model_id, device_mapauto, quantization_configBitsAndBytesConfig(load_in_4bitTrue), )使用load_in_4bitTrue可将内存占用近似除以 4。⚠️ 4 位限制4 位加载的模型目前不能把量化权重推送到 Hub不能直接训练量化权重本身不可训练但可以在 4 位基座上训练额外参数如 LoRA 适配器详见 QLoRA 一节。更改计算 dtypecompute dtype计算 dtype 控制计算过程中使用的精度。例如隐藏状态保持float32而把矩阵计算切到bf16以获得加速。默认计算 dtype 为float32源码 quantization_config.py 中bnb_4bit_compute_dtype为None时落回torch.float32import torch from transformers import BitsAndBytesConfig quantization_config BitsAndBytesConfig( load_in_4bitTrue, bnb_4bit_compute_dtypetorch.bfloat16, )使用 NF4Normal Float 4数据类型NF4 是针对正态分布初始化权重设计的新型 4 位数据类型比 FP4 更适合大模型权重分布from transformers import AutoModelForCausalLM, BitsAndBytesConfig nf4_config BitsAndBytesConfig( load_in_4bitTrue, bnb_4bit_quant_typenf4, ) model_nf4 AutoModelForCausalLM.from_pretrained(model_id, quantization_confignf4_config)双重量化嵌套量化节省更多显存双重量化会对「第一次量化产生的量化常数」再做一次量化几乎不损失性能却能进一步压缩内存。文档给出实证观察在 NVIDIA T4 16GB 上借助双重量化可以实现序列长度 1024、batch size 1、梯度累积步数 4 的 llama-13b 微调from transformers import AutoModelForCausalLM, BitsAndBytesConfig double_quant_config BitsAndBytesConfig( load_in_4bitTrue, bnb_4bit_use_double_quantTrue, ) model_double_quant AutoModelForCausalLM.from_pretrained(model_id, quantization_configdouble_quant_config)该参数在源码中会透传给bnb.nn.Linear4bit的compress_statistics见 bitsandbytes.py。3.3 以 8 位加载大模型# pip install transformers accelerate bitsandbytes from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig model_id bigscience/bloom-1b7 tokenizer AutoTokenizer.from_pretrained(model_id) model AutoModelForCausalLM.from_pretrained( model_id, quantization_configBitsAndBytesConfig(load_in_8bitTrue), )load_in_8bitTrue可将内存需求近似减半。随后即可像普通PreTrainedModel一样使用模型并用get_memory_footprint检查实际内存占用该方法定义于 modeling_utils.pyprint(model.get_memory_footprint())⚠️ 8 位限制8 位加载的模型目前同样不能推送量化权重到 Hub除非使用最新版 transformers 与 bitsandbytes量化权重本身不可训练但可以在 8 位基座上训练额外参数。device_map为可选参数但推荐推理时设置device_mapauto以便在可用资源上高效调度模型。3.4 高级用法CPU/GPU 卸载8 位模型的高级用法之一是让模型在 CPU 与 GPU 之间分派权重。注意分派到 CPU 的权重不会被转成 8 位而是保持float32。此特性面向希望容纳超大模型、并在 GPU 与 CPU 间分派权重的用户。首先在配置中开启llm_int8_enable_fp32_cpu_offloadfrom transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig quantization_config BitsAndBytesConfig(llm_int8_enable_fp32_cpu_offloadTrue)以bigscience/bloom-1b7为例假设 GPU 显存足以容纳除lm_head外的整个模型可构造自定义 device_map 把lm_head放到 CPUdevice_map { transformer.word_embeddings: 0, transformer.word_embeddings_layernorm: 0, lm_head: cpu, transformer.h: 0, transformer.ln_f: 0, }然后加载模型model_8bit AutoModelForCausalLM.from_pretrained( bigscience/bloom-1b7, device_mapdevice_map, quantization_configquantization_config, )3.5 高级用法调整llm_int8_threshold离群值阈值llm_int8_threshold对应 LLM.int8() 论文中的离群值检测阈值超过该阈值的隐藏状态被视为离群值对这些值的运算改用 fp16 执行。权重通常近似正态分布大部分值落在[-3.5, 3.5]但大模型常存在系统性离群值多落在[-60, -6]或[6, 60]。int8 量化对量级约 5 以内的值效果良好超出后性能显著下降。默认阈值 6 通常合适但对更不稳定的模型小模型、微调模型可能需要更低阈值from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig model_id bigscience/bloom-1b7 quantization_config BitsAndBytesConfig( llm_int8_threshold10, ) model_8bit AutoModelForCausalLM.from_pretrained( model_id, device_mapdevice_map, quantization_configquantization_config, ) tokenizer AutoTokenizer.from_pretrained(model_id)该参数会影响推理速度建议结合自身用例反复实验找到最优取值。源码中llm_int8_threshold会被透传给bnb.nn.Linear8bitLt的threshold参数见 bitsandbytes.py。3.6 高级用法跳过部分模块的 8 位转换部分模型包含不宜做 8 位转换的模块如 Jukebox 模型分布在多处、且不一定位于末位的多个lm_head。可用llm_int8_skip_modules显式跳过from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig model_id bigscience/bloom-1b7 quantization_config BitsAndBytesConfig( llm_int8_skip_modules[lm_head], ) model_8bit AutoModelForCausalLM.from_pretrained( model_id, device_mapdevice_map, quantization_configquantization_config, ) tokenizer AutoTokenizer.from_pretrained(model_id)对于CausalLM类模型被跳过的lm_head将保留原始 dtype。从源码看llm_int8_skip_modules会作为modules_to_not_convert传入replace_with_bnb_linear在遍历模块时通过should_convert_module决定是否替换。3.7 8 位模型微调QLoRA 思路借助 Hugging Face 生态的适配器支持可以在 8 位加载的模型上直接微调从而在单个 Google Colab 中微调flan-t5-large、facebook/opt-6.7b等大模型。细节参考peft库。微调场景的两个要点加载训练模型时无需传device_map模型会自动加载到 GPU也可显式指定单一设备如cuda:0、0、torch.device(cuda:0)device_mapauto仅建议用于推理场景。3.8 BitsAndBytesConfig 参数速查参数默认值说明load_in_8bitFalse启用 LLM.int8() 8 位量化load_in_4bitFalse启用 FP4/NF4 4 位量化替换 Linear 层llm_int8_threshold6.0离群值检测阈值超阈值值用 fp16 运算llm_int8_skip_modulesNone不做 8 位转换的模块名列表llm_int8_enable_fp32_cpu_offloadFalse开启 FP32 CPU 卸载CPU 上的权重保持 fp32llm_int8_has_fp16_weightFalse以 16 位主权重运行 LLM.int8()利于微调反向传播无需来回转换bnb_4bit_compute_dtypetorch.float32计算精度可设为 bf16 加速bnb_4bit_quant_typefp44 位量化数据类型fp4或nf4bnb_4bit_use_double_quantFalse双重量化量化常数二次量化bnb_4bit_quant_storagetorch.uint84 位参数打包的存储类型源码层面需要注意的两点load_in_4bit与load_in_8bit不能同时为True否则构造函数直接抛ValueError见 quantization_config.pybnb_4bit_compute_dtype支持torch.dtype或字符串两种传法字符串会被getattr(torch, ...)解析bnb_4bit_quant_storage仅接受float16、float32、int8、uint8、float64、bfloat16等合法取值。四、bitsandbytes 量化模型的推送与加载4.1 推送 8 位模型到 Hub与普通模型一样通过push_to_hub即可推送量化模型——框架会先推送量化配置文件再推送量化权重。使用该功能需bitsandbytes0.37.2文档写作时以bitsandbytes0.38.0.post1测试通过from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig model AutoModelForCausalLM.from_pretrained( bigscience/bloom-560m, quantization_configBitsAndBytesConfig(load_in_8bitTrue) ) tokenizer AutoTokenizer.from_pretrained(bigscience/bloom-560m) model.push_to_hub(bloom-560m-8bit)强烈建议大模型以 8 位版本推送社区可由此享受更低内存占用例如在 Google Colab 上直接加载大模型。4.2 从 Hub 加载量化模型from transformers import AutoModelForCausalLM, AutoTokenizer model AutoModelForCausalLM.from_pretrained({your_username}/bloom-560m-8bit, device_mapauto)此场景无需再传load_in_8bitTrue但必须确认模型配置对象中存在quantization_config属性确认权重确已量化已安装bitsandbytes与acceleratedevice_map可选但推理推荐device_mapauto以便高效分派。五、量化方案选型建议与注意事项结合文档与仓库实现两条技术路线适合不同的落地场景选择 GPTQ 的场景追求极限压缩2/3 位与推理加速ExLlama 内核、需要离线一次性量化并长期复用共享的场景。代价是需要 GPU 校准时间、需要额外校准数据集且目前仅支持文本模型。选择 bitsandbytes 的场景追求即插即用、支持全模态、需要与device_map深度配合CPU offload、或需要在 4/8 位基座上叠加 LoRA 微调QLoRA的场景。代价是 4 位权重暂不能推送 Hub8/4 位权重本身不可训练。无论选择哪条路线以下几点都是通用的动手前先检索 Hub很多热门模型已有社区量化版本直接加载可省去大量校准时间device_mapauto优先用于推理训练/微调场景建议交给框架自动放置或显式指定单一设备版本敏感不同量化能力依赖具体版本的bitsandbytes、optimum、gptqmodel、accelerate升级前注意核对文档中标注的最低版本内存检查加载后可用get_memory_footprint()量化评估量化收益再决定是否进一步开启双重量化或 CPU offload。六、进一步探索两类配置类的完整参数与 docstringquantization_config.pybitsandbytes 模块替换与反量化实现bitsandbytes.py模型加载入口与get_memory_footprintmodeling_utils.pyGPTQ 集成测试test_gptq.py4 位FP4/NF4测试test_4bit.py8 位LLM.int8测试test_mixed_int8.pyoptimum支持的其他量化方法AWQ、AQLM、EETQ、Quanto、HQQ 等可查阅optimum官方文档判断是否适配自身用例transformers 侧更多量化后端如awq、hqq、torchao等可在 integrations 目录中继续挖掘。【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考