模型量化基础:从数学原理到工程落地
量化,说白了就是把模型从高精度“压缩”到低精度。你想想看,一个 FP32 的模型跑在手机上,内存和功耗都扛不住。我最早接触量化是在做端侧部署的时候,那时候模型 200MB,手机根本跑不动。后来用了 INT8 量化,直接压到 50MB,速度还快了 3 倍。嗯,这就是量化的魅力。
量化的数学原理
量化的核心思路很简单:用更少的比特数去表示一个数值范围。FP32 有 32 个比特,INT8 只有 8 个。我们要把 FP32 的分布映射到 INT8 的离散空间里。这个映射关系,就是量化的数学本质。
我个人习惯把量化分成两类:对称量化和非对称量化。它们的区别在于零点(zero-point)怎么处理。
对称量化
对称量化,就是让量化后的数值关于 0 对称。也就是说,FP32 的 0 映射到 INT8 的 0。公式长这样:
q = round(r / scale)
scale = max(|r|) / (2^(n-1) - 1)
其中 r 是原始浮点数,q 是量化后的整数,scale 是缩放因子,n 是量化位数。对于 INT8,n=8,所以分母是 127。
我在项目中遇到过一个问题:当模型权重分布不对称时,对称量化会浪费很多量化区间。比如权重范围是 [-0.1, 1.0],对称量化会把范围拉到 [-1.0, 1.0],结果 [-1.0, -0.1] 这段全浪费了。这就是对称量化的局限性。
对称量化的特点:实现简单,计算效率高,但对非对称分布不友好。
非对称量化
非对称量化引入了零点(zero-point),让映射更灵活。公式是:
q = round(r / scale) + zero_point
scale = (r_max - r_min) / (q_max - q_min)
zero_point = round(q_min - r_min / scale)
你看,非对称量化可以自由调整映射的偏移量。这样即使权重分布不对称,也能充分利用量化区间。我建议在激活值量化时优先考虑非对称量化,因为激活值的分布往往不是对称的。
我的经验:权重量化用对称,激活量化用非对称。这是很多工业级部署方案的标配。
量化参数:scale 和 zero-point
量化参数就两个:scale 和 zero-point。它们决定了浮点数和整数之间的映射关系。
| 参数 | 含义 | 计算公式 |
|---|---|---|
| scale | 缩放因子,决定每个量化步长代表多少浮点数 | (r_max - r_min) / (q_max - q_min) |
| zero-point | 零点偏移,让浮点 0 映射到整数 0 附近 | round(q_min - r_min / scale) |
反量化公式也很简单:
r = (q - zero_point) * scale
我曾经踩过一个坑:计算 scale 时用了错误的统计量。比如用均值代替最大值,结果量化误差直接爆炸。记住,scale 依赖的是数值范围,不是分布中心。
避坑指南:计算 scale 时一定要用校准集(calibration dataset)的统计量,不要用训练集。校准集要覆盖模型推理时的真实分布。
量化精度:FP32, FP16, INT8, INT4
不同精度对应不同的比特数和表示范围。我整理了一张对比表:
| 精度 | 比特数 | 表示范围 | 典型应用场景 |
|---|---|---|---|
| FP32 | 32 | ±3.4×10^38 | 训练、高精度推理 |
| FP16 | 16 | ±6.5×10^4 | 混合精度训练、GPU 推理 |
| INT8 | 8 | -128 ~ 127 | 端侧部署、边缘计算 |
| INT4 | 4 | -8 ~ 7 | 极致压缩、低功耗设备 |
FP32 是基准精度,模型训练基本都用它。FP16 在混合精度训练中很常见,能省一半显存。INT8 是部署的主力,精度损失通常可以接受。INT4 就比较激进了,我一般只在模型很大、带宽很窄的场景下用。
你可能会问:INT4 精度够用吗?说实话,看模型。大模型(比如 7B 以上)对 INT4 的容忍度更高,小模型就容易崩。我做过一个实验:把 BERT-base 压到 INT4,准确率掉了 3 个点,但模型大小从 400MB 降到了 50MB。值不值?看业务需求。
量化流程框架图
下面这张图展示了从 FP32 到 INT8 的完整量化流程:
量化误差的来源
量化不是无损的。误差主要来自三个方面:
- 截断误差:超出量化范围的数值被截断。比如 INT8 只能表示 -128 到 127,超出部分直接丢掉。
- 舍入误差:浮点数映射到整数时,小数部分被舍入。这个误差一般很小,但累积起来会放大。
- 精度损失:低精度无法表示高精度的细微差异。FP32 有 23 位尾数,INT8 只有 8 位,信息量差了 3 个数量级。
我建议在量化后做一次精度验证。如果精度下降超过 1%,就要考虑调整量化策略,比如改用混合精度或者做量化感知训练。
小技巧:用 KL 散度评估量化前后的分布差异。如果 KL 散度太大,说明量化参数选得不对。
总结
量化是模型压缩的基石。理解对称/非对称量化、scale/zero-point 的计算、以及不同精度的取舍,是后续学习量化感知训练、混合精度部署的前提。我个人觉得,量化最难的不是数学,而是工程调优。同样的模型,不同的校准集、不同的量化策略,结果可能天差地别。多动手、多踩坑,慢慢就熟了。