模型量化基础:量化的数学原理、对称量化与非对称量化、量化感知训练

说到模型量化,我脑子里第一个蹦出来的场景是——几年前在某个边缘设备上部署一个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 的做法是:

  1. 在前向传播时,插入伪量化节点(fake quantization)
  2. 这些节点模拟量化和反量化的过程
  3. 反向传播时,用直通估计器(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。这样能省不少时间。

核心知识体系

下面这张图,是我自己总结的量化知识框架。你看一眼,心里就有数了:

模型量化知识体系 量化数学原理 对称 vs 非对称 量化感知训练 缩放因子 S 零点偏移 Z 取整操作 round 对称:Z=0 非对称:Z可调 计算复杂度差异 伪量化节点 直通估计器 STE 微调训练 先PTQ,不行再QAT 关注敏感层 非对称更灵活 硬件支持要确认 学习率调小 训练时间翻倍

这张图把量化分成三个层次:底层是数学原理,中间是两种量化策略和QAT,顶层是实践中的注意事项。你顺着这个结构学,思路会清晰很多。

好了,量化基础就聊到这儿。记住一句话:量化不是银弹,但用好了,能解决大部分资源受限场景下的部署问题。


公众号:蓝海资料掘金营,微信deep3321