3. 模型量化原理:FP32到INT8的转换、对称量化与非对称量化、量化误差分析

好,咱们进入第三章。这一章聊量化,说白了就是怎么把模型从「养尊处优」的FP32,塞进INT8这个「小房子」里。

我刚开始接触NPU部署时,觉得量化就是个简单的除法。结果第一次跑出来的模型,精度直接掉了5个点,被算法同事追着问了一下午。嗯,从那以后,我再也不敢小看量化了。

3.1 为什么非要从FP32转到INT8?

你想想看,FP32一个数占4个字节,INT8只占1个字节。模型体积直接缩小4倍。带宽占用也小了,计算速度能快好几倍。

更重要的是,NPU的硬件乘法器,做INT8计算比FP32快得多。我见过一个项目,量化后推理速度从30fps直接飙到120fps。代价呢?精度损失控制在0.5%以内。

所以,量化不是「能不能做」的问题,而是「怎么做才能损失最小」的问题。

3.2 量化的核心公式

量化本质上就是一个映射:把FP32的浮点数范围,映射到INT8的整数范围。

公式很简单,就两个:

量化:q = round(r / S) + Z
反量化:r = (q - Z) * S

这里:

  • r:原始浮点数(FP32)
  • q:量化后的整数(INT8)
  • S:缩放因子(Scale),一个浮点数
  • Z:零点偏移(Zero Point),一个整数

说白了,S决定了「步长」,Z决定了「偏移」。这两个参数选对了,量化就成功了一半。

关键点:量化不是简单的截断,而是带舍入的映射。round操作会引入误差,这是量化误差的主要来源之一。

3.3 对称量化 vs 非对称量化

这里有个选择题:你的数据分布是对称的吗?

3.3.1 对称量化

对称量化,就是让零点Z=0。公式简化成:

q = round(r / S)

好处是计算简单,硬件实现容易。很多NPU默认就支持对称量化。

但有个坑:如果数据分布不对称,比如ReLU后的激活值全是正数,对称量化会浪费一半的INT8表示范围(负数部分全空着)。

我曾经在一个项目中,用对称量化量化ReLU后的特征图,精度直接掉了2%。后来换成非对称量化,精度就回来了。

3.3.2 非对称量化

非对称量化,Z可以不为0。它能更好地匹配数据分布。

比如你的数据范围是[0, 6.0],非对称量化可以把INT8的[-128, 127]映射到[0, 6.0]上,一个比特都不浪费。

代价呢?计算时多一步减法,硬件稍微复杂一点。但现在的NPU基本都支持,所以别怕。

对比项 对称量化 非对称量化
零点Z 固定为0 可调节
计算复杂度
数据适配性 适合对称分布(如权重) 适合非对称分布(如激活值)
硬件支持 几乎所有NPU 大部分NPU

我的习惯:权重用对称量化,激活值用非对称量化。这是业界主流做法,也是我踩过坑后总结出来的。

3.4 量化误差分析

量化一定会引入误差,关键是怎么控制它。

3.4.1 误差来源

主要有三个:

  1. 舍入误差:round操作导致的。比如3.14159量化成3,丢了0.14159。
  2. 截断误差:超出INT8范围的值被截断。比如最大值是200,INT8只能表示到127,那73就丢了。
  3. 精度损失:S太大,导致相邻两个INT8值对应的浮点数差距太大。比如S=0.1,那量化后的分辨率就是0.1,小于0.1的差异都丢了。

3.4.2 如何评估误差

我常用的指标是:

  • 量化误差(Quantization Error):|r - r_hat|,单个值的误差
  • 均方误差(MSE):所有误差的平方的平均值
  • 余弦相似度:量化前后特征向量的夹角余弦,越接近1越好

举个例子:

原始FP32张量: [0.5, 1.2, 3.8, 5.0]
量化后INT8:    [13,  31,  97,  127]  (假设S=0.03937, Z=0)
反量化后:      [0.512, 1.220, 3.819, 5.000]

误差:          [0.012, 0.020, 0.019, 0.000]

你看,误差都在0.02以内,对于大多数视觉任务来说,完全可以接受。

注意:量化误差不是均匀分布的。在数值较小的区域,相对误差可能很大。比如0.1量化成0.12,绝对误差0.02,但相对误差20%。如果你的模型对小数敏感,要特别小心。

3.5 实战中的量化策略

光讲理论不够,我分享几个实战经验:

3.5.1 校准数据集

量化时需要知道数据的真实范围。用几百张图片做校准就够了。我一般用验证集的子集,大概500张。

3.5.2 逐层量化 vs 逐通道量化

逐层量化:整个层用一个S和Z。简单,但误差大。

逐通道量化:每个输出通道有自己的S和Z。精度更好,但计算量稍大。

我个人习惯:权重用逐通道量化,激活值用逐层量化。平衡精度和效率。

3.5.3 量化感知训练(QAT)

如果后训练量化(PTQ)精度不够,就用QAT。在训练时模拟量化过程,让模型自己适应量化误差。

我曾经有一个分割模型,PTQ后mIoU掉了3%。用了QAT后,只掉了0.3%。虽然训练时间多了两天,但值得。

3.6 小结

量化不是玄学,是工程。理解FP32到INT8的映射,选对对称或非对称量化,分析好误差来源,你就能在精度和速度之间找到最佳平衡点。

下一章,咱们聊聊具体的量化工具和流程。到时候我会手把手带你走一遍完整的量化部署流程。