大模型量化全景解析:历史、术语、算法体系与现代工程实践
量化不是“把模型变小”这么简单。它是一套横跨数值表示、压缩算法、硬件指令、推理内核、模型结构、评测方法和部署系统的工程体系。
本文讨论的是 AI/LLM 模型量化,不是金融量化交易。
如果用一句话解释:模型量化是把原来用高精度浮点数表示的权重、激活、KV Cache 或梯度,映射到更低比特的离散表示,从而降低显存、内存带宽、存储和计算成本。
它看起来像一个“压缩模型”的技巧,但真正落地时会牵涉到:
- 数学:舍入、缩放、零点、误差传播、率失真;
- 模型:权重、激活、注意力、MoE、视觉塔、LoRA;
- 算法:PTQ、QAT、GPTQ、AWQ、SmoothQuant、QLoRA、AutoRound;
- 格式:GGUF、GPTQ、AWQ、bitsandbytes、safetensors、compressed-tensors;
- 硬件:CPU SIMD、GPU Tensor Core、FP8、INT8、INT4、FP4、NPU;
- 内核:GEMM、GEMV、weight packing、dequant fusion、KV Cache;
- 服务:prefill、decode、continuous batching、PagedAttention、吞吐与延迟;
- 评测:困惑度、MMLU、GSM8K、长上下文、领域集、安全与回归。
本文从历史讲起,再把专有名词、复杂体系、现代方法和开源生态串成一张完整地图。
图 1 把量化放到完整工程链路里看:先有 FP16/BF16 基座模型和校准样本,再统计权重/激活分布,选择量化粒度和算法,最后打包成 GGUF、GPTQ、AWQ、compressed-tensors 等制品,并交给 vLLM、llama.cpp、TensorRT-LLM 或 Transformers 这类 runtime 执行。任何一个环节选错,都会出现“文件很小但速度不快”“benchmark 没掉但业务格式崩了”“同样 4-bit 在不同框架结果不同”这类问题。
零、先把关键词放到坐标系里
量化文章容易读不深,常见原因是把关键词当成孤立名词背:看到 INT4、GPTQ、AWQ、GGUF、FP8、KV Cache,好像都认识,但不知道它们之间到底是什么关系。
更好的读法是把每个词放到一张坐标系里:
| 坐标轴 | 关键问题 | 典型关键词 |
|---|---|---|
| 量化对象 | 到底压缩谁? | W、A、KV Cache、gradient、optimizer state、MoE expert |
| 数值格式 | 用什么低精度表示? | INT8、INT4、FP8、NF4、FP4、MXFP4、NVFP4 |
| 映射参数 | 高精度值如何映射到低精度格点? | scale、zero_point、clipping、rounding、codebook |
| 粒度 | 多少个数共享一套量化参数? | per-tensor、per-channel、per-group、per-token、block-wise、G128 |
| 算法 | 怎么让误差更小? | RTN、GPTQ、AWQ、SmoothQuant、LLM.int8、QLoRA、OmniQuant、AutoRound |
| 训练关系 | 是训练后量化,还是训练中适应? | PTQ、QAT、fake quant、STE、LoRA、FP8 training |
| 文件格式 | 量化后如何保存和交换? | GGUF、GPTQ checkpoint、AWQ checkpoint、safetensors、compressed-tensors |
| 执行引擎 | 谁负责真正跑起来? | llama.cpp、Ollama、vLLM、TensorRT-LLM、Transformers、TorchAO |
| 硬件内核 | 低比特是否真的算得快? | Tensor Core、Triton、CUTLASS、Marlin、ExLlama、GGML、AMX、Metal |
| 评测治理 | 怎么证明它能上线? | perplexity、MMLU、LongBench、needle、TTFT、tokens/s、P99、业务回归 |
这张表里有一个重要结论:INT4 不是一个完整方案,只是数值格式;GPTQ 和 AWQ 是算法;GGUF 是文件格式;llama.cpp 和 vLLM 是执行系统;Tensor Core、AMX、Metal 是硬件路径。
所以,当有人说“我用了 4-bit 量化”,这句话信息不够。更完整的描述应该类似:
Qwen-like 32B
W4A16
group size = 128
AWQ
zero_point = true
格式:safetensors + quant metadata
runtime:vLLM
硬件:A100 80G
评测:MMLU、GSM8K、中文领域集、64k needle、tool-call JSON 回归
这才是一个可复现、可讨论、可上线的量化描述。
一、量化到底是什么?
最抽象的定义来自信号处理:量化是把一个较大的输入集合,通常是连续实数,映射到一个较小的、可数的输出集合。
最简单的例子是四舍五入:
3.14159 -> 3
2.71828 -> 3
-0.12 -> 0
模型量化的版本通常是:
高精度权重:[-0.4321, 0.0137, 1.2842, ...]
低比特表示:[ -7, 0, 21, ...]
缩放系数:scale = 0.061
反量化:real_value ~= int_value * scale
常见线性量化公式可以写成:
q = round(x / scale) + zero_point
x_hat = (q - zero_point) * scale
其中:
x是原始高精度值;q是低比特整数;scale控制每一格代表多大的实数区间;zero_point用来让整数 0 对齐到真实数值中的某个点;x_hat是反量化后用于近似计算的值。
量化一定会引入误差,因为多个原始值会落到同一个低比特值上。工程目标不是“没有误差”,而是让误差在模型可接受范围内,同时换来显著的内存和速度收益。
1. 量化误差来自哪里?
从一个实数 x 变成低比特整数 q,至少会产生三类误差。
| 误差来源 | 发生位置 | 例子 | 工程含义 |
|---|---|---|---|
| 截断误差 | 选择表示范围时 | 极端 outlier 超出范围后被夹到边界 | clipping 策略会影响长尾值 |
| 舍入误差 | 连续值落到离散格点时 | 0.031 和 0.034 都映射到同一个格点 | bit 越低,格点越稀疏 |
| 累积误差 | 多层网络传播时 | 某层输出误差成为下一层输入误差 | 单层 MSE 小不代表最终行为稳定 |
最容易被忽略的是第三类。Transformer 不是单层函数,而是几十层到上百层的残差网络。某一层的微小误差会进入 attention、MLP、residual stream、layer norm,再影响后续 token 的概率分布。生成式模型还会把前一步输出作为下一步输入,所以误差不仅在层间传播,也会在时间步之间传播。
这就是为什么“看起来差一点点”的量化,有时会在代码生成、数学推理、JSON 格式、长上下文引用里突然变差。
2. 线性量化的四个关键选择
线性量化不是只有一个公式,真正重要的是四个选择:
选择 1:表示范围怎么定?
选择 2:范围内有多少格点?
选择 3:每个格点怎么对齐真实值?
选择 4:多少个值共享同一套 scale?
以 n bit 有符号整数为例,可表示格点数量通常是:
levels = 2^n
INT8 约 256 个格点
INT4 约 16 个格点
INT2 约 4 个格点
当从 INT8 下降到 INT4,不是“少一半精度”,而是从约 256 个格点下降到约 16 个格点。每个格点覆盖的实数区间显著变宽,舍入误差会急剧放大。低比特量化困难的根本原因在这里。
3. Clipping 不是小参数
假设一个权重分布大部分落在 [-1, 1],但有少量 outlier 到 [-8, 8]。如果用 min/max 覆盖完整范围,INT4 的 16 个格点要覆盖 16 个单位宽度,大部分普通权重只能挤在很少几个格点里。
另一种做法是 clipping:
原始范围:[-8, 8]
裁剪范围:[-1.5, 1.5]
outlier 被截断,但主体分布获得更密的格点
这就是校准算法要权衡的事情:保护 outlier,还是保护主体分布。不同任务、不同层、不同模型结构的答案不同。SmoothQuant、AWQ、GPTQ、OmniQuant、AutoRound 等方法,本质上都在用不同方式回答这个问题。
4. 量化不是编码压缩
量化和 gzip、zstd、图片压缩不一样。编码压缩的目标通常是文件更小,解压后尽量恢复原数据;模型量化的目标是让低精度表示直接参与计算。
这带来一个重要差异:
编码压缩:小文件 -> 解压 -> 原始计算
模型量化:低比特权重/激活 -> 低比特或混合精度计算 -> 输出
所以量化的收益不只来自文件小,还来自内存带宽下降、cache 命中改善、低精度矩阵乘内核和更高 batch 容量。但如果 runtime 只是把 INT4 解包回 FP16 再算,就会出现“文件小了,速度没有明显提升”的情况。
二、为什么大模型必须关心量化?
一个 70B 参数模型,如果用 FP16 存权重:
70B parameters * 2 bytes ~= 140 GB
这还只是权重,不包括:
- KV Cache;
- 激活峰值;
- runtime workspace;
- 多副本 serving;
- batch 带来的缓存扩张;
- MoE 专家加载;
- tokenizer、embedding、adapter、调度开销。
如果把权重量化到 4-bit,理论权重存储变成:
70B parameters * 0.5 bytes ~= 35 GB
再考虑 scale、zero point、group metadata、对齐 padding 和运行时缓存,实际不会刚好是四分之一,但数量级会明显下降。
量化带来的收益主要有四类。
| 收益 | 解释 |
|---|---|
| 显存下降 | 更大的模型能放进单卡或消费级设备 |
| 带宽压力下降 | decode 阶段常被权重读取和 KV Cache 读取限制 |
| 成本下降 | 同样请求量需要更少 GPU 或更低规格硬件 |
| 边缘部署 | 手机、笔记本、车载、机器人、浏览器更容易跑本地模型 |
但量化也有代价:
- 低比特可能损害困惑度和指令遵循;
- 激活 outlier 会放大量化误差;
- 不同层敏感度不同;
- 内核不匹配时,模型变小但不一定变快;
- 低比特格式越多,部署兼容性越复杂;
- 安全、评测、回归和可复现更难。
所以量化不是单点算法,而是一个系统设计问题。
三、量化历史:从信号处理到 LLM
1. 信号处理时代:量化是数字世界的入口
在深度学习出现前,量化已经是数字通信、音频、图像、视频压缩的基础。
模拟信号要进入计算机,通常要经过:
连续信号 -> 采样 -> 量化 -> 编码
ADC 把连续电压映射成有限 bit 的整数;JPEG、MP3、视频编码会通过量化丢弃人类不敏感的信息;Lloyd-Max 量化讨论如何选择分割边界和重建值来最小化失真。
这套思想后来迁移到神经网络:既然权重和激活也只是数值张量,能不能用更少 bit 表示它们?
2. 深度学习早期:从二值网络到移动端 INT8
2015 到 2017 年前后,研究者尝试了非常激进的低比特网络:
- BinaryConnect:训练时把权重约束到二值;
- BinaryNet / XNOR-Net:权重和激活都接近二值化;
- DoReFa-Net:把权重、激活、梯度都低比特化;
- Integer-only inference:让移动端 CPU 用整数算子完成神经网络推理。
这个阶段的主要驱动力是移动端和嵌入式部署。典型模型是 CNN、MobileNet、检测模型,而不是今天的 LLM。
3. 工具链时代:PTQ 与 QAT 成为标准词汇
2018 到 2021 年,工业界逐渐形成两个主流范式:
- PTQ(Post-Training Quantization):模型训练完后再量化;
- QAT(Quantization-Aware Training):训练或微调时模拟量化误差,让模型适应低精度。
TFLite、TensorRT、ONNX Runtime、PyTorch quantization 等工具链开始成熟。INT8 推理成为很多视觉模型的常规部署方式。
4. LLM 时代:量化突然变成主战场
LLM 改变了问题规模。
CNN 量化主要是为了端侧速度和能耗;LLM 量化首先是为了能不能放进显存。175B、70B、32B 这类模型,即使只做推理,也会把普通硬件直接撑爆。
2022 年之后,几条关键路线出现:
- LLM.int8():处理 Transformer 中的 outlier,把大部分矩阵乘法放到 INT8,同时保留少量高精度路径;
- GPTQ:使用近似二阶信息做 one-shot 权重量化,把大模型压到 3-bit 或 4-bit;
- SmoothQuant:把激活 outlier 的量化难度迁移到权重上,实现 W8A8;
- QLoRA:用 4-bit NF4 冻结基座模型,只训练 LoRA adapter;
- AWQ:根据激活分布识别重要权重通道,用等价缩放保护 salient weights;
- GGUF / llama.cpp:把量化模型带到本地 CPU、Apple Silicon、消费级 GPU 和边缘设备。
量化从论文技巧变成了大模型普及的基础设施。
5. 历史上的几次范式切换
如果只按年份记,很容易觉得量化是一串论文名。更有价值的是看范式切换。
| 阶段 | 核心问题 | 典型对象 | 量化关注点 |
|---|---|---|---|
| 信号处理量化 | 连续世界如何进入数字系统 | 音频、电压、图像、视频 | 采样、编码、率失真 |
| 嵌入式定点计算 | 小设备如何省电省算力 | DSP、MCU、移动端模型 | 定点数、整数乘加、溢出 |
| CNN INT8 推理 | 视觉模型如何部署到手机和服务器 | Conv、BatchNorm、ReLU | PTQ、QAT、per-channel、calibration |
| Transformer 低精度 | 注意力模型如何利用 GPU Tensor Core | BERT、ViT、Encoder 模型 | FP16/BF16、INT8、混合精度 |
| LLM weight-only | 大模型首先要放得下 | 7B、13B、70B Decoder-only 模型 | INT4、GPTQ、AWQ、GGUF |
| LLM serving quant | 模型放得下之后要跑得稳、跑得快 | API 服务、Agent、RAG、长上下文 | FP8、KV Cache、batching、runtime |
| 量化原生模型 | 从训练开始就适配低比特 | BitNet、FP8 training、FP4 路线 | 架构、训练、硬件共同设计 |
这几次切换背后的瓶颈不同:
信号处理:真实世界信号太连续
嵌入式:功耗和算力太有限
CNN 部署:移动端和服务器成本太高
LLM 本地运行:权重太大,显存放不下
LLM 服务:KV Cache、并发和延迟成为瓶颈
未来低比特模型:训练和硬件要一起设计
因此现代 LLM 量化不是孤立发明,而是几十年数值表示、硬件计算和模型压缩技术的连续演进。
四、核心专有名词
1. 数值格式
| 名词 | 含义 | 典型用途 |
|---|---|---|
| FP32 | 32-bit 浮点 | 训练、基准、部分优化器状态 |
| FP16 | 16-bit 浮点 | GPU 训练和推理常用 |
| BF16 | Brain Float 16,指数位更宽 | 训练稳定性更好,现代 GPU/TPU 常用 |
| INT8 | 8-bit 整数 | 成熟推理量化,视觉和 LLM W8A8 常见 |
| INT4 | 4-bit 整数 | LLM weight-only 主流低比特格式 |
| FP8 | 8-bit 浮点,常见 E4M3/E5M2 | 现代 GPU 训练/推理加速 |
| NF4 | NormalFloat4,针对正态分布权重 | QLoRA 的关键格式 |
| FP4 / MXFP4 / NVFP4 | 4-bit 浮点或 microscaling 格式 | 新一代硬件和超低比特推理 |
| 1-bit / 1.58-bit | 二值、三值或 BitNet 类低比特 | 通常需要原生训练或特殊架构 |
这里要区分三个经常混在一起的词。
| 词 | 它回答什么问题 | 常见误解 |
|---|---|---|
| dtype | 张量在计算图里以什么数值类型存在 | 以为 float16、int4 都是同一种 runtime dtype |
| quantization format | 高精度张量如何被低比特表示和反量化 | 以为所有 4-bit 模型可以互相替换 |
| checkpoint/file format | 模型权重和量化元数据如何落盘 | 以为 GGUF、GPTQ、AWQ 只是后缀名不同 |
例如 INT4 只说明每个权重主体大约用 4 bit 表示,但它没有说明:
- 是对称量化还是非对称量化;
- group size 是 32、64、128 还是 256;
- scale 是 FP16、BF16、FP32,还是也被二次量化;
- zero point 是否存在;
- 是否使用 act-order 或 desc_act;
- 是否按列、按行或按 block 打包;
- runtime 是否有对应 kernel;
- 反量化是在 GEMM 前单独做,还是融合在 kernel 里。
因此两个都叫 4-bit 的模型,质量和速度可能完全不同。
dtype、storage dtype、compute dtype
在 LLM 工程里,至少要分清三种 dtype。
| 类型 | 含义 | 例子 |
|---|---|---|
| storage dtype | 权重落盘或驻留显存时的存储格式 | INT4、NF4、FP8、GGUF Q4_K_M |
| compute dtype | 实际矩阵乘或 attention 里使用的计算精度 | FP16、BF16、INT8、FP8 |
| accumulation dtype | 乘加结果累加时使用的精度 | FP32、FP16、BF16、INT32 |
很多低比特方案并不是“全程 4-bit 计算”。常见的 W4A16 是:
权重存储:4-bit
激活输入:FP16/BF16
计算过程:kernel 中解包/反量化后与 FP16/BF16 激活相乘
累加:通常更高精度
输出:FP16/BF16
这类方案主要解决显存和带宽,不一定等同于“用 INT4 Tensor Core 直接计算”。
2. W/A/KV 记法
量化论文和工具经常写:
W8A8
W4A16
W4A8
W4A4
KV FP8
含义是:
W:weights,模型权重;A:activations,推理过程中的激活;KV:attention 的 key/value cache;W4A16:权重 4-bit,激活仍用 16-bit;W8A8:权重和激活都 8-bit;W4A4:权重和激活都 4-bit,难度明显更高。
LLM 中最常见的入门方案是 weight-only quantization,例如 W4A16。它主要减少权重显存和带宽,对内核要求相对低,也更容易保留模型质量。
这些记法也能直接推导出成本结构。
| 方案 | 权重成本 | 激活成本 | 典型优势 | 典型难点 |
|---|---|---|---|---|
| W8A16 | 权重减半左右 | 激活不变 | 稳定、易部署 | 加速有限 |
| W8A8 | 权重和激活都降到 8-bit | 激活也下降 | 硬件友好,服务端常见 | activation outlier 难处理 |
| W4A16 | 权重约四分之一 | 激活不变 | LLM 本地/单卡部署常用 | 需要好 kernel 才能明显提速 |
| W4A8 | 权重很小,激活也压缩 | 激活下降 | 更高压缩和潜在吞吐 | 质量和 kernel 都更难 |
| W4A4 | 极限低比特 | 激活也极低 | 研究和特定硬件方向 | 通常需要 QAT 或架构协同 |
| W4A16 + KV8 | 权重 4-bit,KV 8-bit | KV Cache 降低 | 长上下文 serving | 长上下文质量必须单测 |
W4A16 经常被误解成“模型用 4-bit 运行”。更准确地说,它是权重以低比特存储,但激活和很多中间计算仍保持高精度。这也是为什么它比较稳,但速度收益依赖内核是否能把解包、反量化和矩阵乘融合起来。
3. Scale、Zero Point、Group Size
低比特整数本身没有语义,必须配合缩放参数。
int_value -> real_value
real_value ~= (int_value - zero_point) * scale
group_size 表示多少个权重共享一组 scale/zero point。
| 粒度 | 说明 | 优点 | 缺点 |
|---|---|---|---|
| per-tensor | 整个张量共享 scale | metadata 少,简单 | 精度差 |
| per-channel | 每个输出通道一组 scale | 精度好 | metadata 增加 |
| per-group | 每 N 个权重一组 scale | LLM INT4 常用折中 | kernel 更复杂 |
| per-token | 每个 token 激活动态 scale | 适合 activation/KV | runtime 开销更高 |
| block-wise | 块级 scale,适配硬件 tile | 适合 FP8/FP4/MX 格式 | 依赖硬件和框架 |
G128、group_size=128、q_group_size=128 这类参数,意思通常是每 128 个连续权重共享一套量化参数。它是 LLM INT4 权重量化里最常见的折中点之一。
可以这样理解:
group size 小:
每组覆盖的数更少,scale 更贴合局部分布,质量更好
但 metadata 更多,kernel 加载 scale 的压力更高
group size 大:
metadata 少,打包更简单
但不同分布的权重被迫共享 scale,误差更大
在同一个模型上,G32、G64、G128、G256 的质量、速度和显存可能不同。它不是纯粹的“越小越好”,因为过小的 group 会增加 scale/zero point 元数据,也可能影响 kernel 的访存模式。
粒度和矩阵维度的关系
Transformer 里的大部分参数在 Linear 层中。一个线性层可以写成:
Y = X W^T + b
X: [batch * seq, in_features]
W: [out_features, in_features]
Y: [batch * seq, out_features]
量化 W 时,per-channel 通常对应 out_features 维度,每个输出通道有自己的 scale;per-group 则通常在 in_features 方向切块,让每个输出通道的若干输入权重共享 scale。不同框架的存储布局可能不同,所以同样叫 per-group,实际打包顺序也要看实现。
这也是格式兼容困难的原因:量化不仅是数学,还涉及张量布局。
4. 对称与非对称量化
对称量化:
zero_point = 0
范围大致对称:[-127, 127]
优点是计算简单,硬件友好。缺点是如果数据分布偏移明显,会浪费表示范围。
非对称量化:
zero_point != 0
范围可以覆盖非对称分布
优点是更灵活,缺点是计算和内核更复杂。
5. 静态、动态、权重-only
| 类型 | 含义 | 常见场景 |
|---|---|---|
| 静态量化 | 预先校准权重和激活范围 | 高性能 INT8 部署 |
| 动态量化 | 运行时根据输入动态计算 scale | activation/KV 更灵活 |
| Weight-only | 只量化权重,激活保持 FP16/BF16 | LLM 4-bit 常用 |
| KV Cache 量化 | 压缩注意力缓存 | 长上下文、多并发 serving |
| 训练量化 | 训练或微调过程使用低精度 | FP8 training、QLoRA |
6. 校准集
校准集是用来估计激活分布、选择 scale、识别 outlier 或优化量化参数的一小批样本。
它不一定需要标签,但必须代表真实使用场景。
错误校准集会导致:
- 对聊天好,对代码差;
- 对英文好,对中文差;
- 对短上下文好,对长上下文差;
- 对通用问答好,对领域术语差;
- 对 dense 模型好,对 MoE routing 差。
7. Outlier
LLM 中经常出现极端激活值或极端权重通道。它们数量很少,但对输出影响很大。
处理 outlier 的路线包括:
- 保留高精度路径;
- 对重要通道做缩放保护;
- 把激活难度迁移到权重;
- 混合精度保留敏感层;
- 用旋转变换让分布更均匀;
- 用 QAT 或轻量优化适配量化误差。
Outlier 是 LLM 量化区别于传统 CNN 量化的关键难点之一。
8. 读工具文档一定会遇到的关键词
下面这些词经常出现在 GPTQ、AWQ、bitsandbytes、TorchAO、vLLM、llama.cpp 的配置里。
| 关键词 | 深入解释 | 典型影响 |
|---|---|---|
| calibration | 用一小批样本估计权重/激活分布,或者优化量化参数 | 决定量化是否贴近真实业务 |
| clipping | 把极端值裁剪到某个范围内 | 保护主体分布,但可能牺牲 outlier |
| saturation | 值超出可表示范围后被压到边界 | saturation 过高通常意味着 scale 太小 |
| rounding | 连续值落到哪个离散格点 | RTN、GPTQ、AutoRound 都在处理舍入问题 |
| codebook | 非均匀量化的离散值表 | NF4、向量量化、k-means 量化会用到 |
| packing | 把多个低比特值打包进一个字节或 word | 影响文件大小、显存布局和 kernel 读取 |
| dequantization | 把低比特值恢复成近似实数 | 是否融合到 GEMM 直接影响速度 |
| fused kernel | 把解包、反量化、矩阵乘合在一个 kernel 中 | 避免中间张量,提升吞吐 |
| act-order / desc_act | GPTQ 中按激活重要性调整量化顺序 | 可能改善质量,但影响兼容和速度 |
| static quant | 提前确定 scale 和 zero point | 性能稳定,但依赖校准 |
| dynamic quant | 运行时按输入动态估计 scale | 更灵活,但有额外开销 |
| fake quant | 训练中模拟量化误差,但张量仍用浮点保存 | QAT 常用 |
| STE | Straight-Through Estimator,反向传播时近似处理不可导的 round | 低比特训练和 QAT 的关键技巧 |
| mixed precision | 不同层、通道或模块使用不同精度 | 保护敏感层,但部署复杂 |
| quantization config | 描述 bits、group size、scheme、axis、format 的配置 | 没有配置就无法复现 |
fake quant 和 real quant 的区别尤其重要:
fake quant:
前向传播中模拟 round/clamp/scale 误差
张量通常仍以 FP32/FP16 保存
用来训练模型适应量化
real quant:
权重或激活真实变成低比特存储/计算格式
进入推理 runtime 和 kernel
用来获得实际部署收益
很多 QAT 流程先用 fake quant 训练,再导出 real quant 模型。如果只做 fake quant 而没有部署到真实低比特 kernel,性能收益不会自动出现。
公式补课:从一层 Linear 看量化到底改了什么
为了真正理解 GPTQ、AWQ、SmoothQuant,需要先看一层 Linear 的计算。
Y = X W^T
其中:
X是输入激活;W是权重矩阵;Y是输出激活。
如果做 weight-only 量化,我们保存的不是 W,而是低比特的 Q(W) 加上一些元数据:
W_hat = dequant(Q(W), scale, zero_point)
Y_hat = X W_hat^T
error = Y_hat - Y
注意目标不是让 W_hat 和 W 的每个元素都最接近,而是让 Y_hat 和 Y 尽量接近。因为模型下一层看到的是输出激活,不是权重本身。
这就是 GPTQ 要利用输入分布和 Hessian 近似的原因,也是 AWQ 要看激活分布的原因。
1. 元素误差不等于输出误差
两个权重产生同样大小的量化误差,对输出的影响可能不同。
如果某个输入维度经常很大:
这个维度上的权重量化误差会被放大
如果某个输入维度几乎总是接近 0:
这个维度上的权重量化误差影响可能很小
所以一个更贴近推理行为的目标是:
minimize || X W^T - X W_hat^T ||
而不是只看:
minimize || W - W_hat ||
这句话是大模型量化的核心。很多算法差异都来自“你到底用什么近似目标来衡量误差”。
2. 为什么激活比权重更难量化?
权重是固定的,离线扫一遍就知道分布。激活是运行时输入决定的:
同一个模型:
翻译任务的激活分布
代码任务的激活分布
数学任务的激活分布
64k 长上下文任务的激活分布
可能都不同
如果激活量化使用静态 scale,就需要校准集足够代表真实请求;如果使用动态 scale,就要付出运行时统计和缩放开销。
Transformer 里的 activation outlier 还会集中在少数 channel 上。它们数量少,但不能简单丢掉,因为这些维度可能承载重要语义或路由信息。LLM.int8、SmoothQuant、AWQ 都是在围绕这个问题做设计。
3. 为什么 LayerNorm 和 Residual 会影响量化?
Transformer block 里不是只有矩阵乘。典型结构包含:
LayerNorm -> Attention -> Residual
LayerNorm -> MLP -> Residual
Residual stream 会把多层信息累积起来,LayerNorm 会重新缩放分布。量化误差进入 residual 后,可能被后续层继续携带;LayerNorm 的缩放也可能改变 outlier 的表现。
因此一些实践会保留敏感模块高精度,例如:
- embedding;
- lm_head;
- first/last layer;
- attention output projection;
- router;
- vision projector;
- LayerNorm 周边计算。
这叫 mixed precision 或 layer-wise exception。它牺牲一点压缩率,换取更稳的质量。
4. 量化元数据也占空间
以 INT4 为例,权重主体理论上是 FP16 的四分之一。但实际还要存:
- scale;
- zero point;
- group index 或 block metadata;
- packing padding;
- tensor shape;
- quantization config;
- 有些格式还会保存额外统计量。
所以真实显存不是简单的:
FP16 size / 4
而更像:
quantized_weight
+ scale_metadata
+ zero_point_metadata
+ padding
+ runtime_workspace
+ KV Cache
+ activations
这也是为什么模型权重量化后,服务端显存峰值仍然可能被 KV Cache、batch、workspace 或 CUDA graph 占用主导。
五、量化复杂体系图
这张图说明了一个事实:你不能只问“这个模型能不能 4-bit”。更合理的问题是:
量化什么对象?
用什么算法?
以什么格式保存?
在哪种硬件上跑?
用哪个推理引擎?
用什么业务评测集判断可用?
六、主流算法路线
1. RTN:Round-to-Nearest
RTN 是最朴素的量化:
直接把每个值除以 scale,再四舍五入到最近的低比特值。
优点:
- 简单;
- 快;
- 不需要训练;
- 容易实现。
缺点:
- 对 outlier 敏感;
- 低比特时误差大;
- 不理解不同权重对输出的重要性。
RTN 常被用作 baseline,也会出现在 FP8/INT8 的简单 PTQ 流程里。
RTN 的价值不是“最先进”,而是工程上非常重要的参照物。如果复杂算法相比 RTN 只提升一点质量,却让量化耗时、格式兼容和 runtime 复杂度大幅上升,那在生产中未必值得。
RTN 适合的场景:
- 8-bit 或 FP8 这类误差相对可控的场景;
- 快速验证某个模型是否量化友好;
- 作为 GPTQ/AWQ/AutoRound 的 baseline;
- 对质量要求不高的 embedding、reranker 或小模型;
- 硬件原生支持某种 block floating 格式时。
RTN 不适合的场景:
- 4-bit 以下的高质量 LLM;
- activation outlier 明显的模型;
- 数学、代码、工具调用等对小概率 token 敏感的任务;
- 长上下文和多轮一致性要求高的场景。
2. GPTQ:用二阶信息做 one-shot 权重量化
GPTQ 的核心思想是:逐层量化权重时,不只是看权重本身的误差,而是近似考虑这层输入分布和 Hessian 信息,让量化后的层输出尽量接近原始输出。
简化理解:
普通 RTN:哪个数离最近格点近,就舍入到哪里。
GPTQ:考虑舍入这个权重后,会怎样影响该层输出,并对后续权重做补偿。
GPTQ 在 2022 年让 3-bit、4-bit LLM PTQ 变得实用,是很多后续工具和格式的基础。
适合:
- 4-bit weight-only;
- 显存有限但仍希望保持质量;
- 离线量化后部署到 vLLM、ExLlama、Transformers 等生态。
风险:
- 校准集会影响结果;
- 量化耗时比 RTN 高;
- 不同 kernel 和格式兼容性要检查;
- 新模型结构可能需要适配。
更细一点看,GPTQ 的流程可以理解为:
1. 收集校准样本,跑一遍模型,记录每层输入激活 X
2. 对每个 Linear 层,估计 X^T X 或 Hessian 相关近似
3. 按列或按重要性顺序量化权重
4. 每量化一部分权重,就把误差补偿到后续未量化权重
5. 保存低比特权重、scale、zero point、group size、act-order 等元数据
GPTQ 关注的是“舍入某个权重后,如何影响这层输出”。它不是训练,不需要反向传播更新整个模型,但它比普通 RTN 更理解该层输入分布。
常见 GPTQ 参数含义:
| 参数 | 含义 | 影响 |
|---|---|---|
| bits | 量化 bit 数 | 4-bit 常见,3-bit 更激进 |
| group_size | 每组共享 scale 的权重数量 | 小 group 质量更好但 metadata 更多 |
| damp_percent | Hessian 阻尼,改善数值稳定性 | 太小可能不稳定,太大可能欠拟合 |
| desc_act / act-order | 按激活重要性顺序量化 | 可能提升质量,但影响速度和兼容 |
| sym | 是否对称量化 | 对称更简单,非对称更灵活 |
| true_sequential | 是否按模块顺序逐步量化 | 更贴近真实前向,但更慢 |
GPTQ 的核心风险是“校准集和实现细节绑定较深”。同样是 GPTQ,校准文本、group size、act-order、kernel 支持不同,最终模型可能不是同一个工程制品。
3. SmoothQuant:把激活难题迁移到权重
很多 LLM 层的权重相对容易量化,激活更难,因为激活会出现 outlier。
SmoothQuant 的思路是做一个数学上等价的缩放变换:
降低激活 outlier 的量化难度
把一部分难度迁移到权重上
权重更容易承受这部分变化
它主要面向 W8A8,也就是权重和激活都 8-bit。优点是硬件友好,适合服务端 INT8 推理。
SmoothQuant 的关键是一个等价变换。对矩阵乘:
Y = X W
可以插入一个按通道的缩放向量 s:
Y = (X / s) (s * W)
如果某些激活 channel 特别大,就用 s 把激活压平,同时把相反的缩放迁移到权重。数学上输出不变,但量化难度从“难量化的激活”转移到“更容易离线处理的权重”。
SmoothQuant 的关键参数通常是迁移强度,可以理解为:
alpha 小:更多保护权重,激活 outlier 仍明显
alpha 大:更多平滑激活,权重分布变得更难
它适合追求 W8A8、INT8 Tensor Core 或服务端稳定吞吐的场景。它不等同于 4-bit weight-only,关注点也不一样。
4. LLM.int8():outlier 单独保留高精度
LLM.int8() 观察到大模型中存在少数非常关键的 outlier feature。它把绝大多数计算放到 INT8,同时把 outlier 维度拆出来走高精度路径。
简化理解:
99.9% 普通值:INT8
少量 outlier:FP16
结果:接近无损,显存下降明显
bitsandbytes 的 8-bit 加载和训练生态,很大程度推动了这条路线的普及。
LLM.int8 的直觉是:与其强行把 outlier 压进 INT8,不如承认少量通道确实不适合低精度,把它们拆出去保留高精度。
这是一种典型的混合精度策略:
| 部分 | 处理方式 | 原因 |
|---|---|---|
| 普通通道 | INT8 矩阵乘 | 数量多,适合低精度加速和省显存 |
| outlier 通道 | FP16/BF16 路径 | 数量少但影响大,强行量化会损害质量 |
| 最终输出 | 合并两路结果 | 在效率和精度之间折中 |
它的优势是质量稳定,缺点是 kernel 和实现更复杂,且压缩率不如纯 4-bit weight-only 激进。
5. QLoRA:量化不是只为推理,也能让微调变便宜
QLoRA 不是简单“把模型量化后推理”,而是:
冻结 4-bit NF4 基座模型
反向传播穿过量化模型
只训练 LoRA adapter
它的关键创新包括:
- NF4:更适合近似正态分布权重;
- Double Quantization:连量化常数也再量化,进一步省显存;
- Paged Optimizers:缓解训练时显存峰值。
QLoRA 的价值是让 33B、65B 这类模型的微调门槛大幅下降。
QLoRA 要分清两件事:
基座模型:
4-bit NF4 存储,通常冻结不训练
LoRA adapter:
小规模可训练参数,通常 FP16/BF16
反向传播会穿过量化基座,但主要更新 LoRA 参数。这让显存大幅下降,同时避免直接训练完整低比特基座的困难。
NF4 之所以重要,是因为神经网络预训练权重常接近正态分布。普通 INT4 的格点是均匀间隔,NF4 的离散值更贴近正态分布下的高概率区域。直观地说,它把有限的 16 个 4-bit 格点更多分配给“权重更常出现的位置”。
QLoRA 常见风险:
- adapter 训练数据质量仍然是核心,不会因为 4-bit 自动变好;
- 量化基座、LoRA target modules、rank、alpha、学习率互相影响;
- 最终部署时,adapter 合并、继续外挂 adapter、重新量化会产生不同结果;
- 训练能跑不等于 serving 最快,bitsandbytes 更偏训练/加载便利。
6. AWQ:根据激活识别重要权重通道
AWQ 的出发点是:不是所有权重同等重要。少量 salient weights 对输出影响很大。
它通过激活统计识别重要通道,再用等价缩放保护这些通道,同时避免硬件不友好的逐权重混合精度。
适合:
- 4-bit weight-only;
- 指令模型;
- 多模态模型;
- 端侧和本地推理;
- 需要较好泛化而不想过度依赖校准集的场景。
AWQ 的关键观察是:保护少量重要权重,比平均保护所有权重更有效。它不是简单地把重要权重保留成 FP16,而是通过等价缩放让这些重要通道在量化后保留更多信息,同时仍保持硬件友好的整块低比特结构。
可以把 AWQ 理解成三步:
1. 用校准样本观察激活,判断哪些 channel 对输出更敏感
2. 对重要 channel 做缩放保护,让它们量化损失更小
3. 把缩放后的权重整体量化,保持 kernel 友好的 weight-only 格式
这就是 AWQ 与“逐权重混合精度”的区别:它尽量避免破坏低比特矩阵乘的规则结构。
AWQ 在多模态模型中也常被讨论,因为视觉语言模型的 projector、vision token 和语言层对误差的敏感度不一样。对这类模型,校准样本最好包含真实图文输入,而不是只喂纯文本。
7. SpQR、OmniQuant、AutoRound 与更新路线
后续方法大多围绕三个问题展开:
-
哪些值最敏感?
- SpQR 隔离 outlier weights;
- mixed precision 保留关键层或关键通道。
-
量化参数如何更好地优化?
- OmniQuant 优化 clipping 和等价变换;
- AutoRound 优化 rounding 策略;
- SignRound 等方法进一步改善低比特舍入。
-
如何适配硬件?
- Marlin、ExLlama、GGML、CUTLASS、Triton kernel 让压缩真正变成速度;
- FP8、FP4、MXFP4、NVFP4 逐渐与硬件 Tensor Core 绑定。
这些方法可以按“主要优化对象”来理解。
| 方法 | 主要想解决什么 | 适合关注点 |
|---|---|---|
| SpQR | outlier weight 对低比特量化破坏大 | near-lossless 压缩、稀疏异常值 |
| OmniQuant | clipping、scale、等价变换需要联合优化 | 无需大规模训练的 PTQ 质量 |
| AutoRound | round 到哪个格点不是固定规则 | 低比特舍入优化、工程易用性 |
| Rotation-based quantization | 分布不均匀,outlier 集中 | 通过旋转让分布更平滑 |
| Mixed precision | 少数层明显更敏感 | 生产质量兜底 |
| QAT | PTQ 已不足以保质量 | 极低比特或高风险任务 |
现代量化已经从“把权重 round 一下”演化成多目标优化:既要让误差小,又要保持 kernel 规则;既要利用校准数据,又不能过拟合;既要压缩权重,也要考虑激活、KV Cache、MoE routing 和业务回归。
8. 主流路线横向对比
| 路线 | 主要对象 | 是否需要校准集 | 常见目标 | 优势 | 风险 |
|---|---|---|---|---|---|
| RTN | 权重/激活 | 不一定 | 快速 baseline | 简单、快、易实现 | 低比特质量差 |
| GPTQ | 权重 | 需要 | W4A16 / W3A16 | 4-bit 质量好,生态成熟 | 校准和参数敏感 |
| AWQ | 权重 | 需要少量激活统计 | W4A16 | 泛化较好,适合指令/VLM | runtime 支持要确认 |
| SmoothQuant | 权重 + 激活 | 需要 | W8A8 | 服务端 INT8 友好 | 主要面向 8-bit |
| LLM.int8 | 权重/矩阵乘 + outlier | 较少 | 8-bit 加载/推理 | 稳,质量损失小 | 压缩率不如 4-bit |
| QLoRA | 4-bit 基座 + LoRA | 训练数据 | 低成本微调 | 显存门槛低 | serving 方案需另选 |
| FP8 | 权重/激活/训练 | 取决于流程 | 新 GPU 训练/推理 | 硬件原生支持强 | 依赖硬件和框架 |
| KV quant | KV Cache | 需要长上下文验证 | 长上下文/高并发 | 降低 serving 显存 | 可能损害引用和记忆 |
| QAT | 权重/激活 | 需要训练 | 极低比特/高质量 | 质量潜力高 | 成本高、流程复杂 |
一个常见误区是把这些路线看成排名。实际上它们解决的问题不同:
要本地跑得起来:优先 GGUF / W4A16
要服务端吞吐:优先 FP8 / W8A8 / AWQ / GPTQ + runtime
要低成本微调:优先 QLoRA
要长上下文并发:必须考虑 KV Cache
要极低比特:PTQ 可能不够,需要 QAT 或架构协同
七、量化对象:不只是权重
1. 权重量化
权重量化是最常见、最容易理解的量化。
优点:
- 权重是静态的,可以离线处理;
- 显存收益稳定;
- 对 decode 阶段权重带宽有帮助;
- 可以直接发布量化 checkpoint。
典型格式:
- GGUF;
- GPTQ;
- AWQ;
- bitsandbytes 4-bit;
- compressed-tensors;
- TorchAO tensor subclass。
2. 激活量化
激活是运行时产生的,跟输入有关。
难点:
- 分布动态变化;
- outlier 更明显;
- 长上下文和不同任务分布差异大;
- scale 计算会引入 runtime overhead。
激活量化能让矩阵乘法更彻底地使用低精度硬件,但难度比 weight-only 高。
3. KV Cache 量化
KV Cache 是现代 LLM serving 的核心瓶颈之一。
自回归生成时,每生成一个 token,都要保留前面 token 的 key/value。上下文越长、并发越高,KV Cache 越大。
KV Cache size ~= layers * sequence_length * hidden_dim * batch * dtype
更完整地说,KV Cache 近似由下面几个变量决定:
layers
* batch_size
* sequence_length
* num_kv_heads
* head_dim
* 2 # K 和 V 两份缓存
* bytes_per_value
在 grouped-query attention 或 multi-query attention 中,num_kv_heads 会小于 num_attention_heads,这本身就是一种降低 KV Cache 成本的结构设计。量化 KV Cache 则是在结构之外进一步压缩 bytes_per_value。
KV Cache 量化的价值:
- 支持更长上下文;
- 提高并发;
- 降低显存;
- 降低 attention 读取带宽。
但它也可能影响长上下文检索、细粒度引用和多轮对话稳定性,因此必须用长上下文评测单独验证。
KV Cache 量化常见策略:
| 策略 | 说明 | 风险 |
|---|---|---|
| KV8 | K/V 用 8-bit 保存 | 通常较稳,但仍需长上下文回归 |
| KV4 | K/V 用 4-bit 保存 | 压缩强,质量风险更大 |
| per-token scale | 每个 token 或 block 动态 scale | 质量好,metadata 和计算开销更高 |
| sliding window | 只保留局部窗口或压缩远端上下文 | 可能影响远距离引用 |
| mixed precision KV | 近期 token 高精度,远期 token 低精度 | 适合长上下文,但实现更复杂 |
长上下文场景里,权重显存可能不是最大瓶颈。一个 7B 模型量化到 4-bit 后,权重已经很小,但当上下文拉到 128k、并发增加时,KV Cache 会迅速成为主成本。Agent、多轮对话、RAG 长文档、代码仓库问答都属于这种情况。
4. 训练量化和优化器状态
训练阶段的显存不只来自模型权重,还包括:
- 梯度;
- optimizer states;
- activation checkpoints;
- master weights;
- LoRA adapter;
- 数据并行通信 buffer。
QLoRA 通过 4-bit frozen base + LoRA 显著降低微调成本。FP8 training 则把训练计算本身推向低精度硬件。
5. MoE 与多模态量化
MoE 模型有额外问题:
- 不同 expert 分布不同;
- router 对误差敏感;
- expert 并非每次都激活;
- 热门 expert 和冷门 expert 校准样本不均衡。
多模态模型也类似:
- 视觉塔、音频塔、语言塔分布不同;
- projector 可能非常敏感;
- 图像 token、音频 token、文本 token 的激活范围不同;
- 只用文本校准集会误伤视觉问答。
现代量化越来越强调 architecture-aware 和 modality-aware,不能再把所有 Linear 层一刀切。
八、硬件与内核:为什么量化后不一定更快?
模型变小,不等于速度一定提升。
图 2 展示了量化模型进入推理服务后的真实位置:用户请求先经过调度层,再由 runtime 加载量化模型制品,最后交给低比特 kernel 和硬件执行。权重量化、激活量化、KV Cache 量化分别作用在不同瓶颈上。只有模型格式、runtime、kernel 和硬件路径都匹配,量化才会同时带来显存、吞吐和延迟收益。
1. 低比特计算需要匹配硬件
如果 GPU 没有高效 INT4/FP8/FP4 Tensor Core,或者推理框架没有对应 kernel,低比特权重可能要先解包、反量化成 FP16 再算。
这时收益主要是省显存,不一定提速。
理想:INT4 packed weights -> Tensor Core / custom kernel -> 快速输出
糟糕:INT4 unpack -> dequant to FP16 -> 普通 FP16 GEMM -> 额外开销
2. Prefill 和 Decode 的瓶颈不同
LLM 推理分两个阶段:
| 阶段 | 特点 | 常见瓶颈 |
|---|---|---|
| Prefill | 处理输入 prompt,矩阵乘法大 | 计算吞吐 |
| Decode | 每次生成一个 token | 权重/KV 读取、调度、batching |
Weight-only INT4 对 decode 很有帮助,因为 decode 经常被内存带宽限制。但 prefill 可能需要更高效的矩阵乘内核才能明显加速。
可以用一个简单判断理解:
如果瓶颈是内存带宽:
权重/KV 变小通常很有帮助
如果瓶颈是计算吞吐:
必须有硬件原生低精度算子和高效 kernel
如果瓶颈是调度:
量化本身帮不了太多,需要 batching、cache、路由和队列优化
Prefill 阶段一次处理很多 prompt token,矩阵乘规模大,容易接近 compute-bound;decode 阶段每次只生成一个 token,batch 维度小,频繁读取权重和 KV Cache,更容易 memory-bound。量化对这两个阶段的收益曲线不同,所以性能报告必须拆开测。
一个合格的性能表至少要分开记录:
| 指标 | 为什么要单独看 |
|---|---|
| TTFT | 用户感知首 token 延迟,主要受 prefill 和排队影响 |
| decode tokens/s | 生成阶段速度,常受权重/KV 读取影响 |
| request throughput | 服务整体吞吐,受 batching 和调度影响 |
| P95/P99 latency | 量化可能改善均值但恶化尾延迟 |
| max concurrency | KV Cache 和显存碎片会限制并发 |
| memory peak | 权重、KV、activation、workspace 都要算 |
3. Kernel 决定上限
典型低比特内核问题包括:
- 权重打包格式;
- group scale 加载;
- 反量化是否融合到 GEMM;
- act-order 是否需要重排;
- batch size 多大;
- 是否支持 MoE;
- 是否支持 tensor parallel;
- 是否支持 CUDA graph;
- 是否支持 attention/KV cache 低精度。
很多量化论文只证明“模型质量可接受”,真正生产还要看 kernel 是否足够成熟。
4. CPU、GPU、Apple Silicon、NPU 是不同世界
| 平台 | 常见路线 |
|---|---|
| x86 CPU | AVX2/AVX512/VNNI/AMX,常见 INT8/INT4 优化 |
| ARM CPU | NEON、i8mm,端侧和移动设备重要 |
| NVIDIA GPU | Tensor Core,FP16/BF16/INT8/FP8/FP4 路线 |
| AMD GPU | ROCm/HIP,支持进展取决于框架 |
| Apple Silicon | Metal/MLX/llama.cpp,本地推理体验强 |
| NPU/TPU/Gaudi/Ascend | 通常依赖厂商编译器和特定低精度格式 |
选择量化格式前,先看目标硬件和推理引擎支持什么。
现代方式:量化已经从脚本变成平台能力
早期量化经常是一个离线脚本:
load fp16 model
run quantize.py
save quantized checkpoint
现代 LLM 量化更像平台能力,至少有六条路线并行存在。
1. 离线 checkpoint 量化
这是最容易理解的方式:把一个 FP16/BF16 模型离线转换成低比特制品,再上传或分发。
典型路线:
- llama.cpp 转 GGUF;
- GPTQModel 生成 GPTQ checkpoint;
- AWQ/LLM Compressor 生成 AWQ 或 compressed-tensors;
- TensorRT-LLM / ModelOpt 生成面向 NVIDIA 的优化制品。
优点是部署时加载快,制品可版本化;缺点是每个 runtime 支持的格式和 kernel 不同。
2. 加载时量化
有些框架允许加载 FP16 模型时直接指定低比特配置,例如使用 bitsandbytes 4-bit/8-bit 加载。它适合实验、微调和快速验证。
优点:
- 不需要提前保存多个量化副本;
- 和 Transformers、PEFT、训练脚本结合方便;
- 适合 QLoRA 这类微调流程。
缺点:
- 加载和初始化可能更慢;
- serving 性能不一定最优;
- 线上制品可复现性需要额外记录配置。
3. 硬件原生低精度
FP8、FP4、MXFP4、NVFP4 代表的是另一条路线:让硬件直接提供更低精度的数据格式和计算能力。
这类方式的关键不是“文件压得多小”,而是:
- Tensor Core 或矩阵引擎是否原生支持;
- framework 是否能自动选择低精度 kernel;
- scale/block metadata 是否适配硬件 tile;
- 训练和推理是否共用一套低精度策略。
在新 GPU 上,FP8/FP4 往往比传统 INT4 checkpoint 更接近“平台默认能力”。
4. Runtime 内置压缩
现代 serving 框架越来越多地把量化当成 runtime 能力,而不是外部工具。
例如 vLLM 需要同时考虑:
- 权重量化格式;
- PagedAttention;
- KV Cache dtype;
- continuous batching;
- tensor parallel;
- speculative decoding;
- LoRA serving;
- prefix caching;
- CUDA graph;
- 多模型路由。
量化如果不能和这些能力一起工作,线上价值会打折。
5. 面向训练和微调的量化
QLoRA、FP8 training、QAT、低比特 optimizer 是训练侧路线。它们关注的是训练显存、通信、optimizer state 和反向传播稳定性,而不是单纯推理速度。
训练侧量化要额外关注:
- 梯度缩放;
- loss scale;
- optimizer state 精度;
- activation checkpointing;
- distributed training 通信精度;
- adapter 合并后的部署格式。
6. 结构感知量化
现代模型越来越复杂,不能再一刀切扫描所有 Linear 层。
结构感知量化会区分:
- attention 的 Q/K/V/O projection;
- MLP 的 gate/up/down projection;
- embedding 和 lm_head;
- MoE router 和 experts;
- vision encoder 和 projector;
- audio/video encoder;
- speculative decoding draft model;
- safety head 或 reward model。
一些层可以 4-bit,一些层更适合 8-bit,一些层应该保留 BF16。这类 mixed precision 策略往往比盲目全模型 4-bit 更可靠。
九、现代量化工作流
1. 明确目标
不同目标会导向不同方案。
| 目标 | 推荐起点 |
|---|---|
| 本地运行聊天模型 | GGUF + llama.cpp / Ollama |
| 消费级 NVIDIA GPU | GPTQ/AWQ/EXL2 + ExLlama/vLLM |
| 服务端高吞吐 | vLLM + FP8 / AWQ / GPTQ / compressed-tensors |
| NVIDIA 生产优化 | TensorRT-LLM / ModelOpt / FP8 |
| 低成本微调 | QLoRA + bitsandbytes + PEFT |
| CPU 或边缘设备 | llama.cpp GGUF / Intel Neural Compressor / TorchAO |
| 长上下文 serving | KV Cache quantization + 长上下文回归 |
| 多模态模型 | modality-aware calibration,不要只用文本校准 |
2. 建立 FP16/BF16 基线
先记录原模型:
- 显存;
- TTFT;
- tokens/s;
- 吞吐;
- 困惑度;
- MMLU/GSM8K/代码/领域集;
- 长上下文;
- 安全拒答;
- 业务人工样例。
没有基线,量化后的“差不多”没有意义。
3. 选择校准集
校准集应该覆盖真实分布:
- 短问答;
- 长上下文;
- 代码;
- 中文;
- 数学;
- 工具调用;
- 表格;
- 领域术语;
- 多轮对话;
- 多模态输入。
通常几十到几百条就能做基础 PTQ,但高风险场景要扩大覆盖。
4. 先从保守方案开始
推荐路线:
FP16/BF16 baseline
-> INT8 或 FP8
-> W4A16
-> W4A8 / W4A4
-> KV Cache quantization
-> mixed precision / layer-wise exception
不要一开始就追极限 2-bit。量化的目标是可用,不是数字越低越好。
5. 用决策树选择第一版方案
这棵树的原则是:先选择最容易验证、最容易回滚、最符合目标硬件的方案,再逐步压低 bit 数。很多团队一开始直接追 3-bit 或 2-bit,最后节省的显存不如调试和质量回归成本大。
6. 量化后一定要做业务回归
通用 benchmark 不够。量化可能不会明显影响 MMLU,却会影响:
- 输出格式稳定性;
- 工具调用 JSON;
- 中文专有名词;
- 数学步骤;
- 长上下文引用;
- RAG 答案中的细节;
- 安全边界;
- 代码补全。
生产中应建立量化回归集,并在每次模型、校准集、runtime 或 kernel 变化时重新跑。
十、如何选择量化方案?
场景一:个人电脑或本地应用
优先考虑:
llama.cpp;Ollama;GGUF;- Q4_K_M、Q5_K_M、Q8_0 等量化等级。
经验规则:
- 显存/内存很紧:Q4;
- 想要质量更稳:Q5/Q6;
- 追求接近原始:Q8;
- CPU-only:关注线程数、内存带宽、BLAS/Metal/Vulkan 后端。
场景二:单机多卡或服务端推理
优先考虑:
- vLLM;
- TensorRT-LLM;
- FP8;
- AWQ;
- GPTQ;
- compressed-tensors;
- KV Cache FP8。
经验规则:
- H100/H200/Blackwell 等新卡:优先评估 FP8/FP4 生态;
- A100/A10/4090:INT4 weight-only、AWQ/GPTQ 仍然常见;
- 高并发长上下文:重点评估 KV Cache 量化;
- MoE:确认专家量化和 router 兼容性。
场景三:低成本微调
优先考虑:
- QLoRA;
- bitsandbytes 4-bit;
- PEFT;
- NF4;
- LoRA adapter。
经验规则:
- 基座模型 frozen;
- adapter 用 FP16/BF16;
- 优先保存 adapter 和训练配置;
- 最终部署时再决定是否合并或继续使用量化基座。
场景四:企业生产
优先级不应该只看压缩率。
建议排序:
业务质量 > 可回滚 > runtime 稳定 > 监控可解释 > 成本下降 > 极限压缩率
企业生产还要考虑:
- 模型许可证;
- checkpoint 来源;
- 格式长期可维护;
- 硬件供应;
- 多区域部署;
- 灰度回滚;
- 量化前后安全评测;
- 量化模型是否能进入模型注册表和审计链路。
十一、高 star 开源生态梳理
下面 star 数为 GitHub 页面在 2026-06-19 检索到的近似值。Star 不是技术质量排名,只能反映生态热度、历史积累和社区关注度。
| 项目 | Star | 类型 | 和量化的关系 |
|---|---|---|---|
| Ollama | 175k | 本地模型运行平台 | 让用户直接拉取和运行量化模型,底层大量受益于 llama.cpp/GGUF 生态 |
| Transformers | 162k | 模型定义与生态中枢 | 集成 bitsandbytes、GPTQ、AWQ、Optimum 等量化入口,是模型兼容性的中心 |
| llama.cpp | 117k | C/C++ 本地推理引擎 | GGUF、低比特量化、本地 CPU/GPU/Metal/Vulkan 推理的事实标准之一 |
| vLLM | 83.3k | 高吞吐 LLM serving | 支持 FP8、MXFP8/MXFP4、NVFP4、INT8、INT4、GPTQ、AWQ、GGUF、TorchAO 等量化路径 |
| TensorRT-LLM | 13.9k | NVIDIA 推理优化栈 | 面向 NVIDIA GPU 的高性能 LLM 推理与低精度优化 |
| bitsandbytes | 8.3k | k-bit PyTorch 量化库 | 8-bit/4-bit 加载、QLoRA、低成本微调的重要基础库 |
| AutoGPTQ | 5.1k | GPTQ 量化工具 | GPTQ 易用封装;仓库已于 2025-04-11 archived,官方建议迁移 GPTQModel |
| ExLlamaV2 | 4.6k | 消费级 GPU 推理库 | GPTQ/EXL2 本地推理性能强;仓库提示开发转向 ExLlamaV3 |
| AWQ | 3.6k | AWQ 原始实现 | Activation-aware Weight Quantization,支持 INT3/4、TinyChat、VLM |
| LLM Compressor | 3.4k | vLLM 量化压缩工具链 | 支持 GPTQ、AWQ、SmoothQuant、AutoRound、KV Cache、compressed-tensors |
| Optimum | 3.4k | Hugging Face 硬件优化工具 | 面向 Transformers/Diffusers 等模型的训练和推理优化入口 |
| GPTQ-for-LLaMa | 3.1k | 早期 GPTQ LLaMA 工具 | 4-bit LLaMA GPTQ 的早期重要项目,README 推荐转向 AutoGPTQ |
| TorchAO | 2.9k | PyTorch 原生优化库 | 支持 INT4、INT8、FP8、MXFP4/MXFP8、QAT/PTQ、稀疏等训练到服务优化 |
| Intel Neural Compressor | 2.7k | 通用模型压缩工具 | 面向 PyTorch/TensorFlow/ONNX/JAX 的量化、剪枝、蒸馏和稀疏 |
| AutoAWQ | 2.3k | AWQ 易用封装 | 已于 2025-05-11 archived,README 提示 vLLM 项目已接手相关方向 |
| AutoRound | 1.5k | rounding 优化量化算法 | 支持 CPU/XPU/CUDA,兼容 vLLM、SGLang、Transformers、GGUF |
| GPTQModel | 1.2k | GPTQ 后继工具链 | 面向 NVIDIA/AMD/Intel/Apple CPU 等多硬件,兼容 HF、vLLM、SGLang |
怎么读这张表?
这些项目分成四类:
- 生态中枢:Transformers、Optimum、TorchAO;
- 本地推理:llama.cpp、Ollama、ExLlama;
- 服务端推理:vLLM、TensorRT-LLM;
- 量化算法/压缩工具:bitsandbytes、GPTQModel、AWQ、LLM Compressor、AutoRound、Neural Compressor。
生产选型时不要只看 star。更应该问:
- 是否仍维护?
- 是否支持目标模型结构?
- 是否支持目标硬件?
- 是否支持目标推理引擎?
- 是否有成熟 kernel?
- 是否能保存到长期可读格式?
- 是否有评测和回滚流程?
AutoGPTQ、AutoAWQ、ExLlamaV2 都有很高历史价值,但页面已经提示维护状态变化;新项目更应该看 GPTQModel、LLM Compressor、vLLM、TorchAO 等仍活跃路线。
开源项目不是同一层东西
很多人把上面这些项目放在同一个维度比较,这是不准确的。更合理的分层是:
| 层级 | 你真正需要它解决什么 | 代表项目 |
|---|---|---|
| 模型入口层 | 下载模型、加载配置、兼容 tokenizer 和模型结构 | Transformers、Optimum |
| 量化算法层 | 把 FP16/BF16 模型变成低比特制品 | GPTQModel、LLM Compressor、AWQ、AutoRound、bitsandbytes |
| 制品格式层 | 保存低比特权重和量化元数据 | GGUF、GPTQ/AWQ checkpoint、compressed-tensors、safetensors |
| Runtime 层 | 管理请求、batch、KV Cache、模型加载和执行 | vLLM、llama.cpp、Ollama、TensorRT-LLM |
| Kernel 层 | 真正执行低比特矩阵乘和 attention | GGML、Marlin、ExLlama、CUTLASS、Triton、TorchAO |
| 硬件层 | 提供低精度指令和内存带宽 | NVIDIA GPU、Apple Silicon、x86 AMX、ARM NEON、NPU |
因此,“Transformers 支持某个量化模型”不等于“生产 serving 最快”;“某个 GitHub 项目能量化”也不等于“目标 runtime 有高性能 kernel”。工程选型要看链路完整性。
典型组合
| 目标 | 推荐组合 | 说明 |
|---|---|---|
| Mac 本地聊天 | Ollama / llama.cpp + GGUF Q4/Q5 | 简单稳定,适合本地应用 |
| 消费级 NVIDIA GPU | ExLlama/GPTQModel 或 vLLM + GPTQ/AWQ | 关注显存和单用户 tokens/s |
| 服务端 API | vLLM + AWQ/GPTQ/FP8/compressed-tensors | 关注 batching、KV Cache 和吞吐 |
| NVIDIA 高性能部署 | TensorRT-LLM + FP8/INT8/FP4 路线 | 版本、硬件和编译链绑定更强 |
| 低成本微调 | Transformers + PEFT + bitsandbytes/QLoRA | 训练方便,serving 另行评估 |
| PyTorch 原生优化 | TorchAO | 适合跟 PyTorch 生态和新低精度类型结合 |
| Intel/CPU/ONNX 场景 | Neural Compressor / OpenVINO / ONNX Runtime | 关注 CPU 指令集和图优化 |
看开源项目时要问的十个问题
- 最近是否仍在维护?
- 支持哪些模型结构,是否支持当前模型的 attention、MoE、VLM projector?
- 支持哪些量化对象,是只支持权重,还是也支持激活和 KV Cache?
- 输出格式能被哪些 runtime 直接加载?
- 目标硬件上是否有成熟 kernel?
- 是否支持 tensor parallel、pipeline parallel、LoRA、speculative decoding?
- 量化配置是否能完整保存并复现?
- 是否有官方或社区 benchmark,是否区分 prefill/decode?
- 是否有 archived、迁移、重命名或维护者变更风险?
- 许可证是否允许你的业务使用和再分发?
十二、常见格式和生态关系
| 格式/生态 | 典型用途 | 优点 | 注意事项 |
|---|---|---|---|
| GGUF | llama.cpp/Ollama 本地推理 | 自包含、跨平台、本地生态强 | 不一定适合服务端 GPU 高吞吐 |
| GPTQ | 4-bit weight-only | 质量好、生态广 | kernel 和 act-order 兼容性要看 runtime |
| AWQ | 4-bit weight-only | 泛化好、VLM 支持较好 | 工具链迁移到 vLLM/LLM Compressor 等方向 |
| bitsandbytes | 8-bit/4-bit 加载和 QLoRA | 易用、训练生态成熟 | 生产 serving 不一定是最高性能 |
| compressed-tensors | vLLM 压缩模型交换格式 | 面向现代 serving | 生态仍在快速演进 |
| TorchAO | PyTorch 原生低精度张量 | 训练到推理统一 | 需要跟 PyTorch 和 runtime 版本对齐 |
| ONNX / TensorRT | 工业推理部署 | 硬件优化强 | LLM 动态结构和新模型支持要验证 |
十三、量化评测:不要只看模型能不能回答
量化评测至少分四层。
1. 数值层
- 权重重建误差;
- layer output MSE;
- activation range;
- saturation ratio;
- outlier coverage;
- dequant 后分布漂移。
2. 模型层
- Perplexity;
- MMLU;
- GSM8K;
- HumanEval;
- MT-Bench;
- code benchmark;
- 多语言 benchmark。
3. 系统层
- 显存峰值;
- 模型加载时间;
- TTFT;
- tokens/s;
- request throughput;
- P50/P95/P99 latency;
- prefill/decode 分别测速;
- batch size 扩展曲线;
- 长上下文 KV Cache 占用。
4. 业务层
- RAG 引用准确率;
- JSON/tool call 成功率;
- 安全拒答一致性;
- 中文术语准确性;
- 领域问答;
- 长文档摘要;
- 多轮记忆;
- 线上 A/B 质量。
一个健康的量化报告应该长这样:
model: "Qwen-like-32B"
baseline_dtype: "BF16"
quantized_dtype: "W4A16-G128-AWQ"
runtime: "vLLM"
hardware: "A100-80G"
quality:
perplexity_delta: "+1.8%"
mmlu_delta: "-0.4"
gsm8k_delta: "-0.8"
json_tool_call_success_delta: "-0.2%"
domain_qa_pass_rate: "96.5%"
performance:
memory_reduction: "58%"
ttft_delta: "-12%"
decode_tokens_per_second_delta: "+41%"
max_batch_size_delta: "+75%"
risks:
- "长上下文 64k needle recall 下降 2.1%"
- "数学链式推理对 3-bit 更敏感,当前不启用 3-bit"
十四、常见误区
1. “4-bit 一定比 8-bit 快”
不一定。
如果硬件和 kernel 不支持高效 4-bit,解包和反量化开销可能抵消收益。8-bit 反而可能更快、更稳。
2. “量化只影响模型质量,不影响系统行为”
量化会影响输出分布,进而影响:
- sampling;
- tool calling;
- JSON 格式;
- safety classifier;
- speculative decoding acceptance rate;
- RAG 引用细节;
- 长上下文注意力。
3. “通用 benchmark 没掉就可以上线”
量化后 MMLU 没掉,不代表业务可用。生产必须用领域回归集。
4. “校准集越小越快越好”
校准集太小会过拟合或漏掉分布。特别是代码、中文、多模态、长上下文、工具调用都要覆盖。
5. “量化模型就是原模型的低配版”
量化模型是一个新 artifact,应该有自己的:
- 版本;
- 评测报告;
- runtime 依赖;
- checksum;
- 许可证;
- 发布记录;
- 回滚策略。
6. “越低 bit 越先进”
2-bit 或 1.58-bit 很吸引人,但生产价值取决于:
- 质量;
- kernel;
- 硬件;
- 工具链;
- 维护成本;
- 评测覆盖。
极低比特通常需要架构、训练和硬件共同设计,不能简单套用到所有模型。
十五、未来趋势
1. 从 PTQ 走向模型-硬件协同设计
未来的模型可能从训练开始就考虑低比特部署,而不是训练完再压缩。
典型方向:
- FP8 training;
- FP4/NVFP4/MXFP4;
- BitNet / ternary LLM;
- low-bit friendly architecture;
- quantization-aware pretraining。
2. KV Cache 量化会越来越重要
长上下文、Agent、多轮对话和高并发 serving 会让 KV Cache 成本快速上升。只量化权重已经不够。
3. MoE 与多模态量化成为核心难题
新模型越来越多使用 MoE、视觉、音频、视频、工具调用。量化必须理解结构,而不是只扫 Linear 层。
4. 量化格式会继续分裂,然后再收敛
短期内会有更多格式:
- GGUF;
- EXL2;
- GPTQ;
- AWQ;
- FP8 block;
- NVFP4;
- compressed-tensors;
- vendor-specific formats。
长期看,生产会倾向能跨框架、可审计、可复现、可部署的格式。模型仓库会越来越像软件制品仓库。
5. 评测会从“平均准确率”走向“行为稳定性”
量化后的模型可能平均分数接近原模型,但在特定行为上变得不稳定。未来评测会更关注:
- tool call schema;
- long-context faithfulness;
- refusal consistency;
- code execution correctness;
- multi-turn drift;
- RAG citation grounding;
- domain-specific edge cases。
十六、选型备忘录
可以把量化选型压缩成下面这张表。
| 你要解决什么 | 首选方向 | 不建议一开始做什么 |
|---|---|---|
| 本地跑模型 | GGUF + llama.cpp/Ollama | 自己写 kernel |
| 便宜微调 | QLoRA + bitsandbytes + PEFT | 全参数低比特训练 |
| 服务端降显存 | AWQ/GPTQ/FP8 + vLLM | 没评测直接上 3-bit |
| NVIDIA 极致推理 | TensorRT-LLM / FP8 / FP4 | 忽略版本和硬件绑定 |
| CPU 部署 | llama.cpp / Neural Compressor / TorchAO | 假设 GPU 方案可直接迁移 |
| 长上下文 | KV Cache 量化 + LongBench/needle 回归 | 只看短文本 benchmark |
| 多模态 | modality-aware calibration | 只用纯文本校准集 |
| 企业生产 | 量化报告 + 灰度 + 回滚 | 只根据 star 或榜单选工具 |
总结
量化的本质,是在 精度、内存、带宽、计算、硬件、格式和质量 之间做工程交易。
它的发展路径经历了:
信号处理量化
-> 神经网络低比特推理
-> 移动端 INT8
-> LLM weight-only 4-bit
-> QLoRA 低成本微调
-> FP8/FP4 与现代推理系统
-> KV Cache、MoE、多模态和端侧协同量化
现代 LLM 量化不能只看“几 bit”。真正要回答的是:
- 量化对象是什么?
- 算法如何控制误差?
- 格式能否长期维护?
- runtime 是否有高效 kernel?
- 硬件是否真的支持?
- 评测是否覆盖业务失败模式?
- 线上是否能监控和回滚?
当这些问题都能回答时,量化才从“压缩技巧”变成“AI 基础设施”。
参考资料
- Quantization (signal processing), Wikipedia.
- Amir Gholami et al., A Survey of Quantization Methods for Efficient Neural Network Inference, 2021.
- Benoit Jacob et al., Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference, 2017.
- Tim Dettmers et al., LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale, 2022.
- Elias Frantar et al., GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers, 2022.
- Guangxuan Xiao et al., SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models, 2022.
- Tim Dettmers et al., QLoRA: Efficient Finetuning of Quantized LLMs, 2023.
- Ji Lin et al., AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration, 2023.
- Tim Dettmers et al., SpQR: A Sparse-Quantized Representation for Near-Lossless LLM Weight Compression, 2023.
- Wenqi Shao et al., OmniQuant: Omnidirectionally Calibrated Quantization for Large Language Models, 2023.
- PyTorch, TorchAO.
- ggml-org, llama.cpp.
- vLLM Project, vLLM and LLM Compressor.
- Hugging Face, Transformers and Optimum.
- bitsandbytes Foundation, bitsandbytes.
- NVIDIA, TensorRT-LLM.
- Intel, Neural Compressor and AutoRound.