4. PTQ进阶技巧:逐层量化与逐通道量化、融合BN与Conv、量化敏感层分析与处理
各位同学,咱们今天聊点硬核的。PTQ(Post-Training Quantization)听起来简单,不就是训练完再量化一下吗?但真正落地的时候,你会发现坑多得很。我刚开始做模型部署那会儿,觉得PTQ就是调个scale和zero_point,结果模型精度直接崩了,差点被老板骂死。
后来我才明白,PTQ不是简单的「一刀切」。它有很多进阶技巧,用好了精度几乎不掉,用不好就是灾难。今天我把这些年踩过的坑和总结的经验,一次性讲清楚。
4.1 逐层量化 vs 逐通道量化
先说说最基础的概念。量化的时候,我们得决定:是每一层用一个scale,还是每个通道用一个scale?
逐层量化(Per-Layer Quantization):整层共享一个量化参数。简单粗暴,计算量小,但精度损失大。
逐通道量化(Per-Channel Quantization):每个输出通道独立计算scale和zero_point。精度更高,但计算量也更大。
我个人的习惯是:权重用逐通道量化,激活值用逐层量化。为什么?
- 权重的分布差异大,不同通道的数值范围可能差好几倍。逐通道量化能保留更多信息。
- 激活值的分布相对均匀,逐层量化就够了,而且硬件实现更友好。
核心经验:如果你发现量化后精度掉得厉害,先把权重量化改成逐通道的。这个改动往往能挽回1-3个点的精度。
举个例子,我在部署一个MobileNetV3的时候,逐层量化后Top-1精度掉了4.2%。改成逐通道量化后,只掉了1.1%。效果立竿见影。
4.2 融合BN与Conv
这个技巧,说白了就是把Batch Normalization层「吃掉」。BN在训练时很有用,但在推理时其实可以合并到卷积层里。
为什么要融合?因为BN层本身不做量化,它就是个线性变换。如果不融合,推理时就得先做量化卷积,再做BN,最后再量化一次。多了一次量化,精度就多损失一次。
融合的公式很简单:
# 假设卷积层权重为W,偏置为b
# BN层参数:gamma, beta, mean, var, epsilon
# 融合后的权重
W_fused = W * (gamma / sqrt(var + epsilon))
# 融合后的偏置
b_fused = (b - mean) * (gamma / sqrt(var + epsilon)) + beta
嗯,这里要注意:融合必须在量化之前做。如果你先量化再融合,那融合后的参数就没办法正确量化了。
避坑指南:我曾经在融合BN时忘了处理epsilon,结果模型精度直接崩了。epsilon虽然很小,但在数值计算中不能忽略。建议用float64做融合计算,避免精度损失。
融合BN之后,模型的计算图会变得更简洁。原来需要6个算子(Conv、BN、Scale、Shift、量化、反量化),现在只需要2个(量化卷积、反量化)。推理速度能提升10%-20%。
4.3 量化敏感层分析与处理
这是PTQ进阶里最核心的部分。不是所有层对量化都「敏感」。有些层量化后精度几乎不变,有些层一量化就崩。
怎么找到这些敏感层?我一般用两种方法:
- 逐层精度分析:每次只量化一层,其他层保持float,看精度变化。变化大的就是敏感层。
- 梯度分析:计算每层输出对损失的梯度,梯度大的层通常更敏感。
找到敏感层之后,怎么处理?
- 保留float:如果硬件支持混合精度,就让敏感层跑float16或float32。
- 增加校准数据:用更多、更多样的数据做校准,让量化参数更准确。
- 调整量化位宽:从int8降到int16,或者用非对称量化。
警告:不要一上来就全层保留float。我见过有人把一半的层都保留float,那还不如不做量化。敏感层通常只占5%-10%,重点处理这些就够了。
我记得有一次做YOLOv5的量化,发现前几层卷积特别敏感。后来分析发现,是因为输入图像的分布和校准数据不太匹配。我重新采集了一批和实际场景更接近的校准数据,精度就回来了。
4.4 知识体系总览
说了这么多,咱们用一张图来总结一下PTQ进阶的核心逻辑:
4.5 实战建议
最后,给各位几个实战中的建议:
- 先做融合,再做量化:这个顺序不能乱。融合BN之后再量化,精度更高。
- 校准数据要「像」真实数据:我见过有人用ImageNet的校准数据去量化一个自动驾驶模型,结果精度崩了。校准数据一定要和实际部署场景匹配。
- 敏感层分析要自动化:手动一层层试太慢了。写个脚本,自动逐层量化并记录精度变化,几分钟就能出结果。
- 不要迷信int8:如果int8精度实在保不住,试试int16或者混合精度。有时候int8+float16混合的效果比纯int8好得多。
我的经验:PTQ做到极致,精度损失可以控制在0.5%以内。如果超过1%,说明你的量化策略有问题。回头检查一下:校准数据够不够?敏感层处理了没有?BN融合了没有?
好了,这一章的内容就到这里。PTQ进阶技巧其实不难,关键是要理解每个技巧背后的原理,以及它们之间的配合关系。你想想看,融合BN、逐通道量化、敏感层分析,这三招用好了,大部分模型都能做到无损量化。