模型量化原理:从单个权重到逐层推理

A visual guide · 2026

模型量化,
究竟量化了什么?

从一个权重的舍入误差,走到 Transformer 的每一层、推理内核和显存账本。

INT8 · FP8 · W4A16 · W8A8 · Q3_K · KV Cache
浮点权重到量化权重再到推理计算W · ORIGINAL WEIGHTS+0.81−0.42+1.73+8.20GROUP SCALE + LOW-BIT CODESs = 1.17[ 1, 0, 1, 7 ]kernel: x × dequant(Wq)
分组决定 scale 的作用范围;离群值会挤压其他数的刻度。

量化是一次有损编码:把高精度张量映射到更少的可表示数值,同时尽量保持模型的输出行为。它首先是数值近似问题,然后才是文件压缩和内核加速问题。

01 / WEIGHTS权重 W

模型训练后固定的参数。压缩它,直接降低常驻权重的存储需求。

02 / ACTIVATIONS激活 A

推理时随输入产生的中间数。压缩它,才能使用部分低精度矩阵乘法路径。

03 / KV CACHE注意力历史

每个请求累积的 Key 和 Value。长度与并发增长时,它可能成为另一笔显存大头。

01 / THE NUMBER

一个浮点数如何变成低位整数

先看最简单的对称、按组量化。它是理解 GPTQ、AWQ 和 GGUF 块量化的起点。

对于一组浮点权重,选一个缩放因子 s。每个权重 w 被映射成有限范围内的整数 q;需要用它计算时,再得到近似值 ŵ。例如 INT4 的对称表示可使用 −7 到 +7 的 15 个量化级别。这里采用这个约定来做交互演示,实际格式的取值范围可能不同。

SYMMETRIC QUANTIZATION
s = max(|wᵢ|) / (2⁽ᵇ⁻¹⁾ − 1)
qᵢ = clip(round(wᵢ / s), −qmax, qmax)
ŵᵢ = s · qᵢb 是编码位数。非对称量化还会引入 zero-point;不同方法可使用更复杂的缩放和误差补偿。

位数越低,可选刻度越少;同组若出现极大的离群值,它会拉大 s,使其他小权重更容易被舍入到同一刻度。缩小分组有时能缓解这个问题,但每组都要额外保存 scale。

试着改动位数与分组

平均平方误差
有效编码位数
离群值所在组 scale
原值量化还原值
序号−9 ← 数值轴 → +9原值还原scale

橙色行是离群值。这个示例只演示最简单的舍入;真实 GPTQ/AWQ 会利用样本统计进一步控制误差。有效位数计入每组一个 16 bit scale,不含其他元数据。

WHAT WE REALLY CARE ABOUT
目标:尽量减小 ‖W·X − Ŵ·X‖单个权重误差 |W−Ŵ| 很小,也不代表乘上实际输入 X 后的输出误差一定小。
02 / THE LAYER

同一层里,并非每个张量都用同一种精度

以一个典型的 GQA + SwiGLU 解码层为例。具体模型还需看实际 config 和张量清单。

Attention 的矩阵

  • Query 投影Wq
  • Key 投影Wk
  • Value 投影Wv
  • 输出投影Wo

这些矩阵是权重量化的主要对象;K/V 投影的输出还会写入 KV Cache。

MLP 的矩阵

  • 门控投影Wgate
  • 上投影Wup
  • 下投影Wdown

宽大的 MLP 常占一层权重的多数。MoE 模型还要分别考虑每个 expert 的这些矩阵。

其他运算与张量

  • 词向量表Embed
  • 归一化Norm
  • 残差与 softmaxOps
  • 最终输出头lm_head

敏感层可能保留 BF16/FP16;是否量化取决于实际 checkpoint 与后端。

  1. 选量化对象:可能只量化线性层权重,也可能同时量化输入激活;KV Cache 是独立开关。
  2. 选粒度:每张量、每通道、每组或每块。粒度越细,通常越能贴合数值分布,但 scale 和计算开销会增加。
  3. 选精度:敏感的层、输出头或部分通道可保留更高精度。因此“4 bit 模型”常是主体权重约 4 bit,而非每个参数都严格 4 bit。
03 / THE METHODS

算法在解决哪一种误差

“INT4”是目标格式;“GPTQ / AWQ”回答的是怎样把原模型变成这个格式。

BASELINE

RTN

直接四舍五入到最近的刻度。无需校准样本,成本低;很低位数时容易损伤敏感权重。

WEIGHT ONLY

GPTQ

观察校准输入,逐步量化权重并补偿其余权重,目标是减小层输出误差。[1]

WEIGHT ONLY

AWQ

依据激活分布找出敏感权重通道,用等价缩放保护它们。[2]

WEIGHT + ACTIVATION

SmoothQuant

针对难量化的激活离群值,把部分量化难度转移到权重,服务于 INT8 W8A8。[3]

INT8 与 FP8 的区别:它们都是 8 bit,但编码方式不同。INT8 用整数级别配合 scale;FP8 把位数分给符号、指数和尾数,也通常结合 scale。两者对极端数值、误差和硬件的要求不同。[4]

GGUF 的 Q3_K:它是另一套权重块编码命名。单个 Q3_K 256 权重块有 3 bit 权重编码及分级 scale,合计约 3.4375 bit/权重;`Q3_K_M` 是模型级混合档位,平均位数还会更高。[5]

04 / THE KERNEL

压缩权重如何参与一次推理

磁盘格式、显存中的布局、算子实际使用的数据类型,是三个不同层次。

LOAD读取压缩权重加载 packed codes、scale、必要的 zero-point;某些后端可能重排布局。
PREFILL / DECODE准备当前激活W4A16 保留 16 bit 激活;W8A8 将当前激活转换为 8 bit。
GEMM低精度矩阵乘法内核边解包/缩放边计算,或直接用 INT8/FP8 硬件路径。
STATE写入 K/VKV Cache 精度单独配置,随 token 和并发累积。

仅权重量化不意味着推理时把整份权重永久还原成 BF16;高效内核通常在计算过程中处理编码和 scale。不过,解包和转换有代价,因此文件更小不保证每个 batch 都更快。W8A8 则有机会直接使用低精度矩阵乘法硬件,实际收益取决于芯片、形状、batch 与内核。[6]

THREE INDEPENDENT SWITCHES
W4A16 ≠ FP8 KV Cache ≠ W8A8W/A 描述权重与激活;KV 描述历史注意力状态。三者可以组合,但要分别确认框架支持。
05 / THE MEMORY

文件大小和显存,要分开算

先估权重,再估 KV,最后给运行时工作区留空间。

A权重编码

参数数 × 有效 bits/8;按每个张量实际精度求和。

B元数据

scale、zero-point、混合精度张量和对齐。

CKV Cache

层数、上下文、并发、KV heads、head_dim 与 KV dtype。

D运行时开销

激活、内核工作区、通信 buffer、图捕获和分配器。

CAPACITY ESTIMATES
权重 ≈ Σ(张量参数数 × 有效 bits/8)
KV ≈ 2 × L × T × B × Hkv × Dh × 元素字节
显存 ≈ 权重 + 已分配 KV + 临时激活/工作区 + 运行时KV 公式适用于普通全注意力/GQA 的基础估算;滑动窗口、MLA、分页块、scale 与张量并行会改变实际分配。

约 8B 参数:只看权重

14.90 → 3.84 GiB

理论示例:全模型 BF16 约 14.90 GiB;若全部按 INT4、每 128 权重一个 FP16 scale,约 3.84 GiB。实际还可能保留高精度张量、存 zero-point 或额外布局。

32 层 GQA:单请求 8K token

1.00 → 0.50 GiB

假设 8 个 KV heads、head_dim 128:BF16 KV 的数据主体 1 GiB;FP8 的数据主体约 0.5 GiB。16 个同长度请求,主体约为 16 / 8 GiB,未计额外开销。

一个实测参照:llama.cpp 给出的 Llama 3.1 8B 文件大小约为 F16 14.96 GiBQ4_K_M 4.58 GiB。这只是模型文件口径,不能直接当成加载后的总显存。vLLM 等服务框架还可能预分配 KV Cache,使“启动后已占用显存”大于当下请求真正使用的 KV 数据。[7][8]

06 / REFERENCES

资料与口径

公式中的容量例子是按明确假设推导的教学示例;量化算法、格式和运行时描述依据下列原始论文或项目文档。

  1. [1] Frantar et al., GPTQ: Accurate Post-Training Quantization, 2022.
  2. [2] Lin et al., AWQ: Activation-aware Weight Quantization, 2023.
  3. [3] Xiao et al., SmoothQuant, 2022.
  4. [4] vLLM Project, LLM Compressor: Compression Schemes.
  5. [5] llama.cpp, Tensor Encoding Schemes.
  6. [6] vLLM Project, Choosing the Right Compression Scheme.
  7. [7] llama.cpp, Quantization README, model-size table.
  8. [8] vLLM Project, KV Cache configuration.