量化基础:从FP32到INT4,精度是如何一步步被“压缩”的?

聊到大模型推理,有个话题绕不开——量化。

说白了,就是把模型里那些又大又沉的FP32参数,换成更轻量的INT8、INT4。你想想看,一个70B的模型,FP32要280GB显存,换成INT4直接降到70GB。这诱惑力,谁能顶得住?

但问题来了:精度是怎么被“压缩”的?代价又是什么?

这一讲,我就带你从底层拆解这件事。

1. 浮点数的“奢侈”生活

先看FP32。一个32位浮点数,由1位符号位、8位指数位、23位尾数位组成。

它能表示的范围大约是 ±1.18×10⁻³⁸ 到 ±3.4×10³⁸。精度呢?大约7位有效数字。

这很奢侈。你想想,模型里几万亿个参数,每个都占4字节。我当年第一次跑LLaMA-65B时,光加载权重就花了260GB显存,差点把A100集群干趴下。

核心矛盾:FP32精度高,但存储和计算开销太大。推理时,我们真的需要那么高的精度吗?

2. 量化的本质:映射与截断

量化,本质上是一个映射函数:

Q(x) = round(x / scale) + zero_point

其中:

  • scale:缩放因子,决定每个量化步长代表多少浮点值
  • zero_point:零点偏移,让浮点0能精确映射到某个整数值

反量化就是逆过程:

x_hat = (Q(x) - zero_point) × scale

嗯,这里要注意:round操作会引入误差。这个误差,就是精度损失的根源。

举个例子。假设原始权重范围是[-1.0, 1.0],要量化到INT8(-128到127):

scale = (1.0 - (-1.0)) / (127 - (-128)) = 2.0 / 255 ≈ 0.00784
zero_point = round(-(-1.0) / 0.00784) + (-128) = round(127.55) - 128 = 0

你看,原本连续的浮点值,现在只能取256个离散值。每个值之间的差距约0.00784。这就是量化步长。

个人经验:我习惯先看权重的分布。如果分布很均匀,量化误差就小。如果分布有长尾,那就要小心了——那些离群点会被严重截断。

3. 从FP32到INT8:对称 vs 非对称

INT8量化有两种主流方式:

类型 zero_point 适用场景 精度损失
对称量化 固定为0 权重分布对称(如经过LayerNorm后的值) 较小
非对称量化 可调 激活值分布不对称(如ReLU后的正值) 更小

对称量化实现简单,但遇到ReLU后的激活值(全是正数)就浪费了一半的表示范围。非对称量化通过调整zero_point,能把整个量化范围“对准”数据的实际分布。

我在项目中遇到过一个问题:用对称量化量化BERT的激活值,精度掉了2个点。换成非对称量化后,只掉了0.3个点。差别就在这里。

4. INT4:更激进的压缩

INT4只有16个取值(-8到7)。相比INT8的256个,信息量少了16倍。

这带来的问题是:量化步长变大,误差急剧增加。

举个例子,同样范围[-1.0, 1.0]:

INT8步长:0.00784
INT4步长:2.0 / 15 ≈ 0.1333

INT4的步长是INT8的17倍。这意味着每个量化值代表的浮点范围更大,精度损失更严重。

避坑指南:我曾经在量化一个代码生成模型时,直接用了INT4,结果生成的代码全是语法错误。后来发现是注意力层的softmax输出被严重截断。解决方案:对敏感层保留INT8,其他层用INT4。这叫混合精度量化。

5. 量化误差的传播

量化误差不是孤立的。它会随着网络层逐层传播。

你想想看:第一层量化误差1%,经过100层后,误差可能累积到10%甚至更高。这就是为什么有些模型量化后直接“崩了”。

我总结了几种常见的误差来源:

  • 截断误差:超出量化范围的值被强行截断
  • 舍入误差:round操作导致的精度丢失
  • 零点漂移:zero_point计算不准确导致的系统性偏差

怎么缓解?

  • 使用校准数据集,统计真实的激活值分布
  • 采用逐通道量化(per-channel),每个通道独立计算scale和zero_point
  • 离群点做特殊处理,比如用FP16存储那些极端值

6. 一张图看懂量化流程

下面这张SVG图,展示了从FP32到INT4的完整量化流程:

量化流程:从FP32到INT4 FP32 权重 32位浮点 统计分布 校准数据集 计算scale/zero_point 映射 INT8 量化 256个离散值 进一步压缩 INT4 量化 16个离散值 量化误差分析 截断误差 超出范围的值被截断 舍入误差 round操作导致精度丢失 零点漂移 系统性偏差累积 缓解措施:逐通道量化 | 混合精度 | 离群点处理

7. 实战建议:怎么选量化精度?

没有银弹。选哪种量化,取决于你的场景:

  • INT8:大多数场景的首选。精度损失通常在1%以内,速度提升2-4倍。我建议从INT8开始尝试。
  • INT4:适合对精度要求不高的场景,或者模型本身很大(如70B+)。精度损失可能到3-5%。
  • 混合精度:敏感层(如注意力、输出层)用INT8,其他层用INT4。这是目前工业界的主流做法。

我的习惯:先跑一遍校准数据集,看看每层的激活值分布。如果某层的分布范围特别宽(比如超过±10),我会单独处理这层,或者保留FP16。

量化不是玄学,是工程。理解每一步的误差来源,你就能在精度和速度之间找到那个平衡点。


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