4. 量化对视觉模型精度的影响机理
要理解量化为什么会让视觉模型掉点,不能只盯着“位宽从 32 降到 8”这个数字,而要看清数值在模型内部经历了什么。量化的本质是把连续的浮点值映射到有限的离散格点上,映射公式通常写作 q = clamp(round(x / s) + z, q_min, q_max),其中 s 是缩放因子(scale),z 是零点(zero point)。一旦 s 被某个极端值撑大,绝大多数正常数值就会被挤到很少的几个格点里,舍入误差随之放大。视觉模型精度下降的根源,几乎都能追溯到“谁决定了 s”以及“哪些值被牺牲了”。
先看三类核心算子对量化的敏感度差异。卷积是权重密集、计算量最大的部分,但它的权重分布通常接近零均值、近似对称的钟形,且同一层内数值范围相对可控,因此权重量化一般比较友好。真正棘手的是卷积的激活输入:经过 ReLU 后激活被截断为非负,分布强烈右偏,少数通道可能出现远高于均值的响应,这会直接拉大激活的 s。归一化层(BN、LayerNorm)本身参数少,但它对量化极其敏感,因为它依赖均值与方差做仿射变换,量化误差会改变统计量的等效作用,尤其在推理时 BN 已被折叠进卷积的情况下,折叠后的权重范围可能被显著放大。激活函数则决定了激活的分布形态:ReLU 产生非负稀疏分布,GELU、SiLU 更平滑但存在负值长尾,Sigmoid/Tanh 有饱和区,这些形态直接决定激活量化是“好量化”还是“难量化”。
权重与激活的分布差异,是量化工程中最需要区别对待的一对矛盾。权重在训练收敛后通常呈现零均值、近似对称、尾部较短的分布,因此对称量化(z=0)就能取得不错效果,且每层权重数量固定,校准稳定。激活则完全不同:它随输入图像变化,分布动态且右偏,ReLU 之后大量值集中在零附近,但少数通道可能因某个强纹理、高对比边缘或小目标而产生极大响应。如果按全局 min/max 确定激活的 s,这些异常值会主导缩放因子,使绝大多数正常激活只落在两三个量化格点上,等效于把有效位宽降到了 3~4 bit。这就是“长尾与异常值问题”的核心:不是所有值都难量化,而是少数极端值绑架了整体映射。
长尾问题在视觉任务中尤其突出。检测模型中的小目标、分割模型中的细边界、分类模型中的高饱和区域,都容易在中间层产生离群激活。逐层看,浅层卷积对颜色和边缘敏感,激活范围宽;深层语义特征虽然更抽象,但通道间差异大,某些通道可能长期处于低响应,另一些通道则频繁出现尖峰。若统一用一套 s,低响应通道会被量化到零附近,信息直接丢失。工程上常见的应对是逐通道量化(per-channel)用于权重,逐张量或逐通道用于激活,并配合百分位截断(如取 99.9% 分位数而非最大值)来抑制异常值。例如某层激活最大值为 12.0,但 99.9% 分位数为 3.2,若按 12.0 定 scale,8 bit 下格点间距约 0.094;按 3.2 定 scale,格点间距约 0.025,正常值精度提升近 4 倍,代价是极少数超过 3.2 的值被截断,通常对最终指标影响远小于舍入误差的改善。
归一化层的敏感度还体现在“折叠”这一操作上。推理时 BN 常被折叠进前一层卷积:W' = W · γ/σ,b' = β − γ·μ/σ。折叠本身不改变浮点结果,但会改变权重的数值范围。如果某通道 σ 很小,γ/σ 会放大权重,使该通道权重出现离群值,进而拉大权重量化的 s。因此,在量化前检查折叠后各通道权重的最大绝对值分布,比只看原始权重更有意义。若发现个别通道权重被放大数十倍,可考虑对该层采用逐通道量化,或在校准阶段对该通道单独处理。
激活函数的选择同样影响量化难度。ReLU 输出非负,天然适合非对称量化(z≠0),但负半轴信息全部丢失,若某层依赖负激活表达特征,量化后会更脆弱。SiLU、GELU 保留负值且曲线平滑,分布更接近对称,理论上对对称量化更友好,但其负值长尾仍可能产生离群点。Sigmoid、Tanh 在饱和区梯度接近零,量化误差在饱和区被压缩,反而相对稳定,但中间线性区对格点密度要求高。实际部署中,若发现某激活函数层量化后掉点明显,可优先尝试保留该层为浮点(混合精度),而不是强行全量化。
把上述机理落到工程判断上,可以形成一条清晰的因果链:异常值或长尾 → 缩放因子被撑大 → 正常值落入少数格点 → 舍入误差放大 → 逐层累积 → 最终指标下降。反过来,量化的优化方向也就明确了:要么压缩异常值的影响(截断、逐通道、平滑),要么给敏感层保留更高精度(混合精度),要么在训练阶段让模型适应量化(QAT)。理解卷积、归一化、激活函数各自的敏感点,以及权重与激活分布的差异,才能在面对具体掉点现象时,快速判断问题出在映射的哪一环,而不是停留在“8 bit 就是会掉点”的模糊认知上。