模型量化基础:从数学原理到工程实践
大家好,我是你们的老朋友。今天咱们聊聊模型量化——这个在IoT设备上跑大模型绕不开的话题。
说实话,我第一次接触量化是在一个智能门锁项目上。客户要求人脸识别模型跑在Cortex-M4上,内存只有256KB。我当时第一反应是:这不开玩笑吗?后来才发现,量化就是那把钥匙。
量化的本质:用更少的比特说清楚事
量化说白了,就是把模型里的浮点数(通常是FP32)变成整数(INT8或INT4)。为什么要这么干?
- 存储省了:FP32是4字节,INT8是1字节,直接缩到1/4
- 计算快了:整数运算比浮点快得多,尤其在那些没有FPU的MCU上
- 功耗低了:少搬数据、少算,电池自然更耐用
但代价呢?精度会掉。怎么在压缩和精度之间找平衡?这就是咱们今天要啃的硬骨头。
对称量化 vs 非对称量化
先看数学公式。量化的核心就一句话:把实数映射到整数。
对称量化
公式长这样:
q = round(r / S)
其中:
r = 原始浮点值
q = 量化后的整数值
S = 缩放因子(scale)
对称量化的特点是:零点(zero point)固定为0。也就是说,浮点数的0映射到整数的0。
我习惯在权重上使用对称量化。为什么?因为权重分布通常是对称的,正负值差不多。我在做一个人脸检测模型时试过,对称量化后精度只掉了0.3%,但计算量少了将近一半。
适用场景:权重(weights)量化,尤其是ReLU之前的层
非对称量化
公式稍微复杂点:
q = round(r / S) + Z
其中:
Z = 零点(zero point),可以是任意整数
非对称量化的好处是:能处理分布不均匀的数据。比如ReLU之后的激活值,全是非负的。这时候用对称量化会浪费一半的表示范围。
我记得有个项目做语音唤醒,激活值分布严重偏右。用对称量化,精度掉了5%。换成非对称,只掉了1.2%。这就是差距。
我的建议:激活值用非对称量化,权重用对称量化。这是工程上最稳妥的组合。
INT8量化:最成熟的方案
INT8量化是目前工业界的主流。为什么?
- 硬件支持好:几乎所有AI加速器都支持INT8
- 精度损失小:大部分模型掉精度在1%以内
- 压缩比高:模型体积缩到1/4
具体怎么做?以TensorRT为例:
// 伪代码示意
calibrator = Int8Calibrator(calibration_dataset)
network.setInt8Mode(true)
network.setCalibrator(calibrator)
engine = builder.buildEngine(network)
这里有个关键点:校准数据集。后面我会细说。
INT4量化:极限压缩的尝试
INT4量化,说白了就是把每个值用4个比特表示。压缩比是FP32的1/8。
但代价也大。我踩过这个坑——在一个关键词检测模型上试INT4,精度直接掉了12%。后来发现是某些层的敏感度太高。
避坑指南:INT4量化建议只用在非关键层,或者配合混合精度使用。我曾经在最后一层全连接上保留INT8,其他层用INT4,精度只掉了3%,但模型体积又小了40%。
量化误差分析:到底损失在哪?
量化误差主要来自三个方面:
- 截断误差:超出表示范围的值被强行截断
- 舍入误差:round操作带来的精度损失
- 累积误差:多层量化后误差不断放大
我习惯用信噪比(SNR)来评估量化误差:
SNR = 10 * log10( sum(r^2) / sum((r - q)^2) )
一般来说,SNR大于30dB,人眼/人耳就基本分辨不出来了。
但要注意:SNR高不代表模型精度高。我见过一个模型SNR有35dB,但分类准确率掉了8%。为什么?因为误差集中在关键特征上。
核心观点:量化误差分析不能只看全局指标,要逐层看、逐通道看。
校准数据集:量化的灵魂
校准数据集的作用是什么?说白了,就是帮量化器找到合适的S和Z。
怎么选校准集?我总结了三条经验:
- 代表性:必须覆盖真实场景的数据分布。做语音就用语音,做图像就用图像
- 多样性:至少100-500张样本,覆盖各种情况
- 不要用训练集:否则会过拟合,部署后精度崩盘
我记得有个项目,客户拿训练集做校准,结果在测试集上精度掉了5%。换成验证集后,只掉了0.8%。
常用的校准方法有:
| 方法 | 原理 | 适用场景 |
|---|---|---|
| MinMax | 取最小最大值作为范围 | 分布均匀的数据 |
| KL散度 | 最小化量化前后的分布差异 | 大部分场景,推荐 |
| Percentile | 去掉极端值,取百分位点 | 有离群点的数据 |
我个人最常用KL散度。它在精度和压缩率之间平衡得最好。
知识体系总览
下面这张图是我自己画的,把量化的核心逻辑串起来了:
这张图把量化拆成了四个维度:类型、位宽、误差、校准。你想想看,做量化其实就是在这四个维度上做权衡。
最后说一句:量化不是银弹。我见过有人盲目上INT4,结果模型直接废了。我的建议是:先做INT8,精度能接受再试INT4。每一步都要用校准集验证,别偷懒。
公众号:蓝海资料掘金营,微信deep3321