推理量化精度调优指南
概述
本章节提供了一套系统化的量化精度调优方法论,遵循“确认精度问题可信→调整离群值抑制算法→调整量化策略→调整校准集→量化回退”的递进路径。详细介绍了各步骤的操作方法、算法对比和配置示例,帮助用户在可接受的精度损失内实现模型的高效量化部署。
调优步骤详解
- 确认精度问题可信
在开始调优前,需要排除环境干扰,确保问题真实存在。具体可参见表1。
- 调整离群值抑制算法(关键步骤)
激活值中的离群值会大幅扩展量化范围,占用有效量化比特,导致精度损失。可以使用离群值抑制算法,将激活的量化难度“转移”到权重上。具体可参见表2。
表2 离群值抑制算法对比 算法
算法特点
适用场景与建议
配置示例链接
Smooth Quant
仅对norm-linear子图做平滑处理,支持对称/非对称
在Qwen、DeepSeek等热门系列模型上精度较差,不建议使用
Iterative Smooth
解决o_proj、down_proj等层因无相邻LayerNorm而无法转移scale的问题。支持对称/非对称
优先使用。运行快,精度较高。超长序列校准集时优先使用。可调整 alpha 参数优化
Flex Smooth Quant
通过二阶段网格搜索自动寻找最优alpha和beta参数,实现更精细的平衡
当Iterative Smooth不达标、对量化时间不敏感且显存充足时尝试。运行速度较慢
QuaRot
通过对权重和激活进行旋转变换,将离群值"分散"到多个通道,平滑分布
可与其他算法叠加使用,作为进一步提升精度的备选方案。
总结建议
- 优先选用Iterative Smooth算法:运行速度快,精度较高,是大多数场景下的首选方案。
- 对称性选择:非对称离群值抑制算法在大多数情况下优于对称方案,但需提前确认推理引擎是否已完成对非对称离群值抑制算法的适配支持。
- 参数调优:若Iterative Smooth算法的量化精度未达预期,可通过调整alpha参数进行针对性优化。
- 进阶方案:若调整后精度仍无法满足需求,可进一步尝试启用Flex Smooth Quant算法,或通过叠加QuaRot算法实现协同优化。
- 量化算法选择
根据量化对象(权重/激活)和比特数选择合适算法。量化算法选择包括表3 权重量化方法对比选择和表4 激活量化方法对比选择两部分。
表3 权重量化方法对比 量化方法
特点
量化精度
量化速度
适用场景与建议
minmax
统计权重张量的最小值和最大值来确定量化范围,方法简单,计算速度快
低
快
INT8量化场景优先推荐。方法简单,速度快,通常能获得不错的精度
ssz
通过迭代搜索最优的量化参数来最小化量化误差
中
中
INT4等低比特量化场景优先推荐。相比 minmax,通过更精细的搜索可以获得更高的量化精度,但速度稍慢
autoround
通过引入可学习的舍入偏移参数,结合SignSGD优化器自适应调整各权重的舍入方向,训练得到最优的取整补偿
高
慢
当 ssz 方法精度不达标时,可以尝试使用 autoround 来进一步提升精度,尤其在超低比特条件下寻求最优平衡
配置示例 (YAML)
在量化配置文件中,权重量化通常在 linear_quant 处理器的 qconfig.weight 部分进行配置:- type: "linear_quant" qconfig: weight: scope: "per_channel" # 量化粒度:per_channel dtype: "int8" # 量化数据类型:int8 或 int4 symmetric: true # 是否对称量化:权重量化通常使用对称量化 method: "minmax" # 量化方法:minmax、ssz 或 autoround总结建议
- INT8权重量化:优先使用 minmax 方法,在保证精度的同时速度最快。
- INT4等低比特权重量化:优先使用 ssz 方法,若精度不足再尝试 autoround方法。
- 量化粒度 (scope):权重量化建议使用逐通道(per_channel),这会比逐张量(per_tensor)粒度更细,能获得更高的量化精度。
- 对称性 (symmetric):权重量化通常设置为 true(对称量化),计算更简单高效。
表4 激活量化方法对比 量化方法
特点
量化精度
量化速度
适用场景与建议
minmax
统计激活张量的最小值和最大值来确定量化范围,方法简单,计算速度快
低
快
优先推荐。方法简单,速度快,适用于大多数场景
histogram
通过分析激活值的直方图分布,自动搜索最优的截断区间,过滤离群值,提高量化精度和模型性能
高
慢
当 minmax 方法精度不足时,可以尝试使用 histogram 来进一步提升精度,但速度稍慢
激活值量化粒度选择
激活值量化支持多种粒度,对精度和性能有直接影响,具体可参见表5。
表5 激活值量化粒度对比 粒度类型
特点
适用场景
per_tensor
整个张量使用一组量化参数。静态量化。计算简单,性能最好,几乎所有硬件都支持。但当张量内数据分布差异大时,量化误差显著
追求最佳性能时使用
per_token
每个token独立使用一组量化参数。动态量化。量化粒度更细,能获得更高的量化精度,但计算也更复杂,性能较差
追求更高精度时使用
pd_mix
profiling阶段使用 per_token,decoding阶段使用 per_tensor。混合策略。旨在平衡精度和性能
需要平衡精度和性能时使用
配置示例 (YAML)
在量化配置文件中,激活值量化通常在 linear_quant 处理器的 qconfig.act 部分进行配置。- type: "linear_quant" qconfig: act: scope: "per_tensor" # 量化粒度:per_tensor、per_token 或 pd_mix dtype: "int8" # 量化数据类型:int8 或 int4 symmetric: false # 是否对称量化:激活值量化通常使用非对称量化 method: "minmax" # 量化方法:minmax weight: scope: "per_channel" dtype: "int8" symmetric: true method: "minmax"总结建议
- 量化方法:优先使用minmax方法,当精度不足时可尝试histogram方法。
- 量化粒度 (scope):
- 追求性能时,使用per_tensor(静态量化)。
- 追求精度时,使用per_token(动态量化)。
- 需要平衡精度和性能时,使用pd_mix(混合策略)。
- 对称性 (symmetric):激活值量化通常设置为false(非对称量化),以更好地适应非零中心的数据分布。
- 校准集调整
当算法调整效果有限时,通过优化校准数据来提升量化模型精度。校准集的质量直接影响量化参数的准确性。具体可参考表6。
表6 校准集优化策略 调整策略
具体操作
优化目的
增加数据量
适当增加数据量(建议10-50条样本)
提升量化参数估计的准确性
匹配应用场景
使用与模型应用场景匹配的数据(如中文模型用中文数据,代码模型用代码数据)
使校准数据更贴近实际应用场景
平衡数据分布
从多个数据集中抽取样本混合,平衡数据分布
提升数据分布的多样性和均衡性
删除异常数据
删除导致精度显著下降的校准数据
减少异常样本对量化参数的干扰
加入badcase
加入模型在该数据集上的badcase数据,以更好地反映模型真实输入分布
帮助量化模型学习困难样本,提升精度
总结建议
- 数据量:建议使用10-50条样本,过少可能无法充分估计量化参数,过多则可能增加量化时间。
- 场景匹配:优先使用与模型应用场景匹配的数据,确保校准集能代表实际使用场景。
- 数据质量:及时删除异常数据,避免对量化参数产生负面影响。
- 困难样本:适当加入badcase数据,有助于提升模型在困难样本上的量化精度。
- 量化回退(最终手段)
当通过算法和校准集调整仍无法达到预期精度时,可针对模型中最敏感层进行回退处理,使其保持高精度(FP16/BF16),从而有效缓解量化带来的精度下降问题。
- 使用场景
- 通过步骤1-4调整后,精度仍无法满足精度要求
- 需要在精度和性能之间寻求更精细的平衡
- 某些特定层对量化极度敏感,需要保持高精度
- 操作流程
- 配置示例
- type: "linear_quant" qconfig: act: scope: "per_tensor" dtype: "int8" symmetric: false method: "minmax" weight: scope: "per_channel" dtype: "int8" symmetric: true method: "minmax" include: ["*"] exclude: ["*model.layers.*.mlp.down_proj*"] # 回退所有mlp.down_proj层 - 总结建议
- 优先回退建议:通过经验得知,mlp.down_proj层通常是量化敏感度最高的层之一,建议将其列为回退的优先对象。
- 权衡代价:回退会部分减少量化带来的性能提升和内存节省收益,需要根据具体的业务目标来决定回退的层数和范围。
- 回退策略:建议采用“从上到下”的策略,从敏感度最高的层开始,进行逐步回退,以在模型精度与计算性能之间找到最优平衡点。
- 使用场景