4、量化参数:Scale(缩放因子)和Zero-point(零点)的数学原理

好,咱们进入量化最核心的两个参数:ScaleZero-point

说白了,量化就是把浮点数(比如 3.14159)映射到整数(比如 128)的过程。那怎么映射?靠的就是这两个参数。我刚开始接触量化时,总觉得这俩东西很玄乎,后来自己手推了一遍公式,发现其实挺朴素的。

4.1 从数学角度看映射

假设你有一个浮点数范围 [r_min, r_max],要映射到 8 位整数的范围 [0, 255]。那这个映射就是一条直线:

r = S * (q - Z)

其中:

  • r 是真实的浮点数值
  • q 是量化后的整数值
  • S 是 Scale(缩放因子)
  • Z 是 Zero-point(零点)

反过来,从浮点到整数的公式是:

q = round(r / S + Z)

嗯,这里要注意:round 操作会带来精度损失。我在项目中遇到过,有些模型对舍入方式特别敏感,用 floorround 结果能差 2% 的精度。

4.2 Scale(缩放因子)的数学本质

Scale 说白了就是「步长」。它决定了每个整数步长代表多大的浮点数变化。

计算公式很简单:

S = (r_max - r_min) / (q_max - q_min)

举个例子:

  • 浮点范围:[-1.0, 1.0]
  • 量化范围:[0, 255]
  • 那么 S = (1.0 - (-1.0)) / (255 - 0) = 2.0 / 255 ≈ 0.00784

你想想看,这意味着每个整数步长代表约 0.00784 的浮点数变化。S 越小,精度越高,但能表示的范围也越小。

关键点:Scale 是浮点数,在推理时需要用浮点运算。但好在它是个常数,可以提前算好。

4.3 Zero-point(零点)的数学意义

Zero-point 是浮点数 0 对应的整数值。为什么需要它?

我个人的理解是:它解决了「偏移」问题。比如你的数据范围是 [-1.0, 2.0],对称范围是 [-1.0, 1.0] 的话,零点就不在中间了。

计算公式:

Z = round(q_min - r_min / S)

或者更直观的:

Z = round(-r_min / S) + q_min

举个例子:

  • r_min = -1.0, r_max = 2.0
  • S = (2.0 - (-1.0)) / 255 = 3.0 / 255 ≈ 0.01176
  • Z = round(0 - (-1.0) / 0.01176) = round(85.0) = 85

这意味着浮点数 0 对应整数 85。如果数据是对称的,Z 通常接近 128(对于 8 位无符号)。

小技巧:我习惯在量化前先检查数据的分布。如果数据集中在 0 附近,Z 会接近 128;如果数据偏正或偏负,Z 会偏移。这个偏移量会影响量化误差。

4.4 对称量化 vs 非对称量化

这里有个重要的分支:对称量化和非对称量化。

类型 特点 Z 值 适用场景
对称量化 r_min = -r_max Z = 0(或 128) 权重(通常对称分布)
非对称量化 r_min ≠ -r_max Z ≠ 0 激活值(ReLU 后全为正)

我曾经在量化一个 MobileNet 时,对权重用了非对称量化,结果精度掉了 5%。后来改成对称量化,精度只掉了 0.5%。为什么?因为权重的分布通常是对称的,非对称量化反而引入了不必要的偏移误差。

4.5 量化误差的数学分析

量化误差主要来自两个方面:

  1. 舍入误差:round 操作带来的,最大误差为 0.5 * S
  2. 截断误差:超出 [r_min, r_max] 的值被截断,误差可能很大

举个例子:

// 假设 S = 0.01, Z = 0
// 浮点数 3.14159
q = round(3.14159 / 0.01 + 0) = round(314.159) = 314
// 反量化
r' = 0.01 * (314 - 0) = 3.14
// 误差 = 3.14159 - 3.14 = 0.00159

嗯,这个误差看起来不大。但如果你的数据范围很大,S 就会变大,误差也会变大。

避坑指南:我曾经在量化一个语音模型时,没注意输入数据的动态范围。结果有个通道的峰值是其他通道的 10 倍,导致 S 被拉得很大,其他通道的精度全毁了。后来我用了逐通道量化(per-channel quantization),才解决了这个问题。

4.6 实际应用中的选择

在 STM32 上做量化时,我一般遵循这几个原则:

  • 权重:用对称量化,Z=0,计算简单
  • 激活值:用非对称量化,因为 ReLU 后全是正数
  • 偏置:用 32 位整数,不量化,或者用高精度量化

你想想看,如果权重和激活都用对称量化,那卷积计算就变成了整数乘加,效率极高。但激活值如果是对称的,有一半的量化范围就浪费了(因为 ReLU 后全是正数)。

所以,没有绝对的好坏,只有适合不适合。

4.7 小结

Scale 和 Zero-point 是量化的基石。理解它们的数学原理,你就能:

  • 手动计算量化参数
  • 分析量化误差的来源
  • 选择合适的量化策略

下一章,我会讲如何在 STM32CubeAI 中实际配置这些参数,以及如何用代码验证量化效果。到时候咱们再细聊。