模型量化基础:从数学原理到工程落地

量化,说白了就是把模型从高精度“压缩”到低精度。你想想看,一个 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 的完整量化流程:

量化流程框架图 FP32 模型 校准集统计分布 计算 scale 和 zero-point 执行量化映射 INT8 模型 关键步骤 1. 收集校准数据 2. 统计 min/max 3. 计算量化参数 注意事项 校准集要覆盖 真实推理分布 避免 outlier 干扰

量化误差的来源

量化不是无损的。误差主要来自三个方面:

  • 截断误差:超出量化范围的数值被截断。比如 INT8 只能表示 -128 到 127,超出部分直接丢掉。
  • 舍入误差:浮点数映射到整数时,小数部分被舍入。这个误差一般很小,但累积起来会放大。
  • 精度损失:低精度无法表示高精度的细微差异。FP32 有 23 位尾数,INT8 只有 8 位,信息量差了 3 个数量级。

我建议在量化后做一次精度验证。如果精度下降超过 1%,就要考虑调整量化策略,比如改用混合精度或者做量化感知训练。

小技巧:用 KL 散度评估量化前后的分布差异。如果 KL 散度太大,说明量化参数选得不对。

总结

量化是模型压缩的基石。理解对称/非对称量化、scale/zero-point 的计算、以及不同精度的取舍,是后续学习量化感知训练、混合精度部署的前提。我个人觉得,量化最难的不是数学,而是工程调优。同样的模型,不同的校准集、不同的量化策略,结果可能天差地别。多动手、多踩坑,慢慢就熟了。