一个70B参数的大语言模型,如果以FP16格式存储,需要140GB显存。NVIDIA A100只有80GB,H200也才141GB——这意味着推理一个70B模型,要么用多卡分布式,要么接受频繁的CPU-GPU数据交换。但2022年底开始,一种技术让同样大小的模型可以塞进消费级显卡:4位量化。
这不是魔法,而是深度学习领域二十年量化技术的集大成。从最早的INT8到如今的INT4甚至1.58-bit,每一次精度下降都伴随着精巧的数学技巧来"欺骗"模型的感知。
量化的数学本质:比特与精度的博弈
量化的核心问题只有一个:如何用更少的比特表示一个浮点数,同时让误差可控?
假设有一个FP16权重 $w = 1.234$,要量化到INT8。首先需要确定量化范围,找到权重的最大值 $w_{max}$ 和最小值 $w_{min}$。然后定义缩放因子:
$$s = \frac{w_{max} - w_{min}}{2^b - 1}$$其中 $b$ 是目标比特数。量化的核心操作是将浮点值映射到整数:
$$w_q = \text{round}\left(\frac{w - w_{min}}{s}\right)$$反量化时再映射回来:
$$w' = w_q \cdot s + w_{min}$$这个过程引入的误差是 $|w - w'|$。误差的大小取决于两个因素:量化的比特数 $b$,以及原始权重的分布范围。
表面上看,INT4比FP16减少了75%的存储空间。但更深层的意义在于内存带宽。LLM推理在自回归生成阶段是内存受限(memory-bound)的——每生成一个token,都需要从显存中读取全部参数进行计算。如果能用4bit表示权重,意味着同样的带宽可以传输2倍多的参数。
但这里有一个陷阱:简单的均匀量化在LLM上行不通。
为什么大模型不能直接量化
2022年,Tim Dettmers在论文《LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale》中揭示了一个令人惊讶的现象:Transformer模型中存在"涌现的异常特征"(emergent outlier features)。
在超过6B参数的模型中,特定特征维度的激活值会变得极其巨大——比其他维度大20-100倍。这些异常值不是随机出现的,而是集中在特定的通道上,贯穿整个序列长度。
这种分布给量化带来了致命挑战。假设激活值的范围是 [-100, 100],而99.9%的值都在 [-1, 1] 之间。如果使用min-max量化,整个INT8的256个离散值需要覆盖200的范围,分辨率约为0.78。那些在 [-1, 1] 之间的值只能使用大约2-3个离散级别表示——精度损失极其严重。
这就是为什么简单的量化方法在LLM上会导致灾难性的性能下降。解决方案必须回答一个核心问题:如何处理这些异常值?
GPTQ:逐层最优的权重量化
GPTQ(Accurate Post-Training Quantization for Generative Pre-trained Transformers)由Elias Frantar等人于2022年提出,是目前最主流的权重量化方法之一。
GPTQ的核心思想是逐层优化。对于每一层的权重矩阵 $W$,量化后的权重 $W_q$ 应该使得该层的输出误差最小。问题可以形式化为:
$$\arg\min_{W_q} \|WX - W_q X\|^2$$其中 $X$ 是校准数据通过该层时的输入激活值。
直接求解这个问题是不可行的,因为需要搜索所有可能的量化组合。GPTQ采用了一个巧妙的策略:逐行量化,并利用海森矩阵(Hessian Matrix)近似二阶信息来补偿量化误差。
具体而言,当量化权重矩阵的第 $i$ 列时,产生的量化误差 $\delta_i$ 会传播到后续列。GPTQ使用海森矩阵的逆来计算补偿项:
$$\delta_{comp} = -\frac{\delta_i}{[H^{-1}]_{ii}} \cdot H^{-1}_{:,i}$$其中 $H = 2X X^T$ 是海森矩阵的近似。
flowchart LR
A[原始权重 W] --> B[逐列量化]
B --> C[计算量化误差]
C --> D[海森矩阵补偿]
D --> E[更新未量化列]
E --> B
B --> F[量化完成]
GPTQ的一个关键优势是只需要少量校准数据(通常128-256个样本)。量化过程不涉及反向传播,而是纯粹的前向计算和误差补偿。这使得量化一个175B模型只需要约4小时的单卡时间。
实验结果显示,GPTQ可以将模型量化到4bit甚至3bit,同时保持极低的困惑度损失。在OPT-175B上,INT4量化后的困惑度从8.34增加到8.37,几乎可以忽略。
AWQ:激活感知的显著性保护
GPTQ虽然有效,但存在一个潜在问题:它可能过拟合校准数据集。当模型在分布外的数据上推理时,性能可能下降。
MIT Han Lab在2023年提出的AWQ(Activation-aware Weight Quantization)提供了一个不同的视角:不是所有权重都同样重要。
AWQ的出发点是一个简单的实验。研究者发现,将1%的权重保持FP16精度,其余99%量化到INT4,模型的困惑度几乎不增加。这1%的"显著性权重"(salient weights)对模型性能至关重要。
但如何识别这些显著性权重?AWQ的关键洞察是:参考激活分布,而非权重分布。
具体而言,对于权重矩阵的每个通道 $w_j$,其显著性由对应输入激活值的幅度决定:
$$\text{salience}(w_j) = \mathbb{E}[|x_j|]$$如果某个通道的输入激活值普遍较大,那么该通道的权重就更重要——因为任何量化误差都会被大的激活值放大。
AWQ的第二个关键思想是通道缩放(channel scaling)。与其使用混合精度(重要通道用FP16,其他用INT4),AWQ通过等价变换来保护重要通道:
$$y = Wx = (s^{-1} \cdot W)(s \cdot x)$$通过将显著性通道的权重放大,同时相应缩小输入激活值,可以在不改变输出结果的前提下,让这些通道在量化时获得更高的相对精度。
AWQ相比GPTQ有几个优势:
- 更好的泛化性:不依赖反向传播或重构损失,不会过拟合校准集
- 更少的校准数据:只需要16-32个样本
- 更快的推理速度:优化后的kernel实现比GPTQ快2倍以上
权重量化 vs 激活量化
到目前为止讨论的都是权重量化(weight-only quantization):只将权重压缩到低精度,激活值仍然使用FP16计算。这种方式简单有效,因为权重是静态的,可以离线量化。
但更进一步的优化是权重-激活量化(weight-activation quantization),将两者都压缩到INT8。这需要解决之前提到的异常值问题。
LLM.int8() 的解决方案是混合精度分解:
$$Y = WX = W_{outlier} X_{outlier} + W_{normal} X_{normal}$$将包含异常值的通道分离出来,使用FP16单独计算,其余通道使用INT8。由于异常值只占0.1%左右,性能损失极小。
SmoothQuant 则采用迁移平滑的策略。核心思想是将激活值的异常值"迁移"到权重中:
$$Y = (WX) = (W \cdot s^{-1})(s \cdot X)$$通过选择合适的缩放因子 $s$,可以平衡权重和激活值的量化难度。SmoothQuant使得全INT8量化(W8A8)成为可能,在保持精度的同时,可以充分利用硬件的INT8加速单元。
GGUF与K-quants:为本地推理而生
当谈论本地LLM推理时,GGUF格式几乎是不二之选。它由llama.cpp项目开发,专门针对CPU和消费级GPU优化。
GGUF的量化方法与传统方法不同,采用了分层量化(hierarchical quantization)策略。以Q4_K_M为例:
- 每个权重块(block)有256个权重
- 块级别使用6bit存储缩放因子
- 块内部再分为子块,使用更精细的缩放
这种设计的核心考虑是:量化误差的来源不仅是权重本身,还包括缩放因子的表示误差。传统的per-channel量化使用FP32存储缩放因子,虽然精度高但存储开销大。GGUF的K-quants通过分层设计,在精度和压缩率之间找到平衡。
| 量化方法 | 比特/权重 | KL散度(中位数) | 困惑度变化 |
|---|---|---|---|
| Q2_K | 3.00 | 0.0588 | +0.1103 |
| Q3_K_M | 3.89 | 0.0171 | +0.0258 |
| Q4_K_M | 4.83 | 0.0075 | +0.0060 |
| Q5_K_M | 5.67 | 0.0043 | +0.0005 |
| Q6_K | 6.57 | 0.0032 | -0.0008 |
数据来源: GGUF量化方法对比
值得注意的是,GGUF还引入了重要性矩阵(importance matrix, imatrix)的概念。通过分析模型在真实数据上的激活模式,可以为不同层的量化分配不同的精度。这是对AWQ思想的扩展应用。
FP8:硬件原生的量化格式
NVIDIA H100引入了FP8数据类型,这是首次有主流GPU硬件原生支持8位浮点运算。
FP8有两种格式:
- E4M3:4位指数,3位尾数,范围更大,适合前向传播
- E5M2:5位指数,2位尾数,精度更高,适合梯度计算
FP8的关键优势是不需要反量化。INT8权重在参与计算前需要先转换回FP16/FP32,而FP8可以直接在Tensor Core中进行运算。H100的FP8吞吐量是BF16的两倍。
在vLLM等推理框架中,FP8量化通常采用延迟缩放(delayed scaling)策略:使用历史批次的激活统计量来确定缩放因子,而不是每次都重新计算。这简化了实现,同时保持了足够的精度。
BitNet:1.58-bit的极限挑战
2024年,微软提出的BitNet b1.58将量化推向了极限:每个权重只有三种取值 $\{-1, 0, 1\}$,等效于 $\log_2(3) \approx 1.58$ 比特。
BitNet不是后训练量化,而是从零训练的1-bit模型。它修改了标准的线性层:
$$y = \text{Sign}(W) \cdot \text{Quant}(x)$$其中 $\text{Sign}(W)$ 将权重二值化为 {-1, +1},而 $\text{Quant}(x)$ 将激活值量化为整数。
BitNet的核心贡献在于证明了一个反直觉的事实:1.58-bit模型可以与全精度模型性能相当。在相同参数规模和训练token数量的条件下,BitNet b1.58在多个基准测试上与LLaMA LLM持平。
更重要的是,BitNet开创了一种全新的计算范式。由于权重只有三种取值,矩阵乘法可以用加法和减法替代乘法,理论上可以实现数量级的能效提升。
graph LR
A[FP16/BF16<br/>标准模型] --> B{量化路径}
B --> C[PTQ后训练量化<br/>GPTQ/AWQ/GGUF]
B --> D[QAT量化感知训练]
B --> E[原生训练<br/>BitNet]
C --> F[INT4/INT8]
D --> F
E --> G[1.58-bit三元权重]
量化感知训练:训练时就想好要量化
后训练量化(PTQ)有一个根本局限:模型是在全精度下训练的,量化只是一个"补救"措施。量化感知训练(Quantization-Aware Training, QAT)则将量化纳入训练过程,让模型"学会"适应低精度。
QAT的核心技术是伪量化(fake quantization):在前向传播中模拟量化效果,但在反向传播时使用直通估计器(straight-through estimator)绕过量化操作:
$$\frac{\partial L}{\partial w} \approx \frac{\partial L}{\partial w_q}$$LLM-QAT(Data-Free Quantization Aware Training for Large Language Models)进一步解决了数据依赖问题。它不需要原始训练数据,而是使用模型自身生成的合成数据来训练量化后的模型。
QAT相比PTQ有更高的精度上限,但代价是训练成本显著增加。因此,QAT通常用于对精度要求极高的场景,或者极端量化(如2-bit)的情况。
KV Cache量化:被忽视的内存杀手
在长上下文推理中,KV Cache可能比权重占用更多内存。每个token需要在KV Cache中存储键和值,内存占用与序列长度线性相关。
一个简单的计算:假设7B模型,隐藏维度4096,层数32。对于100K上下文,KV Cache需要的内存是:
$$2 \times 32 \times 100000 \times 4096 \times 2 \text{ bytes} \approx 52 \text{ GB}$$这已经超过了权重本身的大小(约14GB)。
KV Cache量化面临的挑战与激活量化类似:存在异常值。但由于KV Cache是在线计算的,不能像权重那样离线分析。
vLLM等框架采用FP8 KV Cache量化,使用逐token的动态缩放因子。相比FP16,内存占用减半,同时精度损失可接受。对于更激进的压缩,也有INT8甚至INT4的KV Cache量化方案,但需要更精细的异常值处理。
实践选择指南
面对众多量化选项,如何选择?
推理硬件是首要考虑因素:
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| NVIDIA H100/H200 | FP8 | 硬件原生支持,无需反量化 |
| NVIDIA A100/3090/4090 | GPTQ或AWQ INT4 | Tensor Core优化,内存带宽敏感 |
| AMD GPU | AWQ | AutoAWQ支持多后端 |
| Apple Silicon | GGUF Q4_K_M | Metal优化,内存统一架构 |
| CPU推理 | GGUF Q4_K_S 或 Q5_K | AVX-512优化,内存带宽是瓶颈 |
精度与压缩的权衡:
- INT8/FP8:几乎无精度损失,推荐生产环境使用
- INT4 Q4_K_M:典型选择,困惑度损失约0.5-1%
- INT3:可接受损失,适合资源极端受限场景
- INT2:仅用于原型验证或极度压缩需求
框架选择:
- vLLM:生产部署首选,支持多种量化后端
- llama.cpp:本地推理,CPU/GPU混合推理
- AutoGPTQ:灵活的量化工具,支持自定义校准
- AutoAWQ:简单易用,校准数据需求少
量化不是免费的午餐,但它是让大模型走出实验室、走向生产环境的关键技术。从INT8到INT4再到1.58-bit,每一次精度的牺牲都换来了更广泛的可用性。在这个内存比算力更昂贵的时代,量化技术的价值只会越来越高。
参考资料
-
Frantar, E., & Alistarh, D. (2022). GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers. ICLR 2023. arXiv:2210.17323.
-
Lin, J., et al. (2023). AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration. MLSys 2024. arXiv:2306.00978.
-
Dettmers, T., et al. (2022). LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale. NeurIPS 2022. arXiv:2208.07339.
-
Xiao, G., et al. (2022). SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models. ICML 2023. arXiv:2211.10438.
-
Wang, H., et al. (2024). The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bits. arXiv:2402.17764.
-
Liu, Z., et al. (2024). LLM-QAT: Data-Free Quantization Aware Training for Large Language Models. ACL 2024.
-
NVIDIA. (2023). Mastering LLM Techniques: Inference Optimization.
-
vLLM Documentation. (2026). Quantized KV Cache.
-
llama.cpp Wiki. (2024). GGUF Quantization Methods Overview.
-
Artefact2. (2024). GGUF quantizations overview. GitHub Gist.