模型量化基础:量化的数学原理、对称量化与非对称量化、量化感知训练
说到模型量化,我脑子里第一个蹦出来的场景是——几年前在某个边缘设备上部署一个BERT模型,显存死活塞不下。那时候我就在想,这模型参数要是能“瘦身”一点该多好。后来接触了量化,才发现这玩意儿比我想象的优雅得多。
量化说白了,就是把模型里那些高精度的浮点数(比如FP32),用低精度的整数(比如INT8)来表示。你想想看,一个FP32占4个字节,INT8只占1个字节,直接压缩到原来的四分之一。代价呢?精度会掉一点点,但很多时候完全能接受。
核心思想:用更少的比特数,去近似表达原来的数值分布。这不是简单的截断,而是有数学依据的映射。
量化的数学原理
量化的本质,就是一个映射函数。我习惯把它理解成“缩放+平移”。
假设我们有一组浮点数 r,想映射到整数 q。数学上可以写成:
q = round(r / S + Z)
其中:
- S 是缩放因子(scale),一个浮点数
- Z 是零点偏移(zero point),一个整数
- round 是取整操作
反过来,从整数恢复成浮点数:
r ≈ (q - Z) × S
这里有个细节要注意——取整操作会引入误差。我在项目中遇到过,有些层对量化误差特别敏感,比如那些激活值分布很广的层。嗯,这时候就得单独处理。
我的经验:量化误差的大小,取决于原始数据的分布和量化位宽。INT8通常能保留大部分信息,INT4就得小心了。
对称量化与非对称量化
这两种量化方式,区别就在于零点 Z 怎么处理。
对称量化
对称量化要求零点 Z = 0。也就是说,浮点数的0,映射到整数的0。公式简化成:
q = round(r / S)
这样做的好处是计算简单,硬件实现也方便。但有个问题——如果原始数据的分布不是对称的(比如ReLU的输出全是非负数),那量化范围就浪费了一半。
我记得有一次部署一个卷积网络,激活值全是正数,用对称量化后精度掉得厉害。后来换成非对称量化,效果立马好了不少。
非对称量化
非对称量化允许 Z 不为0。这样就能灵活地适配各种数据分布。公式就是前面那个:
q = round(r / S + Z)
举个例子:假设原始数据范围是 [0.0, 6.0],量化到 [0, 255]:
S = (6.0 - 0.0) / (255 - 0) = 0.02353
Z = 0
你看,这里 Z 恰好是0,但如果是 [-3.0, 3.0] 这种对称分布,Z 就是128左右。
| 特性 | 对称量化 | 非对称量化 |
|---|---|---|
| 零点 Z | 固定为0 | 可调节 |
| 计算复杂度 | 低 | 稍高 |
| 适用场景 | 权重、对称分布数据 | 激活值、非对称分布数据 |
| 精度损失 | 对称数据小,非对称数据大 | 整体更优 |
注意:非对称量化虽然灵活,但硬件支持度不如对称量化。选型前一定要确认目标芯片的指令集。
量化感知训练
量化感知训练(Quantization-Aware Training,QAT),说白了就是在训练过程中“模拟”量化效果。让模型提前适应量化带来的误差。
为什么需要这个?因为直接训练完再量化(Post-Training Quantization,PTQ),有时候精度掉得让人心疼。QAT 的做法是:
- 在前向传播时,插入伪量化节点(fake quantization)
- 这些节点模拟量化和反量化的过程
- 反向传播时,用直通估计器(STE)处理梯度
我刚开始接触QAT时,觉得这玩意儿挺玄乎的。后来自己动手跑了一遍,发现核心就两点:
- 前向:假装量化了,实际还是浮点运算
- 反向:假装梯度能直接通过量化节点
代码实现上,PyTorch 提供了现成的 API:
import torch
import torch.quantization as quant
# 定义模型
model = MyModel()
# 开启量化感知训练
model.qconfig = quant.get_default_qat_qconfig('fbgemm')
model = quant.prepare_qat(model, inplace=True)
# 正常训练
for data, target in dataloader:
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
# 训练完成后,转换为量化模型
model = quant.convert(model, inplace=True)
这里有个坑——QAT 训练时,学习率要调小一点。我曾经用默认学习率跑QAT,结果模型直接不收敛了。后来改成原来的十分之一,效果才正常。
避坑指南:QAT 训练时间通常是普通训练的1.5到2倍。如果时间紧张,可以先试试PTQ,精度不够再上QAT。
三种量化方法的对比
我整理了一张表,方便你对比:
| 方法 | 精度 | 部署难度 | 适用场景 |
|---|---|---|---|
| 对称量化(PTQ) | 中等 | 低 | 权重量化、对称分布数据 |
| 非对称量化(PTQ) | 较高 | 中 | 激活值量化、非对称分布数据 |
| 量化感知训练(QAT) | 最高 | 高 | 精度敏感场景、小模型 |
我个人习惯是:先跑一遍PTQ对称量化,看看精度。如果掉得厉害,换成非对称。还不行,再上QAT。这样能省不少时间。
核心知识体系
下面这张图,是我自己总结的量化知识框架。你看一眼,心里就有数了:
这张图把量化分成三个层次:底层是数学原理,中间是两种量化策略和QAT,顶层是实践中的注意事项。你顺着这个结构学,思路会清晰很多。
好了,量化基础就聊到这儿。记住一句话:量化不是银弹,但用好了,能解决大部分资源受限场景下的部署问题。
公众号:蓝海资料掘金营,微信deep3321