仅权重量化

仅权重量化

💡 原文英文,约3700词,阅读约需14分钟。
📝

内容提要

本文介绍仅权重量化:模型权重存为低比特整数、激活保持FP16/BF16,以降低自回归解码时的权重读取开销。文中讲解非对称仿射量化的缩放因子与零点、逐通道与逐组量化,并演示用TorchAO做训练后量化、用GPTQ和AWQ借助校准数据减少误差、转换为GGUF格式供llama.cpp运行。最后强调需在目标硬件上评估质量、内存、延迟与吞吐,并确保格式、量化方案与推理内核兼容。

🔎

延伸解读

量化收益取决于硬件与内核

文章指出,仅权重量化在自回归解码、小批量场景下主要降低权重读取开销,但实际加速取决于硬件、内核和模型形状。许多AI GPU的低精度矩阵运算更快,但并非所有配置都能获得同等收益。因此,不能仅凭比特数推断性能提升,需在目标硬件上实测。

量化粒度与格式兼容性

逐通道和逐组量化通常比逐张量更能保持LLM权重质量,因为每个通道或组有独立范围。但更细粒度会增加元数据与内核复杂度。此外,检查点格式、量化方案与推理内核必须匹配,例如非对称GPTQ检查点兼容内核较少,Marlin后端不支持非对称GPTQ。

校准数据与量化误差

GPTQ和AWQ利用校准激活来减少量化对模型输出的影响,但效果取决于校准样本的代表性。AWQ参考实现固定使用128个样本,不暴露更换数据集的参数。若质量下降,可尝试不同校准集、量化器或比特宽度,但校准代理指标不能替代应用级质量评估。

评估需覆盖质量、内存与延迟

文章建议在代表性输入上评估困惑度、任务准确率,并对比生成结果。性能方面需测量检查点大小、加载内存、预填充与解码峰值内存、首令牌时间及真实批量下的吞吐。小规模诊断基准不足以支撑部署决策,且峰值PyTorch分配可能遗漏其他库占用,应同时检查设备级内存。

❓

Q&A

仅权重量化是什么意思?它和普通量化有什么区别?

仅权重量化是指将模型权重存为低比特整数,而激活值保持 FP16 或 BF16 精度。普通量化可能同时量化权重和激活,而仅权重量化只量化权重,主要目的是降低自回归解码时读取权重的开销。

非对称仿射量化中的缩放因子和零点分别起什么作用?

缩放因子 s 决定相邻可表示值之间的距离,零点 z 是实数零对应的整数编码。量化公式为 q = clamp(round(x/s) + z, q_min, q_max),反量化公式为 x_hat = s(q - z)。包含零的实数范围可确保零被精确表示。

逐通道和逐组量化为什么比逐张量量化更能保持模型质量?

逐通道和逐组量化让每个通道或每组拥有自己的量化参数(缩放因子和零点),从而更精细地适应不同权重的数值范围,减少量化误差,因此通常比整个张量共用一个参数的逐张量量化更能保持 LLM 权重质量。

用 TorchAO 做训练后量化时,如何配置逐通道 INT8 仅权重量化?

使用 TorchAO 的 quantize_() 函数,配置 IntxWeightOnlyConfig,设置 weight_dtype=torch.int8、granularity=PerAxis(0)(逐通道)、mapping_type=MappingType.ASYMMETRIC,然后对评估后的模型调用 quantize_ 即可完成训练后量化,激活保持 BF16。

GPTQ 和 AWQ 量化方法有什么不同?它们各自如何减少量化误差?

GPTQ 逐层量化权重,利用近似二阶信息在量化过程中调整剩余权重以补偿先前误差;AWQ 则识别在代表性激活下重要的权重,并搜索缩放因子来保护这些权重后再进行低比特量化。两者都使用校准数据来减少量化对模型输出的影响。

如何将模型转换为 GGUF 格式并用 llama.cpp 运行?

首先用 convert_hf_to_gguf.py 将原始 Hugging Face 模型转换为高精度 GGUF 文件(如 bf16),然后用 llama-quantize 工具量化为所需类型(如 Q4_K_M),最后用 llama-cli 加载量化后的 GGUF 文件进行推理。

评估仅权重量化效果时应该关注哪些指标?

应在目标硬件上评估质量(如困惑度、任务准确率、生成样本对比)、内存占用(检查点大小、峰值内存)、延迟(首 token 时间)和吞吐量(实际批大小与并发下的吞吐),并确保格式、量化方案与推理内核兼容。

🏷️

标签

➡️

继续阅读