4、训练后量化(PTQ):校准数据集的选择,KL散度与MSE两种校准方法
说到训练后量化,也就是 PTQ,这可能是咱们嵌入式部署中最常用的一招了。你想想看,模型训好了,直接拿来量化,不用重新训练,多省事。但这里有个关键问题——校准数据集怎么选?选不好,量化后的模型精度可能直接崩掉。
我个人习惯把 PTQ 分成两步走:第一步是选好校准数据,第二步是选好校准方法。今天咱们就重点聊聊这两件事。
校准数据集:别随便拿几张图就上
校准数据集,说白了就是用来「摸清」模型激活值分布的一组数据。量化的时候,我们需要知道每一层输出的数值范围,才能决定怎么把 float32 映射到 int8。
我在项目中遇到过这样一个坑:有次做一个人脸检测模型,随手拿了 100 张风景图做校准。结果量化后模型在测试集上直接掉了 5 个点。后来换成 500 张人脸图,精度只掉了 0.3 个点。嗯,校准数据的选择就是这么敏感。
校准数据集选择的核心原则:
- 代表性:校准数据必须来自训练集的分布,或者至少和实际部署场景一致
- 多样性:覆盖各种可能的输入情况,别只挑简单的
- 数量适中:一般 200-1000 张就够了,太多反而浪费计算资源
你可能会问:「那我直接用训练集行不行?」理论上可以,但没必要。训练集太大,校准过程会变得很慢。而且,用训练集校准容易过拟合到训练数据的分布上,泛化性反而不好。
我一般会从验证集里随机抽 500 张左右。如果验证集也不大,那就用全部验证集。记住一个原则:校准数据要能代表你模型在实际场景中会遇到的数据。
KL 散度校准:让分布尽量接近
KL 散度,全称 Kullback-Leibler divergence,中文叫相对熵。它衡量的是两个概率分布之间的差异。在量化中,我们用它来找到最佳的量化阈值。
具体怎么做呢?
- 收集校准数据,跑一遍前向推理,记录每一层的激活值
- 把这些激活值统计成直方图,得到原始 float 分布的近似
- 尝试不同的量化阈值,把原始分布截断后量化到 int8
- 计算量化后的分布和原始分布的 KL 散度
- 选择 KL 散度最小的那个阈值
说白了,KL 散度校准就是在找一个「最优截断点」。因为 int8 只能表示 256 个值,而 float32 的范围可能很大。我们得决定哪些值可以丢掉,哪些值必须保留。
我的经验:KL 散度对激活值中的「长尾分布」特别有效。如果你的模型激活值有很多离群点,KL 散度通常比 MSE 表现好。我在做 MobileNet 量化时,KL 散度比 MSE 高了 0.8 个点。
MSE 校准:最小化量化误差
MSE,均方误差,这个大家应该很熟悉了。在量化校准中,它的思路更直接:找到一组量化参数,让量化前后的数值误差最小。
公式很简单:
MSE = (1/N) * Σ (x_float - x_quant)^2
其中 x_float 是原始 float 值,x_quant 是量化后再反量化回来的值。我们遍历所有可能的量化阈值,选 MSE 最小的那个。
MSE 校准的好处是计算简单,容易理解。但它有个问题:它对所有数值一视同仁。不管是大值还是小值,误差权重都一样。这在实际中不一定合理——有些数值范围对模型精度影响更大。
注意:MSE 校准对「均匀分布」的数据效果很好。但如果你的激活值分布严重偏斜,MSE 可能会把量化阈值选得偏大或偏小。我曾经在 ResNet-50 上对比过,当激活值分布比较集中时,MSE 和 KL 散度结果差不多;但分布很散时,KL 散度明显更优。
两种方法怎么选?
我整理了一个对比表格,方便你参考:
| 对比维度 | KL 散度 | MSE |
|---|---|---|
| 核心思想 | 最小化分布差异 | 最小化数值误差 |
| 适用场景 | 长尾分布、非对称分布 | 均匀分布、对称分布 |
| 计算复杂度 | 较高(需要统计直方图) | 较低(直接计算误差) |
| 对离群点敏感度 | 低(会自动截断) | 高(离群点会拉大误差) |
| 实际效果 | 多数场景下更优 | 分布均匀时不错 |
我个人习惯的做法是:先试 KL 散度,如果精度下降在可接受范围内,就用它。如果 KL 散度效果不好,再试试 MSE。有时候两种方法结合使用效果更好——比如对某些层用 KL,对另一些层用 MSE。
避坑指南
最后分享几个我踩过的坑:
- 校准数据太少:我曾经只用 50 张图做校准,结果量化后模型在某些类别上完全失效。后来加到 300 张,问题解决了。
- 校准数据太「干净」:有次做工业检测模型,校准数据全是完美光照下的图片。部署到现场后,光线一变,模型精度直接掉到 60%。后来在校准数据里加了各种光照条件,才稳住。
- 忽略 BatchNorm 层:量化前一定要把 BatchNorm 层融合到卷积层里,否则校准结果会偏差很大。这个我后面会专门讲。
嗯,关于 PTQ 的校准数据选择和两种校准方法,今天就聊这么多。记住一句话:校准数据选得好,量化成功一半。剩下的,就是选对方法,调好参数了。