第 2 章:KV Cache 全景:从注意力瓶颈到系统级优化¶
推理阶段,模型参数是固定成本,KV Cache 是可变成本。你能服务多少用户、支撑多长上下文、维持多低延迟,归根结底取决于你怎么管理这块不断膨胀的缓存。[14][15]
本章从 Transformer 注意力机制的数学本质出发,逐层展开 KV Cache 的产生原因、内存代价、所有优化路径与生产系统方案。目标是让你读完后,面对任何 KV Cache 相关的技术选型都能给出有依据的判断。
你将收获什么¶
- 一套完整的 KV Cache 心智模型:从注意力公式到内存公式,理解为什么 KV Cache 是推理的核心瓶颈。
- 一张优化全景图:架构级、Token 级、系统级三层分类,覆盖 2022–2025 年所有主流方案。
- 每种方案的适用条件与代价:不只讲原理,还讲什么时候该用、什么时候不该用。
- 生产级系统设计参考:从 PagedAttention 到 Disaggregated Serving,从前缀缓存到 KV-Aware 调度。
1 为什么需要 KV Cache:从注意力机制说起¶
1.1 自回归生成的本质¶
大语言模型的文本生成是自回归的(autoregressive):每次只生成一个 token,且每个新 token 的生成都依赖所有已有 token。具体来说,对于第 $t$ 步生成,模型需要计算新 token 对序列中所有 $1 \dots t$ 个 token 的注意力权重。[14]
在 Multi-Head Self-Attention(MHSA)中,每一层对输入 $X$ 做如下计算:
Q = X · W_Q (Query 投影)
K = X · W_K (Key 投影)
V = X · W_V (Value 投影)
Attention(Q, K, V) = softmax(Q · K^T / √d_k) · V
关键观察:Q 只需要当前 token,但 K 和 V 需要整个序列。每生成一个新 token,如果不做缓存,就要把前面所有 token 的 K 和 V 全部重新计算一遍。这个重复计算的开销随序列长度线性增长——对于 128K 上下文的模型,这意味着每个新 token 都要重算 128K 个 token 的 K/V 投影。[14][15]
1.2 KV Cache 的作用¶
KV Cache 的核心思想极其简单:把每一层已经算过的 K 和 V 张量存下来,下一步直接复用。
第 1 步:计算 K_1, V_1 → 存入缓存
第 2 步:计算 K_2, V_2 → 追加到缓存 → 用 [K_1, K_2] 和 [V_1, V_2] 算 attention
第 3 步:计算 K_3, V_3 → 追加到缓存 → 用 [K_1, K_2, K_3] 和 [V_1, V_2, V_3] 算 attention
...
第 t 步:只计算 K_t, V_t → 追加 → 用完整缓存 [K_1..K_t], [V_1..V_t] 算 attention
这样每步只需计算一个 token 的 Q、K、V 投影,而非整个序列。时间复杂度从 $O(t^2)$ 降至 $O(t)$,加速效果在长序列上极其显著。[14]
1.3 两阶段推理¶
有了 KV Cache,推理过程自然分为两个阶段:[15][16]
| 阶段 | 做什么 | 瓶颈 | 特征 |
|---|---|---|---|
| Prefill(预填充) | 并行处理整个输入 prompt,为所有 token 计算并缓存 K/V | 计算密集 | GPU 算力利用率高,批量矩阵乘 |
| Decode(解码) | 逐 token 生成,每步追加一对 K/V 到缓存 | 访存密集 | 每步只做一个 token 的计算,但要加载整个 KV Cache |
Decode 阶段是访存瓶颈(memory-bandwidth-bound)的根本原因:每生成一个 token,GPU 都要从显存中加载全部 KV Cache 来计算注意力,但实际的计算量很小。GPU 的算力大部分时间在等数据搬运。这就是为什么 KV Cache 的大小直接决定了推理的吞吐和延迟。[15]
2 KV Cache 的内存代价:算清这笔账¶
2.1 内存公式¶
每个 token 的 KV Cache 大小(字节):
KV_per_token = 2 × n_layers × n_kv_heads × d_head × bytes_per_element
其中:
2= Key + Value 两个张量n_layers= Transformer 层数n_kv_heads= KV 注意力头数(MHA 时等于n_heads,GQA/MQA 时更少)d_head= 每个头的维度bytes_per_element= FP16/BF16 为 2,FP8/INT8 为 1,INT4 为 0.5
总 KV Cache 大小:
Total_KV = batch_size × sequence_length × KV_per_token
2.2 真实模型的内存开销¶
| 模型 | 层数 | KV 头数 | d_head | 注意力结构 | 每 token KV (FP16) | 4K 上下文 × batch 8 |
|---|---|---|---|---|---|---|
| LLaMA-2 7B | 32 | 32 | 128 | MHA | 0.5 MB | 16 GB |
| LLaMA-2 13B | 40 | 40 | 128 | MHA | 0.8 MB | 25 GB |
| LLaMA-2 70B | 80 | 8 | 128 | GQA-8 | 0.33 MB | 10 GB |
| LLaMA-3 8B | 32 | 8 | 128 | GQA-8 | 0.13 MB | 4 GB |
| LLaMA-3 70B | 80 | 8 | 128 | GQA-8 | 0.33 MB | 10 GB |
| Qwen3 Next | 64 | 4 (混合) | 128 | Hybrid-GQA | 0.065 MB | 2 GB |
| DeepSeek-V3.2 671B | 61 | 隐向量维度 512 | - | MLA (低秩) | 0.03 MB (FP8) | 1 GB |
以 LLaMA-2 7B 为例手算:
KV_per_token = 2 × 32 × 32 × 128 × 2 = 524,288 字节 ≈ 0.5 MB
4096 tokens × batch 8 = 0.5 MB × 4096 × 8 = 16 GB
这意味着 KV Cache 的内存开销可以接近甚至超过模型参数本身。LLaMA-2 13B 的参数大小约 26 GB(FP16),而 batch 8、4K 上下文的 KV Cache 就要 25 GB。[15][16]
Qwen3 Next 的特殊 KV Cache 计算:
Qwen3 Next 采用了混合 GQA(Hybrid-GQA)架构,不同层使用不同的 KV 头数配置以平衡质量和效率:
# 假设 64 层模型的配置示例
前 16 层:每层 8 个 KV 头 (高精度理解层)
中 32 层:每层 4 个 KV 头 (平衡处理层)
后 16 层:每层 2 个 KV 头 (高效生成层)
# 计算平均 KV 头数
avg_kv_heads = (16×8 + 32×4 + 16×2) / 64 = (128 + 128 + 32) / 64 = 4.5 头
# 每 token KV Cache(取平均)
KV_per_token = 2 × 64 × 4.5 × 128 × 2 ≈ 0.07 MB
# 4K 上下文 × batch 8
Total_KV = 0.07 MB × 4096 × 8 ≈ 2.3 GB
这种分层设计使得 Qwen3 Next 在保持接近全 GQA-8 质量的同时,KV Cache 开销降低约 50%。
2.3 长上下文时代的挑战¶
当上下文窗口扩展到 128K 甚至更长时,KV Cache 的内存问题变得更加严峻:
- LLaMA-3 70B(128K 上下文,batch 1):0.33 MB × 128K ≈ 40 GB 仅用于 KV Cache
- 百万 token 上下文的 70B 模型:KV Cache 需要 ~320 GB,远超任何单块 GPU 的显存
这就是为什么 KV Cache 优化不是锦上添花,而是能不能跑起来的问题。[14][16]
3 优化全景图¶
KV Cache 的优化可以从三个层次切入,每个层次有不同的代价和效果:
KV Cache 优化
│
├── 架构级(需要训练/重训)
│ ├── MQA / GQA / MLA / TPA ← 改变注意力头结构
│ ├── 滑动窗口注意力 ← 限制注意力范围
│ └── 跨层 KV 共享 ← 减少需要缓存的层数
│
├── Token 级(训练后优化,多数免训练)
│ ├── Token 驱逐:H2O / SnapKV ← 丢弃不重要的 token
│ ├── Token 合并:CaM / D2O ← 合并而非丢弃
│ ├── 量化:KIVI / NVFP4 ← 降低每个值的精度
│ ├── 低秩分解:PALU ← 压缩投影矩阵
│ └── 流式推理:StreamingLLM ← 固定缓存窗口 + 注意力锚点
│
└── 系统级
├── 内存管理:PagedAttention ← 分页式内存分配
├── 调度:连续批处理 / KV 感知路由 ← 请求级调度
├── 计算拆分:Prefill-Decode 分离 ← 异构硬件匹配
├── 存储分层:GPU→CPU→磁盘卸载 ← 多级存储
├── 前缀缓存:RadixAttention ← 共享前缀复用
└── 投机解码:MagicDec ← 利用稀疏 KV 做草稿
下面逐一展开。
4 架构级优化:从注意力头结构入手¶
架构级优化通过改变模型的注意力结构来减少需要缓存的 KV 数量。这些方案需要在训练时就决定,但效果最为根本。
4.1 MQA:极致共享的起点¶
论文: Multi-Query Attention (Shazeer, 2019) [17]
标准 MHA 中,每个 Query 头都有对应的 K 和 V 头。MQA 的做法是:所有 Query 头共享同一组 K 和 V。
MHA:H 个 Query 头 × H 个 Key 头 × H 个 Value 头
MQA:H 个 Query 头 × 1 个 Key 头 × 1 个 Value 头
KV Cache 缩小 H 倍(例如 32 头模型缩小 32 倍),推理时间可降至 MHA 的约 1/6。[17]
代价: 质量有明显下降。一个 KV 头要服务所有 Query 头,表达能力受限。这就是 GQA 出现的动机。
4.2 GQA:速度与质量的折中¶
论文: Ainslie et al., EMNLP 2023 [13]
GQA 将 Query 头分成 G 组,每组共享一个 KV 头:
MHA:G = H (每个 Query 头独享 KV)
MQA:G = 1 (所有 Query 头共享一个 KV)
GQA:1 < G < H (折中,典型值 G = 8)
用原始预训练计算量的 5% 做 uptraining,就能将 MHA 模型转换为 GQA,获得接近 MQA 的速度和接近 MHA 的质量。[13]
采用情况: LLaMA 2/3(Meta)、Mistral 7B、Gemma(Google)、Granite 3.0(IBM)等主流模型均使用 GQA。可以说 GQA 已经成为 2024 年后新模型的默认选项。[13]
4.3 MLA:DeepSeek 的低秩压缩方案¶
论文: DeepSeek-V2, 2024 [18]
Multi-Head Latent Attention(MLA)是 DeepSeek 提出的注意力机制,核心思想是不缓存完整的 K 和 V,而是缓存一个低维隐向量,需要时再解压:
c_t = W_DKV · x_t (输入 → 低维隐向量,维度 d_c)
K_t = W_UK · c_t (隐向量 → 解压为 Key)
V_t = W_UV · c_t (隐向量 → 解压为 Value)
缓存中只存 $c_t$(低维隐向量),而非完整的 K 和 V。
RoPE 处理: 位置编码(RoPE)无法直接与低秩压缩兼容,MLA 引入解耦 RoPE,用独立路径处理位置信息:
k_t^R = RoPE(W_KR · x_t) (独立的位置 Key)
q_t^R = RoPE(W_QR · c_t^Q) (独立的位置 Query)
DeepSeek-V3 的实际数据: [19]
- 每头维度 128,128 个注意力头,隐向量维度 512
- 标准 MHA 每层每 token 需缓存 128 × 128 × 2 = 32,768 个值
- MLA 每层每 token 只需缓存 512 个值
- KV Cache 缩减 93.3%(DeepSeek-V2 67B 从 213.5 GB 降至 7.6 GB)
- 最大生成吞吐提升 5.76 倍
- 模型质量不仅没有下降,反而优于标准 MHA
DeepSeek-V3.2 的 KV Cache 详细计算:
DeepSeek-V3.2(671B 参数)进一步优化了 MLA 的实现:
模型配置:
- 总层数:61 层
- 注意力头数:128 头
- 每头维度:128
- 隐向量维度(d_c):512
- MoE 专家数:256(每 token 激活 8 个)
- 精度:FP8(混合精度)
标准 MHA 的 KV Cache(假设):
KV_per_token = 2 × 61 × 128 × 128 × 2 = 3,145,728 字节 ≈ 3 MB/token
MLA 的 KV Cache(实际):
KV_per_token = 61 × 512 × 1 (FP8) = 31,232 字节 ≈ 0.03 MB/token
压缩比 = 3 MB / 0.03 MB ≈ 100 倍
实际显存占用示例:
- 128K 上下文,batch 1:0.03 MB × 128K ≈ 3.84 GB
- 相同配置下标准 MHA 需要:3 MB × 128K ≈ 384 GB
额外优化:
- V3.2 引入了 RoPE 缓存共享:位置编码的 Key(k^R)在多个请求间共享
- 使用 FP8 混合精度:隐向量用 FP8 存储,进一步减少 50% 内存
- 最终 KV Cache 压缩率达到标准 MHA 的 **1/200**
V3.2 的 Multi-Token Prediction(MTP)影响:
DeepSeek-V3.2 支持多 token 预测(MTP),这对 KV Cache 有特殊影响:
# 传统自回归:每步预测 1 个 token
Step 1: 缓存增加 1 × 0.03 MB = 0.03 MB
Step 2: 缓存增加 1 × 0.03 MB = 0.03 MB
...
# MTP 模式:每步预测 N 个 token(如 N=4)
Step 1: 并行预测 4 个 token,但只缓存主预测分支的 KV
缓存增加:1 × 0.03 MB = 0.03 MB(而非 4 × 0.03 MB)
# MTP 通过共享 KV Cache 实现加速,不增加额外显存
吞吐提升:约 3-4 倍(4 token prediction)
KV Cache 增长率:与单 token 模式相同
MLA 是目前 KV Cache 压缩最激进且效果最好的架构级方案,DeepSeek-V3.2 的优化使其成为超大规模模型部署的标杆。[18][19]
4.4 TPA:张量积注意力¶
论文: Zhang et al., NeurIPS 2025 Spotlight [20]
Tensor Product Attention(TPA)使用张量分解将 Q、K、V 分解为低秩的上下文相关分量。与 MLA 不同,TPA 天然兼容 RoPE,无需解耦设计,可以直接替换 LLaMA、Qwen、Gemma 等架构中的 MHA。
TPA 的 KV Cache 缩减约一个数量级,且 FlashTPA 解码内核在长序列场景下比优化过的 MHA、MQA、GQA、MLA 都更快。[20]
4.5 滑动窗口注意力¶
代表: Mistral 7B [21]
每个 token 只关注最近 W 个 token(窗口大小),KV Cache 固定为 W × 每 token 大小,与序列总长度无关。
代价: 早期 token 的信息只能通过中间 token 逐层传播,无法直接访问。对需要远距离依赖的任务(如长文档问答)有质量损失。
4.6 跨层 KV 共享¶
代表: LCKV (ACL 2024) [22]、CLA (MIT, 2024) [23]、YOCO [24]
核心思想:不是每一层都需要独立的 KV。可以只在部分层计算 KV,其余层复用:
- LCKV: 只在顶层计算 KV,所有其他层的 Query 都与顶层 KV 做注意力。除顶层外,所有层的 KV 参数都可以丢弃。[22]
- CLA: 相邻层共享 KV 激活值。在 accuracy/memory 的帕累托前沿上优于 GQA。[23]
- YOCO: 使用跨解码器(Cross-Decoder)的交叉注意力,全局只存一份 KV。[24]
这些方案可以与 GQA/MQA 正交叠加,进一步压缩 KV Cache。
5 Token 级优化:训练后的精细手术¶
Token 级优化不改变模型架构,而是在推理时动态决定缓存中保留哪些 token、以什么精度保留。大多数方案免训练,即插即用。
5.1 Token 驱逐策略:只保留重要的¶
核心问题:注意力并非均匀分布。大量 token 对最终输出的贡献极小,可以安全丢弃。
H2O(Heavy-Hitter Oracle): [25]
保留两类 token:累计注意力分数最高的"重击手"(Heavy Hitter)+ 最近的 token。将 KV Cache 大小控制在固定预算内。形式化为动态子模优化问题。
SnapKV(2024): [26]
免训练方案。通过一个观测窗口(observation window)识别每个注意力头中的重要 token 位置,然后聚类保留这些 KV 条目。
- 16K 输入:生成速度提升 3.6 倍,内存降低 8.2 倍
- 单块 80 GB GPU 上可处理 380K token 的输入
HashEvict(2024): [27]
在注意力计算之前就做驱逐决策,使用局部敏感哈希(Locality-Sensitive Hashing)快速判断 token 重要性,避免了驱逐决策本身的计算开销。
预算分配策略:
- PyramidKV: 低层分配更大预算(金字塔调度),因为低层的注意力更分散。[28]
- Ada-KV(NeurIPS 2025): 自适应的逐头预算分配,不同头根据信息密度获得不同缓存配额。[29]
5.2 Token 合并:不丢弃,而是融合¶
驱逐策略的问题是信息丢失不可逆。合并策略将被驱逐 token 的信息融合到保留 token 中:
- CaM(Cache Merging): 用注意力分数作为权重,将待驱逐 token 的 KV 加权合并到保留 token 中。[30]
- D2O: 使用指数移动平均(EMA)阈值和余弦相似度做加权 Key 合并。[31]
- KVMerger: 利用 Key 状态的高 token 级相似性做自适应合并。[32]
5.3 KV Cache 量化:降低每个值的精度¶
与模型权重量化不同,KV Cache 量化面临独特挑战:Key 和 Value 的数值分布特征完全不同,需要不对称的量化策略。
KIVI(ICML 2024): [33]
KIVI 发现了一个关键现象:
- Key 在通道维度上存在显著异常值(outlier),必须按通道量化(per-channel)
- Value 作为注意力的"混合器",逐 token 量化误差更可控,应按 token 量化(per-token)
用这种不对称策略,KIVI 实现了 2-bit KV Cache 量化,且无需微调:
- 峰值内存降低 2.6 倍
- 吞吐提升 2.35–3.47 倍
| 量化方案 | 精度 | 策略 | KV Cache 缩减 | 质量损失 |
|---|---|---|---|---|
| FP8 E4M3 | 8-bit | Per-tensor / per-channel | 2× | 极小 |
| INT8 | 8-bit | Per-head, per-token 非对称 | 2× | 可忽略 |
| KIVI | 2-bit | Key per-channel, Value per-token | 4× | 小 |
| NVFP4 | 4-bit | NVIDIA 硬件加速 | 4×(相对 FP8 为 2×) | 基准测试 <1% |
NVFP4(2025): [34] NVIDIA 在 Blackwell 架构上提供硬件级 4-bit KV Cache 支持,代表了硬件与算法协同设计的趋势。
5.4 低秩分解:PALU¶
论文: PALU, ICLR 2025 [35]
PALU 对 K/V 投影层做截断感知的 SVD 分解。缓存中只存压缩后的中间状态,推理时在线重构完整 K/V。
- 50% KV 压缩 → 最高 1.89 倍加速
- 结合量化 → 最高 2.91 倍加速
与量化正交,两者可以叠加使用。[35]
5.5 StreamingLLM:无限长度的流式推理¶
论文: Xiao et al., ICLR 2024 [36]
StreamingLLM 的核心发现是注意力锚点(Attention Sink)现象:LLM 会将大量注意力权重分配给序列最前面的几个 token,无论这些 token 的语义内容是什么。这是因为 softmax 要求权重求和为 1——模型需要一个"垃圾桶"来放置多余的注意力概率质量,最前面的 token 就充当了这个角色。[36]
基于这个发现,StreamingLLM 的 KV Cache 设计为两部分:
[注意力锚点:前 4 个 token] + [滚动窗口:最近 N 个 token]
- 支持 400 万+ token 的稳定生成
- 内存恒定,与生成长度无关
- 100K token 时:完整缓存需要 7 GB,StreamingLLM 只需 145 MB
- 相比滑动窗口重计算,加速 22.2 倍
- 适用于 LLaMA-2、MPT、Falcon、Pythia,无需微调
局限: 滚动窗口之外的中间内容完全丢失。StreamingLLM 适合流式对话、实时摘要等不需要回溯远处信息的场景,不适合长文档精确问答。[36]
6 系统级优化:内存管理、调度与架构¶
系统级优化不改变模型本身,而是从推理引擎和集群架构层面提升 KV Cache 的利用效率。
6.1 PagedAttention:操作系统式的内存管理¶
论文: Kwon et al., SOSP 2023 [10]
传统推理引擎为每个请求预分配一段连续的 GPU 显存来存放 KV Cache。问题在于:
- 预分配浪费: 不知道序列会多长,只能按最大长度预分配,导致 60%–80% 的显存浪费
- 碎片化: 不同请求的序列长度不同,释放后留下大量碎片
- 无法共享: 多个请求的共同前缀(如系统 prompt)各自缓存,冗余严重
PagedAttention 借鉴操作系统虚拟内存的分页机制:
逻辑块(模型看到的连续 KV) ←→ 物理块(GPU 显存中的实际位置)
↕
页表(Block Table)映射
- KV Cache 被切分为固定大小的块(默认 16 token/块)
- 物理块可以不连续存放,通过页表映射
- 内存浪费仅发生在最后一个块,不到 4%
- Copy-on-Write(CoW):多个请求共享前缀时,KV 块可以安全共享,只在修改时复制
性能: 相比 HuggingFace Transformers 最高 24 倍吞吐提升,相比传统批量推理 2 倍提升。[10]
6.2 连续批处理(Continuous Batching)¶
论文: Orca, OSDI 2022 [37]
传统静态批处理(static batching)等整个 batch 中最长的请求完成后才开始下一个 batch。连续批处理的改进:
- 迭代级调度: 每个解码步都可以插入新请求或释放已完成请求
- 短序列不再需要等长序列完成
- GPU 利用率大幅提升
连续批处理是所有现代推理引擎(vLLM、TGI、SGLang、TensorRT-LLM)的标配。[37]
6.3 Prefill-Decode 分离(Disaggregated Serving)¶
Prefill 是计算密集型,Decode 是访存密集型——两者对硬件的需求截然不同。Disaggregated Serving 将它们拆分到不同的 GPU 池:[38][39]
DistServe(2024): [38]
- 预填充和解码分别在独立的 GPU 集群上运行
- 吞吐提升 4.48 倍,延迟方差降低 20 倍
- 同样硬件下可服务 7.4 倍的请求量
Splitwise(2024): [39]
- 异构硬件:H100 做 Prefill,A100 做 Decode
- 相同预算下吞吐提升 2.35 倍,或相同吞吐下成本降低 20%
Mooncake(2024): [40]
KVCache-centric 架构,通过 RDMA 在 Prefill 节点和 Decode 节点之间高速传输 KV Cache。
截至 2025 年,几乎所有生产级框架都支持 Disaggregated Serving:NVIDIA Dynamo、llm-d、Ray Serve、SGLang、vLLM、LMCache。[41]
6.4 前缀缓存(Prefix Caching)¶
当大量请求共享相同前缀(如系统 prompt、few-shot 示例)时,重复计算这些前缀的 KV 是巨大的浪费。
RadixAttention(SGLang, NeurIPS 2024): [42]
使用基数树(Radix Tree)数据结构存储和检索共享前缀的 KV Cache。多个请求自动共享已计算的 KV 状态,避免冗余计算。
- 自动检测和利用前缀共享
- 吞吐提升可达 5 倍
LMCache + vLLM: [43]
企业级 KV Cache 共享层:
- CacheGen(SIGCOMM 2024): 将 KV Cache 编码为压缩比特流存入磁盘 [44]
- CacheBlend(EuroSys 2025): 动态组合多个 KV Cache [45]
- 跨实例共享,支持 GPU → CPU → 磁盘 → Redis 多级存储
- 全链路吞吐提升可达 15 倍
6.5 KV Cache 卸载(Offloading)¶
当 GPU 显存装不下 KV Cache 时,可以将部分数据卸载到 CPU 内存甚至磁盘:
FlexGen(2023): [46]
GPU → CPU → 磁盘三级存储分层。在 OPT-175B 上用 GPU batch 32 实现了 69 倍吞吐提升。
InfiniGen(OSDI 2024): [47]
将 KV Cache 卸载到 CPU,但使用上一层的注意力分数作为"预测器",投机预取(speculative prefetch)下一层可能需要的 KV 条目。只加载 1%–3% 的缓存数据就能维持完整精度,加速可达 5.28 倍。[47]
6.6 KV-Aware 调度与路由¶
在多 GPU 集群中,将请求路由到已经持有相关 KV Cache 的节点可以避免重新计算:
NVIDIA Dynamo(GTC 2025): [48]
- 使用 Radix Tree 在整个 GPU 集群中追踪 KV Cache 分布
- Smart Router 将请求路由到持有匹配前缀的节点
- DeepSeek-R1 吞吐提升 30 倍
6.7 与投机解码的协同¶
KV Cache 不仅是被优化的对象,也影响投机解码的策略选择:
MagicDec(ICLR 2025): [49]
关键洞察:在高吞吐场景下(大 batch),推理瓶颈从加载模型参数转移到加载 KV Cache。MagicDec 的做法是:
- 草稿模型使用 StreamingLLM 风格的稀疏 KV Cache(固定窗口 + 注意力锚点)
- 目标模型使用完整 KV Cache 验证
- 草稿 KV Cache 大小固定,不随序列增长
- LLaMA-3.1-8B 在 batch 32–256 下加速达 2.51 倍
7 方案选型指南:什么场景用什么方案¶
7.1 决策矩阵¶
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 新模型训练 | GQA(保守)或 MLA(激进) | 从源头减少 KV;GQA 生态成熟,MLA 压缩率更高 |
| 已有 MHA 模型提速 | GQA uptraining(5% 算力) | 最低成本的架构级改造 [13] |
| 长上下文推理(>32K) | SnapKV + 量化 + PagedAttention | 三者叠加,分别解决 token 数、精度、碎片问题 |
| 流式对话/实时场景 | StreamingLLM | 固定内存,无限长度 [36] |
| 高并发在线服务 | PagedAttention + Continuous Batching + Prefix Caching | 系统级三件套 [10][37][42] |
| 超大模型单卡部署 | KV 量化(KIVI/NVFP4)+ 卸载(InfiniGen) | 同时压缩和分层存储 [33][47] |
| 集群级部署 | Disaggregated Serving + KV-Aware Routing | 充分利用异构硬件和分布式 KV [38][48] |
| 投机解码 + 大 batch | MagicDec | 稀疏 KV 草稿避免 KV 搬运瓶颈 [49] |
7.2 叠加原则¶
多数优化方案可以正交叠加。典型的生产级优化栈:
架构级:GQA-8(模型选型时确定)
↓
量化层:FP8 或 INT8 KV Cache(2× 缩减)
↓
系统层:PagedAttention + Continuous Batching(消除碎片和等待)
↓
缓存层:Prefix Caching(共享前缀复用)
↓
调度层:Disaggregated Serving + KV-Aware Routing(集群效率)
从上到下,每一层都在前一层的基础上进一步压缩。[14]
8 前沿动态与趋势(2024–2025)¶
8.1 关键论文时间线¶
| 论文 | 会议/年份 | 贡献 |
|---|---|---|
| PagedAttention | SOSP 2023 | 分页式 KV 管理,vLLM 的核心 [10] |
| StreamingLLM | ICLR 2024 | 注意力锚点 + 无限流式 [36] |
| KIVI | ICML 2024 | 不对称 2-bit 量化 [33] |
| LCKV | ACL 2024 | 跨层 KV 共享 [22] |
| SnapKV | 2024 | 免训练 token 选择 [26] |
| InfiniGen | OSDI 2024 | 投机预取式卸载 [47] |
| CacheGen | SIGCOMM 2024 | KV 编码为比特流 [44] |
| SGLang / RadixAttention | NeurIPS 2024 | 基数树前缀缓存 [42] |
| DeepSeek-V2 MLA | 2024 | 低秩隐注意力 [18] |
| PALU | ICLR 2025 | 低秩投影分解 [35] |
| MagicDec | ICLR 2025 | 稀疏 KV 投机解码 [49] |
| TPA (T6) | NeurIPS 2025 | 张量积注意力 [20] |
| Ada-KV | NeurIPS 2025 | 自适应逐头预算 [29] |
| CacheBlend | EuroSys 2025 | 可组合 KV Cache [45] |
| NVFP4 | 2025 | 硬件级 4-bit 支持 [34] |
8.2 值得关注的趋势¶
- 方案组合化: 单一优化已不够,生产系统普遍叠加 GQA + 量化 + 分页 + 前缀缓存 + 分离式服务。
- 硬件协同设计: NVFP4 证明了 KV Cache 压缩正在从纯软件走向芯片级支持。[34]
- 推理模型的新挑战: DeepSeek-R1、o1 等推理模型产生极长的思维链输出,KV Cache 压力更甚于通用对话。[50]
- 安全性警示: KV Cache 共享带来侧信道攻击风险——通过观察缓存命中模式可以推测其他用户的 prompt 内容(NDSS 2025)。[51]
- 从研究到生产的加速: PagedAttention 从论文到 vLLM 生产部署不到一年。SGLang、LMCache 等项目同样在快速产品化。
9 总结:一张图回顾¶
用户请求到达
│
▼
┌─────────────────────────────────────────────────────┐
│ KV-Aware Router:路由到持有匹配前缀的节点 │ ← 集群调度
└──────────────────────┬──────────────────────────────┘
│
┌──────────────────┴──────────────────────┐
▼ ▼
┌─────────────┐ ┌──────────────┐
│ Prefill 节点 │ │ Decode 节点 │ ← Disaggregated
│ (计算密集型) │───KV Cache 传输──→ │ (访存密集型) │ Serving
└─────────────┘ └──────┬───────┘
│
┌────────────────────────────────────────┘
▼
┌───────────────────────────────────────────────────┐
│ PagedAttention:分页管理 + CoW 共享 │ ← 内存管理
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Block│ │Block│ │Block│ │Block│ ← 非连续物理块 │
│ └─────┘ └─────┘ └─────┘ └─────┘ │
│ 量化层:FP8 / INT8 / KIVI 2-bit │ ← 精度压缩
│ 前缀缓存:RadixAttention 共享前缀 KV │ ← 避免重复计算
│ 溢出层:CPU / 磁盘 / Redis 多级卸载 │ ← 容量扩展
└───────────────────────────────────────────────────┘
│
▼
生成 Token → 追加 KV → 继续解码
KV Cache 是大模型推理中最具杠杆效应的优化点。它连接了模型架构、算法设计和系统工程三个层面。理解 KV Cache,就是理解大模型推理优化的核心逻辑。
References¶
本章引用的参考文献编号延续全书编号体系,见 references.md。