4. 模型量化进阶(INT4/混合精度)

量化这件事,说白了就是用更少的比特去表示一个数。FP32 是 32 位,INT8 是 8 位,INT4 只有 4 位。你想想看,数据量直接砍到八分之一,内存带宽压力骤减,功耗自然就下来了。

但事情没那么简单。INT4 带来的红利很诱人,挑战也相当棘手。我在项目中踩过的坑,今天一并倒给你们。

4.1 INT4 量化的功耗红利

先说说好处。INT4 量化最直接的红利,就是内存访问量大幅降低。大模型推理时,内存搬运是功耗大头。数据量减半(相比 INT8)甚至减到四分之一(相比 FP16),功耗自然跟着降。

我做过一个实测对比:

精度 模型大小 单次推理功耗 吞吐量
FP16 13.5 GB 285 W 45 req/s
INT8 6.8 GB 172 W 82 req/s
INT4 3.4 GB 98 W 156 req/s

看到没?INT4 的功耗只有 FP16 的三分之一,吞吐量却翻了三倍多。这个账,算下来很划算。

核心结论:INT4 量化的功耗红利主要来自两点——内存带宽节省和计算单元利用率提升。数据量小了,cache 命中率也上去了,这是个连锁反应。

4.2 精度损失:绕不开的坎

红利背后是代价。INT4 只有 16 个离散值,表达能力极其有限。模型参数从 FP32 压缩到 INT4,信息损失是必然的。

我在项目中遇到过一个问题:某个对话模型用 INT8 量化后,BLEU 只掉了 0.3 个点,大家都很满意。但换成 INT4 后,BLEU 直接掉了 2.1 个点。用户反馈说「回答变傻了」。嗯,这确实是个问题。

为什么会这样?

因为 INT4 的量化粒度太粗。对于权重分布比较均匀的层,影响还小。但对于那些 outlier(离群值)较多的层,比如 attention 的 QKV 投影层,INT4 几乎无法保留有效信息。

注意:不是所有模型都适合 INT4 量化。如果你的模型对精度极其敏感(比如医疗、金融场景),建议先做 INT8,再考虑 INT4。我曾经在一个法律文本摘要项目上硬上 INT4,结果摘要质量惨不忍睹,最后老老实实换回了 INT8。

4.3 混合精度推理策略

既然全盘 INT4 有风险,那我们就搞混合精度。说白了,就是敏感层用高精度,不敏感层用低精度。

我个人的习惯是这样分的:

  • Attention 层:用 INT8 或 FP16。这些层对精度敏感,尤其是 softmax 之前的计算。
  • FFN 层:用 INT4。这些层参数多,权重分布相对均匀,量化损失小。
  • Embedding 层:用 FP16。词向量维度高,量化后容易丢失语义信息。
  • LayerNorm 和激活函数:保持 FP16 或 FP32。这些操作对数值范围敏感。

举个例子,一个 7B 模型的混合精度配置:

# 混合精度配置示例
quant_config = {
    "self_attn.q_proj": "int8",
    "self_attn.k_proj": "int8",
    "self_attn.v_proj": "int8",
    "self_attn.o_proj": "int8",
    "mlp.gate_proj": "int4",
    "mlp.up_proj": "int4",
    "mlp.down_proj": "int4",
    "embed_tokens": "fp16",
    "norm": "fp16"
}

这样配置下来,模型大小从 13.5 GB 降到了 5.2 GB,精度损失控制在 0.5 个点以内。功耗嘛,大概在 120 W 左右,比全 INT4 高一点,但比 FP16 低很多。

小技巧:如何判断哪些层对量化敏感?我的做法是逐层做敏感性分析。把每一层单独量化,跑一遍验证集,看精度变化。变化大的层就保留高精度。这个分析跑一次大概需要几个小时,但值得做。

4.4 我在项目中踩过的坑

坑一:校准数据集选错

我曾经在一个代码生成模型上做 INT4 量化,用了通用文本做校准集。结果量化后的模型在代码任务上表现极差。后来换成代码语料做校准,效果才正常。校准数据集一定要和你的使用场景匹配,这个不能偷懒。

坑二:动态范围没处理好

INT4 的量化范围是 [-8, 7],非常窄。如果权重分布有长尾,很多值会被截断。我建议用 per-channel 量化,而不是 per-tensor。per-channel 虽然计算量稍大,但精度好很多。

坑三:推理框架的 INT4 支持不成熟

去年我在某个框架上做 INT4 推理,发现它的 INT4 内核实现有 bug,导致推理结果错误。排查了两天才找到原因。所以,用之前一定要做精度对齐验证——把量化模型的输出和原始模型的输出逐层对比。

坑四:忽略反量化开销

INT4 计算时,需要先反量化到 FP16 或 INT8,再做运算。这个反量化操作本身也有功耗和延迟。如果你的模型层数不多,反量化开销可能抵消掉 INT4 带来的收益。我建议在部署前做一次端到端的性能 profiling。

4.5 知识体系总览

下面这张图,是我对 INT4 量化和混合精度推理的总结。你可以把它当作一个决策流程图:

INT4 量化与混合精度推理决策流程 模型量化决策 精度要求高? (BLEU损失 < 0.5) 混合精度推理 Attention: INT8 FFN: INT4 全 INT4 量化 最大功耗节省 校准数据集选择 必须匹配使用场景 量化方式选择 per-channel vs per-tensor 精度对齐验证 逐层对比输出 通过 部署上线 性能 profiling 不通过 回退调整 换校准集/调量化参数 注:实际项目中可能需要多次迭代才能找到最优配置

这张图的核心逻辑是:先判断精度要求,再选量化策略,然后做校准和验证。每一步都有坑,每一步都要小心。

4.6 一些实战建议

最后,给几个我自己的经验:

  1. 先做 INT8,再做 INT4。 如果 INT8 精度损失已经很大,INT4 基本不用试。
  2. 校准集大小要适中。 我一般用 1000-5000 条数据。太少校准不准,太多浪费时间。
  3. 关注推理框架的更新。 INT4 的支持还在快速迭代中,新版本往往有更好的内核实现。
  4. 不要迷信理论收益。 实际部署时,内存带宽、计算单元利用率、框架开销都会影响最终效果。一定要做端到端测试。

一句话总结:INT4 量化是降低大模型推理功耗的利器,但要用好它,需要你对模型结构、量化原理和部署框架都有深入理解。混合精度是更稳妥的选择,值得优先考虑。

专注资料整理