高效推理与压缩(算法侧):解码、投机、量化与 KV

系列精华 · 六篇正文每篇一页,按 ↓ 看误差模型、区间与退化在哪

arganzheng · 2026-05-01

这个系列的一句话主张

每种推理优化都改了成本公式的一项;除投机解码之外每一种都改变了输出分布;而退化是不均匀的——集中在困惑度看不到的地方。

\[\text{一步成本} = \frac{\text{权重} + \text{KV}}{\text{带宽} \times \text{每步 token}} + \text{算力}\]
改哪一项 篇
改解码过程(分母) 01 采样与约束 · 02 投机解码
改权重字节 03 训练后量化 · 04 QAT 与评测
改 KV 字节 05 量化、驱逐、稀疏 attention
改参数数量 06 剪枝、深度缩放、小模型

六篇的全景

%%{init: {"flowchart": {"wrappingWidth": 180}}}%%
flowchart TB
    C["一步 decode 成本<br/>=(权重 + KV + 算力)÷ 产出 token 数"]
    C --> D1["改解码<br/>01 采样与约束"] --> D2["02 投机解码"]
    C --> W3["改权重<br/>03 训练后量化"] --> W4["04 QAT 与低比特评测"]
    C --> K5["改 KV<br/>05 量化、驱逐、稀疏"]
    C --> P6["改结构<br/>06 剪枝、缩放"]
    W4 & P6 -. "恢复靠蒸馏" .-> X["评测:退化在困惑度看不到处"]
    D2 & K5 -.-> X

01 · 解码策略:采样参数本身就在改分布

pass@1 与 pass@k 不能用同一组参数报告

同一个排好序的分布上,top-k、top-p、min-p 三种截断各砍在哪里

数字

量 数
熵对温度的导数 \(dH/dT = \text{Var}(z)/T^3\)
128K 词表尾部总质量 可达 10%;T = 0.7 也许只降到 0.02——低温没有去掉尾部
pass@1 最优温度 ≈ 0.2;pass@100 最优 ≈ 0.8
pass@k 无偏估计 \(1 - \binom{n-c}{k}/\binom{n}{k}\)
高温下 min-p 比 top-p 稳

要点

  • 选择题用约束解码还是自由回答再抽取,可以差好几个点——采样参数是评测协议里最大的一项

常见误区

  • 不先固定采样,后面任何「量化前后差多少」都混进了采样噪声

02 · 投机解码:接受率 = 1 − TV,训草稿就是蒸馏

草稿 γ 步、目标一次前向验证 γ+1 个;拒绝采样严格等于目标分布

投机解码的时间线:草稿自回归 γ 步,目标模型一次前向验证 γ+1 个位置

数字

量 数
期望产出 \(\mathbb E[\text{tokens}] = \frac{1 - \alpha^{\gamma+1}}{1 - \alpha}\),speedup \(= \mathbb E/(\gamma c + 1)\),c ≈ 0.02–0.05
平均接受长度 Medusa 2.5–3 → EAGLE 3.8–4.5 → EAGLE-3 5–6.5
MTP 头(与主模型联合训练) 接受率 85–90%、约 1.8×
树的约束 \(B \cdot N_{tree} \lesssim \text{ridge}\):batch 8 × 64 节点 = 512 已过 H100 的 295

常见误区

  • 「草稿的 argmax 一致率就是接受率」——接受率是两个分布的重叠,argmax 相同形状不同 TV 可以很大
  • typical acceptance 放松验证后,它就掉进后面几篇「改变分布」的范畴

03 · 训练后量化:崩掉几乎总是分布形状

4-bit 快在 decode 慢在 prefill;崩掉来自固定通道离群

INT4 均匀量化:一行权重吸附到 15 个格点;范围 α 取 max 时格点被离群值撑开,取小则离群值被裁剪

误差模型与四种方法

量 数
舍入误差方差 \(\Delta^2/12\):每少 1 bit ×4,INT8 → INT4 ×256
一个 15σ 权重 让 INT4 的 Δ = 2σ——group 内一个离群值毁掉一组
g128 有效 4.156 bit,元数据 4%
输出误差 \(\text{tr}(EHE^\top)\),\(H = \mathbb E[XX^\top]\):误差落在激活大的通道被放大

四种方法

方法 做什么
GPTQ 用 \(H^{-1}\) 把误差补偿到未量化的列
AWQ 保护激活幅度最大的约 1% 通道
SmoothQuant \(\text{diag}(s)\) 把激活的离群迁到权重
旋转(QuaRot) Hadamard 把 1000 摊成约 17;70B W4A4KV4 困惑度 3.32 → 3.73

04 · QAT 与评测:困惑度是平均,任务看关键 token

PPL +0.36 的代价:GSM8K 掉 3–6、needle 掉 10+

STE:前向走 round 的台阶,反向当作 y = x;fp32 主权重被更新,跨过格点时量化值才跳一格

部署前怎么发现

Llama-3-8B W4 变化
困惑度 +0.36
MMLU −1–2
GSM8K −3–6
needle −10 以上
逐 token KL 均值 0.01–0.05 nat;超 0.1 明显——看 P99 不看均值

要点

  • 机制:容易的 token 0.9 → 0.88 贡献 0.02,关键的 token 0.4 → 0.3 或被翻转
  • 敏感层:首尾层、out_proj / down_proj、lm_head、MoE 路由;校准集分布(英文网页上校准在中文与代码上损失更大)

常见误区

  • 「QAT 要从头训」——末段 QAT 用最后 5–10% token 或 SFT 阶段

05 · KV cache 压缩:key 与 value 不一样

key 有通道离群、value 没有——key per-channel、value per-token

三种 KV 驱逐策略在 24 个 token 上各保留哪些:StreamingLLM 留 sink 与窗口,H2O 留累计注意力高的与窗口,SnapKV 按问题选

70B、128K 的一条账

步 KV 大小
BF16,每 token 320 KB 40 GB
FP8(KL 0.001 nat) 20 GB
INT4(元数据 25%,实际 3.2×) 12.5 GB
+ SnapKV 保留 25% 3.1 GB

要点

  • KIVI 2 bit:key per-token 崩掉、per-channel +0.1
  • 约 40K 上下文时 KV 读取超过权重读取——此后 KV 量化的边际收益大于权重量化
  • 驱逐只在问题已知(SnapKV)、只依赖近期(StreamingLLM)或输入冗余大时安全;needle 是试金石

常见误区

  • 训练时稀疏(NSA / MoBA)回到「不变」:模型从来就只看那些块;NSA 64K 下 KV 读取 ÷ 11

06 · 剪枝与深度缩放:赢的是 token 效率不是精度上限

删 25% 层 PPL +0.3、GSM8K 50→10——剪枝必须蒸馏恢复

剪枝的三种粒度:非结构化零散分布、2:4 半结构化、结构化整列删除;越规整硬件越容易兑现

重要性、硬件兑现与小模型配方

量 数
OBS / SparseGPT 重要性 \(w_q^2 / [H^{-1}]_{qq}\)——与 GPTQ 同一个拉格朗日推导
Wanda \(\lvert w_{ij}\rvert \cdot \lVert X_j\rVert\)——与 AWQ 同一个一阶观察
非结构化 50% Tensor Core 不识别零,不变快
2:4 GEMM 1.3–1.8×,只在 compute-bound 有效;decode 字节只到 5/8
Minitron 15B → 8B 94B token 蒸馏 vs 从头 8T,省 40×;比继续预训练高 3–4 MMLU 点

要点

  • 承担 sink 功能的 head 与 retrieval head:校准集激活范数看不出、却不能剪
  • 剪枝后再量化:两种误差相乘不相加——剪后模型对同样 W4 的困惑度增量大 1.5–2 倍
  • Llama 3.2:剪枝做初始化,再用 9T token 蒸馏——压缩成了模型发布的一部分

五条贯穿线

线 落点
分布变了多少 有意改(采样)→ 不变(投机)→ 可控噪声(量化,Δ²/12、逐 token KL)→ 任务依赖(驱逐)→ 改变最大(剪枝);度量从 TV 到 KL 到任务曲线
成本公式的哪一项 投机改分母(≲ ridge);W4A16 改权重字节(止于 memory-bound);KV 量化在 40K 后边际更大;2:4 只在 compute-bound;叠加时消耗同一段余量
离群值与同一套二阶数学 \(\text{tr}(EHE^\top)\):GPTQ = SparseGPT、AWQ = Wanda;通道级离群(LayerNorm γ,6.7B 起相变)与 massive activations(sink)
困惑度 vs 关键 token 每个「无损」都要问在哪个指标、哪类任务、什么协议下
蒸馏,教师 = 自己 训草稿、QAT、剪枝恢复;部署需求提前到训练:MTP 头、厂商 QAT 版、NSA / MLA、剪枝做初始化

常见误区

  • 「评测用 greedy 最公平」——推理模型在 T = 1 下训练,greedy 路径未被训练
  • 「低温已经把尾部去掉了」——温度只改比值不置零;128K 词表尾部 10%
  • 「树越大加速越多」——\(B \cdot N_{tree} \lesssim\) ridge,batch 8 × 64 已过
  • 「INT4 的误差只是 INT8 的两倍」——方差 ×256;一个 15σ 权重让 Δ = 2σ
  • 「W4A16 让高吞吐服务也快 4 倍」——GEMM 仍是 BF16,dequant 是额外算力
  • 「困惑度 +0.1 就是无损」——GSM8K −3–6、needle −10 以上;看 KL 的 P99
  • 「key 与 value 用同一种粒度」——key per-channel、value per-token
  • 「注意力低的 KV 可以安全驱逐」——needle 在被读到时就是「不重要」的
  • 「50% 非结构化稀疏快一倍」——只有 2:4 被硬件兑现
  • 「删层后 MMLU 不掉就是无损」——GSM8K 50 → 10;多选只要「大致对」

六个出口

篇 一个公式 / 一个数
01 pass@1 最优 T ≈ 0.2、pass@100 ≈ 0.8;模型卡 T = 0.6 / top-p 0.95
02 \(\alpha = 1 - \text{TV}\);\(\mathbb E = (1-\alpha^{\gamma+1})/(1-\alpha)\);\(B \cdot N_{tree} \lesssim\) ridge
03 \(\Delta^2/12\);\(\text{tr}(EHE^\top)\);Hadamard 1000 → 17
04 STE \(\hat w = w + \text{sg}(Q(w) - w)\);PPL +0.36 ↔ needle −10
05 70B 128K:40 → 20 → 12.5 → 3.1 GB;sink 吃 30–50%
06 \(w_q^2/[H^{-1}]_{qq}\);2:4 1.3–1.8×;Minitron 省 40×

下一步

  • 往前:《现代 LLM 结构》第 02、08 篇——Roofline 与投机解码的第一次出现;量化见独立专题
  • 往后(Infra):《vLLM 源码》——这些方法在引擎里的落点:采样器、投机 worker、量化 kernel、分页 KV
  • 往后(算法):《后训练》第 7 篇——蒸馏的方法本身
  • 原文总纲:/efficient-inference-and-compression-for-llms.html;通关自测 22 题在系列总结
← Arganzheng's Blog