十九:模型压缩:量化、ZeroQuant、LLM.int8() 与 SmoothQuant¶
来源:http://mp.weixin.qq.com/s?__biz=MzYyNTk3Njg1NA==&mid=2247484148&idx=1&sn=ca39ffcd2215dfd05a405e1d42dc5aac&chksm=f01eb18dc769389b47cab9551b217ead7a649e816398b0acfe4444e9022f0231c6cc2f528ed3#rd
1. 学习定位¶
模型压缩的目标是降低模型部署成本,包括显存、内存、带宽、延迟、吞吐和能耗。量化是最常见、最实用的模型压缩方法之一。它把 FP16/BF16/FP32 等高精度数值映射到 INT8/INT4/NF4/FP8 等低精度表示,从而减少存储和计算开销。 第十九天聚焦 8-bit 和 W8A8 量化路线:
量化基础
-> PTQ / QAT
-> per-tensor / per-channel / per-token / per-group
-> weight-only / weight+activation
-> ZeroQuant
-> LLM.int8()
-> SmoothQuant
-> NF4 与 QLoRA 回顾
-> 部署和排错
2. 模型压缩方法版图¶
模型压缩常见方法: - 量化:降低数值精度,例如 FP16 到 INT8/INT4。
-
剪枝:删除权重、通道、attention head、MLP 神经元或层。
-
知识蒸馏:让小模型学习大模型输出或中间表示。
-
低秩分解:用低秩矩阵近似大矩阵。
-
权重共享和编码:减少参数存储冗余。
-
高效结构设计:直接训练小模型、稀疏模型或 MoE 模型。
量化的优势是部署收益直接、通常不需要重新训练完整模型,也是大模型推理落地最常用的压缩手段。
3. 量化的基本公式¶
线性均匀量化通常把实数 x 映射到整数 q:
反量化:
其中:
- scale 控制实数和整数之间的比例。
-
zero_point表示实数 0 对应的整数位置。 -
q_min/q_max由 bit 数决定,例如 int8 通常范围是[-128,127]或[0,255]。
对称量化:
非对称量化: 非对称量化更适合分布不以 0 为中心的数据(如某些图像输入、ReLU 输出),但实现和 kernel 可能更复杂。4. 量化粒度¶
量化粒度决定 scale 的共享范围。 同一个 scale/zero_point 管多大范围的数据,就是什么粒度。 粒度越细 → 精度越高 → 但存储 / 计算开销越大。 Per-tensor(最粗粒度):
优点是实现简单、计算开销小,缺点是对 outlier(异常值) 敏感【只要有一个很大的值,整个tensor精度都会变得很差】。 Per-channel(最常用、精度最好): 常用于权重量化(CNN、Transformer权重都用这个),精度更好。 Per-token(Transformer 专用): 适合激活动态范围随 token 变化明显的场景。适用于Transformer的激活值(activation)优点是不同 token 数值范围差异巨大,per-token 能极大提升精度,缺点则是在推理时需要动态计算scale。 Per-group(4-bit 量化标配): 常用于 4-bit weight-only quantization,在精度和元数据开销之间折中。缺点是实现复杂。 粒度 共享范围 直观特点 Per-tensor 整个张量 1 个 scale 最简单,怕异常值 Per-group 连续一组元素 1 个 scale 精度 & 开销折中,4-bit 常用 Per-channel 单个通道 1 个 scale 权重标配,精度高 Per-token 单个 token1 个 scale Transformer 激活专用 划分范围越小(粒度越细),scale 越贴合局部数据,量化精度就越高,但需要存储更多 scale,开销也越大。5. PTQ 与 QAT¶
PTQ(Post-Training Quantization):训练后量化
QAT(Quantization-Aware Training):感知量化训练 大模型场景中,PTQ 更常见,因为从头或全量 QAT 成本太高。ZeroQuant、LLM.int8()、SmoothQuant、GPTQ、AWQ 都属于重要 PTQ 路线。6. Weight-only 与 W8A8¶
Weight-only quantization:只量化权重
优点是实现相对简单,能显著降低权重显存和内存带宽。缺点是 activation 和 GEMM 计算未必完全 INT8。 W8A8:(权重 + 激活 都量化) 优点是更容易获得 INT8 GEMM 加速。难点是 activation outlier 很强,激活量化比权重量化更困难。 LLM.int8() 是 mixed-precision INT8 路线;SmoothQuant 目标是让 LLM 也能做高效 W8A8。7. Activation Outlier¶
大模型中 activation 常出现 outlier,即某些 hidden dimensions 的数值远大于其他维度。LLM.int8() 论文指出,随着模型规模增大,会出现大幅 outlier features,naive INT8 量化很容易被这些 outlier 破坏。 问题直觉:
结果是小值信息损失严重,模型性能下降。8. ZeroQuant¶
ZeroQuant 是微软 DeepSpeed 提出的面向大 Transformer 的「低成本、高精度、端到端 PTQ 量化方案」。它包含三类核心设计:
1. Fine-grained hardware-friendly quantization(细粒度、硬件友好量化) 就是选对量化粒度,同时让GPU跑得快
权重分组量化、激活值token-wise
2. Layer-by-layer Knowledge Distillation, LKD(LKD,逐层知识蒸馏) 这是 ZeroQuant 最关键、最聪明的地方。
直接把整个模型量化 → 误差逐层累积,最后层烂掉。
LKD 做法(逐层 “校准 + 微调”):将原始FP16模型作为Teacher,将量化模型作为Student,然后一次只处理一层,先将Teacher这一层的输入喂给Student的对应层,让Student量化层的输出尽量逼近Teacher的输出,只微调这一层的量化参数(很少几步),之后固定这一层,继续对下一层进行微调。
3. Optimized backend to reduce quant/dequant overhead(优化后端,减少量化 / 反量化开销)量化不是只算公式,真正部署时 quant/dequant 很耗时间。ZeroQuant把量化 / 反量化和前后算子融合(fusion),专门为 GPU(Ampere 等)写高效 kernel,让量化开销几乎消失 → 加速比接近理论值。
9. LLM.int8() 的核心问题¶
LLM.int8() 关注大规模 Transformer 的 INT8 矩阵乘。它观察到: - 大模型 activation 中存在 emergent outlier features。
-
naive vector quantization 在模型规模变大后会明显失效。
-
outlier 维度数量很少,但影响很大。
LLM.int8() 的目标是:
10. LLM.int8() 的 Mixed-precision Decomposition¶
LLM.int8() 的核心是混合精度分解:
normal dimensions:
int8 matrix multiplication
outlier dimensions:
fp16 matrix multiplication
其中:
- normal 部分占绝大多数,用 INT8 加速。
outlier部分很少,用 FP16 保精度。
这样既保留了 INT8 的效率,又避免 outlier 被粗暴量化。
11. LLM.int8() 的 Vector-wise Quantization向量级量化¶
LLM.int8() 使用 vector-wise quantization。矩阵乘中,对不同向量使用独立归一化 scale,减少不同通道动态范围差异带来的误差。 Vector-wise:矩阵中每一行 / 每一列向量,单独计算专属 scale,相比起Per-tensor来说粒度更细。 直觉:
这比 per-tensor 量化更精细,也更适合 Transformer 中的矩阵乘。 LLM.int8() 常用于推理加载,例如 bitsandbytes 的load_in_8bit=True 路线。
12. SmoothQuant 的核心思想¶
SmoothQuant 目标是让 LLM 做准确高效的 W8A8 PTQ。它的关键观察是:
SmoothQuant 使用数学等价变换,把 activation 的量化难点迁移到 weight:把激活(X)上的极端大值,按比例分摊转移到权重(W)上,操作后:激活的数值范围被拉平,outlier 被削弱,适合 INT8 量化;权重原本分布均匀,分担部分极值后,依然可以稳定做 INT8 量化。
通过选择 smoothing scale s:
- activation 被缩小,outlier 变平滑。
- weight 被相应放大,承担更多量化难度。
由于 weight 通常更容易量化,这种迁移能提升 W8A8 精度。
13. SmoothQuant 的 Alpha¶
SmoothQuant 中常用参数 alpha 控制平滑程度:
直觉:α 决定「量化压力」在激活和权重之间如何分配。
- alpha 越大,更多量化难度从 activation 迁移到 weight。
alpha越小,对 activation 平滑较弱。
alpha 需要通过校准数据或经验选择。不同模型、不同层可能有不同最优值。
14. NF4 与 QLoRA 回顾¶
NF4 是 NormalFloat 4-bit,是 QLoRA 中常用的 4-bit 权重量化格式。它不是普通均匀 int4,而是针对近似正态分布权重设计非均匀 codebook。 QLoRA:
base model: 4-bit NF4 quantized and frozen
adapter: LoRA parameters trainable
compute: often bf16/fp16
-
数值稀疏区域(分布两端、极值):码点稀疏,节省比特
-
仅做权重量化,不处理激活
它和本日 INT8 推理量化的区别: - QLoRA 主要服务低显存微调。
-
LLM.int8()/SmoothQuant 主要服务推理部署。
-
NF4 是 4-bit 权重量化格式。
-
SmoothQuant 是 W8A8 激活/权重平滑方法。
方案 核心用途 量化对象 精度格式 核心目标 QLoRA + NF4 大模型微调 仅基座权重 权重 NF4 (4bit),计算 BF16/FP16 极致降低微调显存 LLM.int8() 推理部署 权重 + 激活 混合精度:大部分 INT8,异常维度 FP16 INT8 加速、兼容 outlier SmoothQuant 推理部署 权重 + 激活 W8A8 全 INT8 平滑激活异常值,实现全 INT8 全速推理
15. 校准数据¶
PTQ 通常需要 calibration data,用来估计 activation 范围、scale、smoothing 参数或 Hessian 近似。 校准数据要求: - 数量不一定很大。
-
分布应接近真实推理输入。
-
prompt 模板应和部署一致。
-
序列长度要覆盖真实场景。
-
多语言/代码/数学等场景要有代表性。
校准数据不匹配会导致量化 scale 不合适,部署精度下降。
16. 量化的部署收益与成本¶
量化收益: - 权重显存下降。
-
内存带宽压力下降。
-
KV 以外的模型加载更轻。
-
INT8/INT4 kernel 可提升吞吐。
-
更容易单卡部署大模型。
量化成本: - 精度损失。
-
scale/zero point 元数据开销。
-
quant/dequant overhead。
-
kernel 兼容性限制。
-
某些层需要保留高精度。
-
calibration 和评估成本。
量化不等于一定加速。如果硬件和 kernel 不支持低精度高效 GEMM,可能只省显存但不明显提速。
17. 工程排错¶
量化后常见问题: - 困惑度明显升高。
-
长文本生成重复或崩坏。
-
数学/代码能力下降。
-
某些语言或格式任务退化。
-
推理速度没有提升。
-
显存没有按理论比例下降。
排查顺序:
1. 检查量化粒度和 bit 数。
2. 检查 calibration 数据分布。
3. 检查哪些层被量化,哪些层保留高精度。
4. 检查 activation outlier。
5. 检查 kernel 是否真正走 int8/int4。
6. 检查 batch size、sequence length、KV cache 是否成为瓶颈。
7. 用任务指标而不只用 perplexity 评估。
18. LLM.int8()、ZeroQuant、SmoothQuant 对比¶
方法 核心定位 核心机制 适用场景 补充特点 ZeroQuant 端到端 PTQ + 工程优化 细粒度量化(权重分组 / 激活逐 Token)+ 逐层知识蒸馏 LKD + 算子后端优化 大规模 Transformer 全链路量化部署 权重 + 激活同时量化,误差逐层抑制,硬件友好,兼顾精度与部署 LLM.int8() 异常值感知 INT8 推理 混合精度分解:普通维度 INT8 矩阵乘,少数异常维度 FP16 计算;向量级量化 通用大模型 8bit 推理(bitsandbytes 主流方案) 不改动数值分布,靠拆分计算避 outlier,无法实现纯 W8A8 SmoothQuant W8A8 全 INT8 PTQ 平滑变换 + 系数α,把激活的数值压力迁移到权重,拉平激活分布 激活异常值突出,追求完整 INT8 GEMM 硬件加速 纯数值变换,可落地标准 W8A8,全链路 INT8 计算,推理速度最优 NF4/QLoRA 4bit 低显存微调 权重使用非均匀 NF4 量化并冻结,仅训练 LoRA 适配器,计算保持 BF16/FP16 大模型低成本微调、参数高效训练 主打训练 / 微调,非纯推理方案,几乎不用于线上推理加速
19. 面试表达框架¶
回答量化问题可以按四层:
定义:
用低 bit 表示权重/激活,降低存储和计算。
技术点:
scale、zero point、粒度、PTQ/QAT、weight-only/W8A8。
LLM 难点:
activation outlier、长尾分布、kernel、校准、误差累积。
方法:
LLM.int8 处理 outlier,SmoothQuant 平滑 activation,
ZeroQuant 用细粒度量化和逐层 KD。
20. 核心总结¶
第十九天需要掌握的最小闭环:
Quantization:
x -> q -> x_hat
scale and zero_point are core
Granularity:
per-tensor, per-channel, per-token, per-group
PTQ:
post-training, calibration-based
LLM challenge:
activation outliers
LLM.int8():
vector-wise int8 quantization
outlier dimensions in fp16
SmoothQuant:
migrate difficulty from activation to weight
Y = XW = (X S^-1)(S W)
ZeroQuant:
fine-grained quantization
layer-by-layer distillation
optimized backend
21. 参考资料¶
-
ZeroQuant 原论文:https://arxiv.org/abs/2206.01861
-
LLM.int8() 原论文:https://arxiv.org/abs/2208.07339
-
SmoothQuant 原论文:https://arxiv.org/abs/2211.10438
-
NF4 量化讲解:https://www.bilibili.com/video/BV15y411a7so/
-
Hugging Face bitsandbytes 量化文档:https://huggingface.co/docs/transformers/quantization/bitsandbytes
-
SmoothQuant GitHub:https://github.com/mit-han-lab/smoothquant
预览时标签不可点<div class="