4. 训练后量化(PTQ):校准数据集、精度损失分析、混合精度量化

训练后量化,简称PTQ,是咱们部署模型时的「第一道防线」。说白了,就是模型训练完了,我们直接把它从FP32转成INT8或者更低精度。我个人觉得,PTQ比QAT(量化感知训练)省心太多了——不需要回炉重训,数据集也不用重新标注,成本低到令人发指。

但问题来了:为什么有些模型PTQ之后精度掉得像瀑布,有些却几乎不掉?这里面的门道,我们来拆开看看。

训练后量化 (PTQ) 核心流程 已训练的 FP32 模型 校准数据集准备 (Calibration Dataset) 统计激活值分布 (Min/Max/Histogram) 精度损失分析 逐层对比 FP32 vs INT8 误差 混合精度量化策略 敏感层保留 FP16 / FP32 量化后的 INT8 / 混合精度模型 关键:数据分布必须对齐 关键:误差边界在 1% 以内

4.1 校准数据集:选错了,后面都是白搭

校准数据集的目的是「摸清」模型各层的激活值分布。你想想看,如果你不知道数据长什么样,怎么确定缩放因子?

选多少张图?不是越多越好。我记得有一次项目,团队用了10000张图做校准,结果精度反而不如512张的版本。为什么?因为数据量太大,分布被「平均化」了,极端值被淹没,量化后反而容易溢出。

我的经验: 分类模型推荐 500~2000 张,检测和分割模型可以稍多,2000~5000 张。关键不是数量,是这些样本要能代表你真实的推理数据分布。

选哪些数据?

  • 覆盖各类别: 不要全是「猫」,要混进「狗」、「车」、「房子」
  • 包含难样本: 低光照、模糊、遮挡的样本,能暴露量化误差
  • 避免离群值: 纯白噪点图或者全黑图,会让校准结果崩掉

我见过一个案例,有人拿验证集做校准,精度掉1.2%,换了个更均匀的数据采样,精度只掉0.3%。差距就在这里。

4.2 精度损失分析:到底是谁在拖后腿

模型量化后精度掉了,你第一反应是什么?我刚开始做的时候,到处找原因,调参数调半天没效果。后来摸出门道了:逐层对比。

把量化前后每一层的输出拉出来,算一下余弦相似度或者相对误差。你会发现——

  • 80%的层误差 < 1%,这些层随便量化
  • 15%的层误差在 1%~5%,需要关注
  • 5%的层误差 > 5%,就是这些「害群之马」把整个模型拖垮了
避坑指南: 我曾经遇到过一层卷积,误差居然高达 34%。找了一整天才发现,那层的输入分布极度不平衡 —— 99%的值集中在 [-0.1, 0.1],剩下1%却跑到 [-50, 50]。标准 MinMax 量化完全失效。后来换成了 KL 散度校准,误差降到 2.1%。
常用校准方法对比
方法 原理 适用场景 我的推荐评级
MinMax 取激活值的最小最大值 分布均匀、无严重离群值的层 ⭐⭐
KL 散度 最小化量化前后分布差异 大多数情况,通用性好 ⭐⭐⭐⭐
Percentile 截断头尾一定比例的值 存在离群值时表现优秀 ⭐⭐⭐⭐⭐
MSE 最小化均方误差 对精度敏感的层 ⭐⭐⭐

我个人习惯的做法:先用 Percentile 校准作为基础方案——我一般取 99.9% 的截断,然后再对误差超过 2% 的层单独调。

4.3 混合精度量化:该放手时就放手

不是所有层都适合量化到 INT8。有些层天生倔强,你一量化它就崩。那就别硬来,给它保留 FP16 或者 FP32。

哪些层容易出问题?

  • 第一层和最后一层: 输入输出层对精度最敏感,我通常直接保留 FP32
  • 残差连接中的加法层: 误差会累积,尤其是 ResNet、Transformer 的结构
  • Bottleneck 层: 维度压缩再恢复,量化误差会被放大
  • 注意力机制中的 Softmax: 输出范围 [0,1],但极度不均匀,量化后容易丢失小概率信息

来看看实际配置:

# 假设用的 NVIDIA TensorRT 或者 ONNX Runtime
# 混合精度策略示例
sensitive_layers = [
    "conv1",       # 第一层 -> FP32
    "fc_out",      # 最后一层 -> FP32
    "res_add_*",   # 所有残差加法 -> FP16
    "softmax_*"    # 注意力 Softmax -> FP16
]

# 其余层自动选择 INT8

根据我的项目数据,一个标准的 ResNet-50 用混合精度量化后,精度损失可以从 1.8% 降到 0.3%,推理速度只慢 5%。这笔账,太划算了。

核心思路: 混合精度量化的本质不是「暴力压缩」,而是「精细化修剪」。该保的地方保,该压的地方压。你用精度损失最小的 20% 层扛起 FP32 的开销,换来剩下 80% 层极致加速。

4.4 PTQ实战步骤:从配置到验证

  1. 准备校准数据: 从训练集中均匀采样 1000~2000 张,确保覆盖全类别
  2. 运行校准: 前向传播一次,收集各层激活值分布
  3. 计算缩放因子: 根据你选的校准方法(推荐 Percentile 99.9%),得到 scale 和 zero_point
  4. 模拟量化: 在意 INT8 forward 上跑一遍,收集每层量化误差
  5. 误差分析: