4、模型量化(Quantization)基础:FP32、FP16、INT8、INT4数据格式,对称量化与非对称量化,量化误差的来源分析

4.1 为什么我们需要量化?

先问大家一个问题:一个训练好的模型,动辄几百兆甚至几个G,怎么塞进只有几十兆内存的嵌入式设备里?

答案就是量化。

量化说白了,就是把模型里那些高精度的浮点数(比如FP32),用低精度的整数(比如INT8)来表示。我刚开始接触这个领域时,总觉得这像是在「压缩饼干」——把信息挤掉一部分,但还能吃。后来发现,其实量化做得好的话,模型精度损失可以控制在1%以内,甚至完全无损。

我个人习惯把量化比作「数字世界的降维打击」。你想想看,一个FP32的数值占4个字节,换成INT8只占1个字节,模型体积直接缩到四分之一。推理速度呢?INT8的矩阵乘法在专用硬件上可以比FP32快2-4倍。这买卖,划算。

4.2 常见的数据格式:FP32、FP16、INT8、INT4

先看看这些数据格式到底长什么样。我整理了一张表,方便大家对比:

格式 位宽 表示范围 精度 典型应用场景
FP32 32位 ±3.4×10³⁸ 约7位有效数字 训练、高精度推理
FP16 16位 ±6.5×10⁴ 约3位有效数字 混合精度训练、移动端推理
INT8 8位 -128~127 或 0~255 整数精度 边缘端部署、加速推理
INT4 4位 -8~7 或 0~15 整数精度 极致压缩、低功耗场景

这里有个坑,我得提醒大家。FP16的表示范围其实很有限,只有±6.5×10⁴。我在项目中遇到过,某个模型的权重值超过了这个范围,结果FP16直接溢出,推理结果全乱套了。所以做混合精度训练时,一定要检查权重分布,必要时用FP32做梯度累加。

4.3 对称量化与非对称量化

量化方式主要分两种:对称量化和非对称量化。这两种方式,说白了就是「怎么把浮点数映射到整数」的问题。

4.3.1 对称量化

对称量化的核心思想是:浮点数的0,映射到整数的0。映射关系是线性的,公式很简单:

Q = round( x / S )

其中S是缩放因子(scale),x是浮点数值,Q是量化后的整数值。

对称量化的好处是计算简单,硬件实现方便。但缺点也很明显——如果浮点数的分布不对称(比如ReLU后的激活值全是正数),那负半轴的量化区间就浪费了。

关键点:对称量化适合权重分布接近0对称的场景,比如卷积层的权重。

4.3.2 非对称量化

非对称量化引入了零点(zero point)的概念,公式变成:

Q = round( x / S ) + Z

其中Z是零点偏移。这样一来,浮点数的0可以映射到任意整数,不再强制为0。

非对称量化能更好地利用整数的表示范围。举个例子,如果激活值全在0到1之间,对称量化只能用到INT8正半轴的127个值,而非对称量化可以用满256个值。精度自然更高。

我的经验:对于激活值,我一般优先用非对称量化。对于权重,对称量化就够了。这个选择我在多个项目里验证过,效果稳定。

4.4 量化误差的来源分析

量化一定会引入误差,这是逃不掉的。但我们可以搞清楚误差从哪来,然后想办法减小它。

误差主要来自三个方面:

  1. 截断误差(Clipping Error):当浮点数值超出量化范围时,会被强行截断。比如INT8的范围是-128~127,如果某个权重是200,量化后只能变成127。这部分信息就丢了。
  2. 舍入误差(Rounding Error):量化时需要对浮点数做四舍五入。比如3.14量化成整数3,0.14的精度就没了。这种误差虽然小,但累积起来也会影响最终结果。
  3. 量化粒度误差:我们通常对整个张量或通道使用同一个缩放因子。如果张量内部数值分布不均匀,那量化效果就会打折扣。比如某个通道的权重范围是-1到1,另一个通道是-100到100,共用同一个缩放因子的话,小范围的通道精度会严重受损。

避坑指南:我曾经在一个语音识别模型上踩过这个坑。模型里有个层的权重分布特别不均匀,我用了per-tensor量化,结果精度掉了5%。后来改成per-channel量化,精度损失降到了0.3%。所以,遇到精度损失大的情况,先检查量化粒度。

4.5 量化流程与核心逻辑

下面这张图是我自己画的,展示了量化的核心流程。从浮点模型到量化模型,中间需要经过校准、计算缩放因子、量化权重和激活值等步骤。

模型量化核心流程 FP32浮点模型 权重+激活值 校准数据集 统计数值分布 计算S和Z 缩放因子+零点 INT8量化模型 推理加速 量化方式选择 对称量化 Q = round(x / S) 适合:权重层 非对称量化 Q = round(x / S) + Z 适合:激活值层 量化误差来源 截断误差 舍入误差 量化粒度误差

这张图把量化流程串起来了。从FP32模型开始,用校准数据集统计数值分布,然后计算缩放因子S和零点Z,最后生成量化模型。下方还列出了量化方式的选择建议和误差来源,方便大家对照。

4.6 实战中的量化策略选择

说了这么多理论,到底怎么选?我给大家一个实用的决策思路:

  • 权重量化:优先用对称量化 + per-channel粒度。权重分布通常比较对称,而且不同通道差异大,per-channel能保留更多信息。
  • 激活值量化:优先用非对称量化 + per-tensor粒度。激活值经过ReLU后全是正数,非对称量化能充分利用整数范围。per-tensor虽然粗一点,但激活值分布相对稳定,够用了。
  • INT4量化:除非对模型体积有极致要求,否则慎用。INT4的表示范围太小,精度损失往往难以接受。我一般只在语音唤醒这类简单任务上用INT4。

一个小技巧:量化后一定要做精度验证。我习惯用验证集跑一遍,对比量化前后的精度差异。如果精度损失超过1%,我会先检查是不是校准数据集选得不对,或者量化粒度太粗。很多时候,换个校准数据集就能解决问题。

好了,这一章的内容就到这里。量化是个实践性很强的话题,光看理论是不够的。建议大家找个模型动手试试,踩踩坑,才能真正理解这些概念。

专注资料整理