近年来,随着 Transformer、MOE 架构的提出,深度学习模型轻松突破上万亿规模参数,导致模型体积庞大。为了降低部署成本并提升推理性能,我们需要采用大模型压缩技术。模型压缩主要分为剪枝(Pruning)、知识蒸馏(Knowledge Distillation)和量化三类。
本系列将针对大模型的一些常见训练后量化方案(GPTQ、LLM.int8()、SmoothQuant、AWQ 等)进行讲述,本文主要针对 LLM.int8() 与 GPTQ 进行深入解析。
大模型量化的对象
大模型量化的对象主要包括权重、激活、KV Cache、梯度及优化器等。由于梯度量化和优化器量化主要用于训练场景以减少反向传播的计算和通信开销,本系列仅讨论权重、激活、KV Cache 量化方案。
- 仅权重量化:如 W4A16、AWQ 及 GPTQ 中的 W4A16,W8A16(权重量化为 INT8,激活仍为 BF16 或 FP16)。
- 权重、激活量化:如 SmoothQuant 中的 W8A8。
- KV Cache 量化:INT8/INT4/FP8。LLM 推理时,为了避免冗余计算设计了 KV Cache 缓存机制,本质是空间换时间。对于支持长文本长度的 LLM,KV Cache 显存占用极高,因此 KV Cache 量化非常有必要。
LLM.int8()
背景
作者发现激活中存在一些离群值,其绝对值明显更大;且这些离群值分布在少量的几个特征中,称为离群特征 (Emergent Features)。以激活 X∈R[T×h] 和权重 W∈R[h×h0] 的矩阵相乘为例,特征维度指 h 这个维度。无论是 per-token(针对激活 x:每行对应一个量化系数)还是 per-channel(针对权重 w:每列对应一个量化系数)量化,都会受到这些离群值的很大影响。既然只有少量特征包含离群值,LLM.int8() 的思路是把这些特征拿出来单独计算,只对剩余特征做量化。
技术原理
LLM.int8()(论文:LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale)是一种采用混合精度分解的量化方法。该方案先做了一个矩阵分解,对绝大部分权重和激活用 8bit 量化(vector-wise)。对离群特征的几个维度保留 16bit,对其做高精度的矩阵乘法。

LLM.int8() 通过三个步骤完成矩阵乘法计算:
- 从输入的隐含状态中,按列提取异常值 (离群特征,即大于某个阈值的值)。
- 对离群特征进行 FP16 矩阵运算,对非离群特征进行量化,做 INT8 矩阵运算;
- 反量化非离群值的矩阵乘结果,并与离群值矩阵乘结果相加,获得最终的 FP16 结果。
实验结果表明该方法效果良好。可以通过使用 LLM.int8() 的量化过程来恢复全部性能。您可以清楚地看到随着模型参数量逐渐变多 8 比特基线(即 vector-wise quantization)的性能大幅下降。而 LLM.int8() 方法使用vector-wise quantization和混合精度分解来恢复全部性能。

虽然 LLM.int8() 带来的性能下降微乎其微,但是这种分离计算的方式拖慢了推理速度。对于 BLOOM-176B,相比于 FP16,LLM.int8() 慢了大约 15% 到 23%;对于更小的模型(3B 和 11B),速度差距更为明显,LLM.int8() 慢了三倍以上。
此外,论文中测量了异常值特征对于注意力和预测性能的影响。下图展示了 Transformer 中受模型大小或 C4 困惑度影响的大量异常值特征的层和所有序列维度的百分比。
从图中可知,当通过参数数量进行测量时,Transformer 所有层上的大幅异常值特征突然出现在 6B 和 6.7B 参数之间。受影响层的百分比从 65% 增加到 100%,受影响的序列维度数量从 35% 迅速增加到 75%。这种突然的转移与量化开始失败的点同时发生。





