← 返回题目列表

什么是 KV Cache?它为什么能加速大模型推理?

高频 中等 第 1 / 25 题 更新于 2026/09/18
KV Cache推理优化Attention

简化版

自回归生成时,历史 token 的 Key 和 Value 在每一步都不会改变。KV Cache 把各层历史 K、V 保存下来,新一步只计算新 token 的 Q、K、V,再让新 Q 查询缓存,从而避免重复计算全部前缀。

详细版

没有缓存时,生成第 t 个 token 会再次对前 t−1 个 token 计算各层投影,产生大量重复工作。有 KV Cache 后:

  1. Prefill 阶段一次计算输入提示的 K、V 并缓存;
  2. Decode 阶段只计算最新 token 的 K、V;
  3. 将新 K、V 追加到缓存;
  4. 新 Q 与全部缓存 K 计算注意力,再加权缓存 V。

它显著降低生成阶段计算量,但不会消除对历史 K、V 的读取,注意力长度仍随输出增长。缓存还会占用大量显存,大小大致与批量、层数、序列长度、KV 头数、头维度和数据精度成正比。

完整版教学

一、重复计算从哪里来

因果模型生成 token 时,历史前缀保持不变。对同一层而言,历史 token 的 K、V 已经确定;下一步只有最新 token 是新增信息。若每步把整个序列重新前向一次,就会反复计算相同结果。

Q 只服务于当前位置发起查询,历史 Q 不需要缓存;历史 K 用于与新 Q 匹配,历史 V 用于汇总内容,因此缓存叫 KV Cache。

二、Prefill 和 Decode

Prefill 一次处理完整提示,Q、K、V 可组织成大矩阵乘法,GPU 并行度较高;提示越长,首 token 延迟通常越明显。Decode 每步只处理一个新 token,却要读取所有层的历史缓存,算术强度较低,更容易受显存带宽和调度影响。两阶段瓶颈不同,服务端应分别观察 TTFT、TPOT 和并发下的尾延迟。

三、缓存为什么很占显存

每层都要为每个历史位置保存 K 和 V。批量越大、上下文越长、层数越多,缓存越大。多用户并发服务时,模型权重是共享的,但每条请求都有独立缓存,因此 KV Cache 经常成为并发量的真正限制。

四、MQA 与 GQA

标准多头注意力为每个查询头保留独立 K、V 头。Multi-Query Attention 让多个查询头共享一组 K、V;Grouped-Query Attention 让若干查询头共享一组。它们显著减少缓存和内存带宽,同时尽量保留多头表达能力。

五、Paged Attention 与前缀复用

连续显存分配容易产生碎片,且不同请求长度变化很大。Paged Attention 把缓存按块管理,类似虚拟内存分页,提高显存利用率。若多个请求共享相同系统提示,还可以复用前缀缓存,避免重复 Prefill。

其他优化还包括 KV Cache 量化、滑动窗口注意力和淘汰低价值 token,但都需要在速度、显存和质量之间权衡。

六、它没有解决什么

KV Cache 避免的是历史 K、V 投影和前层计算的重复,不会让每步注意力变成常数开销。新 Q 仍需读取并关注历史缓存,生成也仍是串行过程,所以输出越长,总延迟依然会上升。

训练时整段目标可以并行计算,通常不依赖推理式 KV Cache;缓存主要服务于自回归解码。

七、算一笔单请求缓存账

KV Cache 的大小可近似写成 2 × 层数 × KV头数 × 头维度 × token数 × 每元素字节数,其中 2 代表 K 和 V。对 32 层、32 个 KV 头、头维度 128、BF16、上下文 4096 的 MHA 模型,单请求缓存约为 2 GiB;如果改成 8 个 KV 头的 GQA,则降到约 512 MiB。

MHA: 2 * 32 * 32 * 128 * 4096 * 2 bytes = 2 GiB
GQA: 2 * 32 *  8 * 128 * 4096 * 2 bytes = 512 MiB
变量增长关系优化手段
上下文长度线性增加缓存滑窗、截断、分页管理
KV 头数线性增加缓存GQA 或 MQA
存储精度随字节数线性变化FP8/INT8 KV 量化

这解释了为什么在线服务的并发上限经常先受 KV Cache 而非权重限制。缓存只消除了历史 K/V 的重复投影,不会消除新 query 与全部历史 key 的注意力计算;上下文继续增长时,单步 decode 仍会越来越慢。

八、常见误区与追问

  • 误区:KV Cache 会缓存历史 Q、K、V。 历史 Q 用完即可丢弃;后续新 query 只需读取历史 K 做匹配、读取历史 V 做聚合。
  • 追问:KV Cache 为什么主要优化 Decode? Decode 若无缓存会反复计算整个前缀;缓存后只计算新 token 的投影,但 Prefill 本来就是一次并行处理输入。
  • 误区:用了 KV Cache 后每个生成步就是 O(1)。 新 query 仍要扫描历史 K/V,单步注意力读写量随上下文长度增长。
  • 追问:GQA 怎样减少缓存? 让多个 query 头共享同一组 K/V 头,缓存容量与 KV 头数近似线性下降。
  • 追问:PagedAttention 改变注意力数学吗? 不改变;它改变 KV 块的物理存储和映射方式,以减少碎片并支持动态请求。

九、加强记忆

KV Cache 用显存换重复计算:历史 token 的 K/V 一旦生成便保持不变,Decode 只为新 token 做投影并读取缓存。容量由层数、KV 头数、头维度、token 数和精度共同决定,因此 GQA、分页缓存和 KV 量化是在削减不同乘数。它不会消除新 query 扫描历史 key 的成本;回答时要把 TTFT、TPOT 与并发显存分开说明。