量化基础:模型量化的基本概念、定点与浮点表示、量化参数(scale/zero-point)与对称/非对称量化
模型量化是深度学习部署中最核心的压缩加速手段之一,其本质是将神经网络中连续分布的浮点权重和激活值,映射到离散的定点数(或低比特整数)空间。理解量化基础,是后续掌握伪量化节点(FakeQuant)插入位置、训练收敛性调优的前提。本章将从数值表示的根本差异出发,系统拆解定点与浮点的数学本质、量化参数(scale/zero-point)的推导逻辑,以及对称/非对称量化在工程中的选择依据。
2.1 定点与浮点表示:数值世界的两种语言
核心原理
浮点数(Floating-Point)采用科学计数法的二进制形式,由符号位(Sign)、指数位(Exponent)和尾数位(Mantissa)组成。以FP32为例,1位符号、8位指数、23位尾数,可表示约1.18×10⁻³⁸到3.4×10³⁸的动态范围,且精度随数值大小自适应变化。定点数(Fixed-Point)则约定小数点位置固定不变,例如Q1.7格式表示1位整数位和7位小数位,范围仅[-1, 1),精度固定为2⁻⁷≈0.0078。
在神经网络推理中,浮点运算需要复杂的指数对齐和尾数规格化,而定点运算只需简单的整数乘加。以ARM Cortex-A系列CPU为例,FP32乘法通常需要3-5个周期,而INT8乘法仅需1个周期,且SIMD(单指令多数据)宽度翻倍。这意味着量化到INT8后,理论峰值算力可提升4倍以上,同时内存带宽压力降低75%。
判断方法:何时选择定点,何时保留浮点
- 动态范围需求:若张量值分布跨越多个数量级(如10⁻⁶到10³),定点数无法覆盖,必须使用浮点或分块量化。
- 精度敏感度:分类任务顶层特征对量化误差容忍度较高,而回归任务(如目标框回归)或分割任务的边界像素对精度极其敏感。
- 硬件指令集:检查目标芯片是否支持INT8 DOT(点积)指令。NVIDIA Tensor Core、高通Hexagon DSP均原生支持INT8,而部分MCU仅支持INT16。
- 混合精度策略:现代部署框架(如TensorRT、OpenVINO)支持层级别精度选择,敏感层保留FP16,非敏感层使用INT8。
案例拆解:FP32到INT8的数值映射推演
假设某层激活值张量实测范围为[-2.5, 6.0],目标位宽为INT8(qmin=-128, qmax=127)。采用非对称量化:
S = (6.0 - (-2.5)) / (127 - (-128)) = 8.5 / 255 ≈ 0.03333
Z = round(-(-2.5) / 0.03333) - 128 = round(75.0) - 128 = -53
验证:r = 0 时,q = round(0/0.03333) + (-53) = -53
反量化:r = 0.03333 × (-53 - (-53)) = 0.0 ✓
若采用对称量化(Z=0),则需取绝对值最大者6.0,S=6.0/127≈0.04724。此时r=0映射到q=0,但r=-2.5映射到q=round(-2.5/0.04724)≈-53,而r=6.0映射到q=127。对称量化在负半轴的精度损失明显:步长从0.0333增大到0.0472,相对误差增加约41.7%。
常见误区与复盘
误区2:忽略溢出风险。INT8乘法结果需要累加到INT32,若累加次数超过2^31/127²≈132,000次,可能溢出。在深度可分离卷积中,逐通道累加次数通常小于此值,但全连接层需谨慎。
2.2 量化参数Scale与Zero-Point的数学本质
核心原理
量化映射的数学表达式为:q = clamp(round(r/S) + Z, qmin, qmax),反量化为r = S(q - Z)。其中Scale(S)是浮点标量,表示每个量化步长代表的实数范围;Zero-Point(Z)是整数,表示实数0对应的量化值。S和Z的确定依赖于张量的实际数值范围(rmin, rmax),而非理论边界。
Scale的计算公式为S = (rmax - rmin) / (qmax - qmin)。Zero-Point的推导需保证实数0无损映射:Z = round(qmin - rmin/S)。当采用对称量化时,令Z=0,S=max(|rmin|, |rmax|)/qmax,此时正负范围对称,但若分布偏斜,会浪费部分量化区间。
操作流程:校准与参数确定
- 数据收集:使用验证集(通常500-1000张图)前向推理,记录每层激活值的直方图分布。
- 范围选择:直接使用min/max(易受离群点影响);或使用百分位法(如99.99%分位)截断极端值;或使用KL散度最小化(TensorRT默认方案)。
- 参数计算:根据选定范围计算S和Z,并保存为每通道(per-channel)或每张量(per-tensor)参数。
- 伪量化模拟:在训练图中插入FakeQuant节点,前向传播时执行量化-反量化循环,反向传播时使用直通估计器(STE)近似梯度。
| 校准方法 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| MinMax | 直接取张量实际最小/最大值 | 实现简单,无额外计算 | 对离群点敏感,浪费量化区间 | 权重分布均匀的层 |
| 百分位 | 截断0.01%~0.1%的极端值 | 抗离群点,保留主要分布 | 需调参,可能丢失尾部信息 | 激活值存在长尾分布 |
| KL散度 | 最小化原始分布与量化分布的KL距离 | 信息损失最小,理论最优 | 计算量大,需多次迭代 | 高精度要求场景(如检测模型) |
| MSE最小化 | 最小化量化前后张量的均方误差 | 直接优化数值误差 | 需梯度计算,实现复杂 | 研究实验,离线量化 |
案例拆解:per-tensor vs per-channel对模型精度的影响
以ResNet-50的3×3卷积层为例,权重张量形状为[64, 256, 3, 3]。per-tensor量化使用全局S和Z,而per-channel量化对输出通道维度(64个通道)分别计算S和Z。实验表明:per-channel量化在MobileNetV2上可减少2.3%的Top-1精度损失,因为深度可分离卷积的每个通道权重分布差异极大(部分通道值域仅[-0.1, 0.1],部分达[-2.0, 2.0])。但per-channel量化在硬件实现上需要额外的反量化操作,增加约5%的计算开销。
2.3 对称量化与非对称量化:精度与计算复杂度的权衡
核心原理
对称量化强制Zero-Point=0,映射关系简化为q = round(r/S),反量化为r = S·q。其优势在于计算简化:INT8乘加后无需减去零点偏移,且卷积运算中零点不会引入额外的加法项。非对称量化允许Z≠0,能更充分利用INT8的256个量化级别,尤其适合ReLU后激活值全为正数的场景。
从信息论角度看,非对称量化相当于在量化前对信号进行直流偏移调整,使量化区间与信号分布对齐。对于均匀分布信号,非对称量化可减少约1bit的量化误差(等效于增加1bit有效位宽)。但代价是:卷积计算时需额外处理(q - Z)项,导致乘加运算变为Σ(q1-Z1)(q2-Z2),展开后多出4个累加项,增加约25%的计算量。
判断方法:选择量化模式的决策树
- 步骤1:检查张量值域是否包含0。若rmin≥0(如ReLU输出),非对称量化可避免负半轴浪费。
- 步骤2:评估硬件支持。部分NPU(如寒武纪MLU)对非对称量化有硬件加速指令,而GPU Tensor Core仅优化对称量化。
- 步骤3:对比精度损失。在ImageNet分类任务上,非对称通常比对称高0.1%~0.5%精度,但需实测验证。
- 步骤4:考虑部署成本。非对称量化在推理时需要额外的零点修正逻辑,增加代码复杂度和延迟。
实战场景:YOLOv5s目标检测模型的量化模式选择
YOLOv5s的检测头输出包含边界框坐标(无界回归值)和类别概率(有界[0,1])。实验配置:COCO验证集5000张图,TensorRT INT8量化。采用对称量化时,边界框回归分支的误差导致mAP@0.5下降4.2%;改用非对称量化后,mAP仅下降1.8%。进一步分析发现,回归分支输出值域为[-8.5, 12.3],对称量化需覆盖[-12.3, 12.3],浪费了约30%的量化级别。而非对称量化将区间对齐到[-8.5, 12.3],步长缩小23%,显著降低回归误差。
常见误区与总结
误区2:忽略Zero-Point的溢出风险。当Z接近qmin或qmax时,反量化计算
r = S(q-Z)可能产生中间值溢出。例如Z=-128时,q=127,则q-Z=255,若S较大,乘法结果可能超出FP16范围。误区3:在QAT训练中,Zero-Point的梯度处理不当。由于round操作不可导,需使用STE将梯度直接传递给浮点输入,但Zero-Point本身应视为常数,不参与梯度更新。