一个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,每一次精度的牺牲都换来了更广泛的可用性。在这个内存比算力更昂贵的时代,量化技术的价值只会越来越高。


参考资料

  1. Frantar, E., & Alistarh, D. (2022). GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers. ICLR 2023. arXiv:2210.17323.

  2. Lin, J., et al. (2023). AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration. MLSys 2024. arXiv:2306.00978.

  3. Dettmers, T., et al. (2022). LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale. NeurIPS 2022. arXiv:2208.07339.

  4. Xiao, G., et al. (2022). SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models. ICML 2023. arXiv:2211.10438.

  5. Wang, H., et al. (2024). The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bits. arXiv:2402.17764.

  6. Liu, Z., et al. (2024). LLM-QAT: Data-Free Quantization Aware Training for Large Language Models. ACL 2024.

  7. NVIDIA. (2023). Mastering LLM Techniques: Inference Optimization.

  8. vLLM Documentation. (2026). Quantized KV Cache.

  9. llama.cpp Wiki. (2024). GGUF Quantization Methods Overview.

  10. Artefact2. (2024). GGUF quantizations overview. GitHub Gist.