KV Cache 与 Prompt Caching 彻底讲透

大模型为什么能"一个字一个字"地流畅生成,又为什么长上下文/多轮对话会很贵?答案藏在两个紧密相关又常被混淆的概念里:KV Cache(单次生成内的算力加速器)与 Prompt Caching(跨请求/跨轮复用的成本优化)。这篇用流程图、计算对比和一张交互图,把"它是什么、为什么这样设计、省在哪"讲清楚。

一句话区别KV Cache一次生成过程中,把已经算过的 Key/Value 存下来给后续 token 复用;Prompt Caching多次请求之间,把相同前缀的 Key/Value 存下来给不同请求复用。前者解决"自回归重复计算",后者解决"重复前缀重复付费"。
阅读建议:KV Cache 直接建立在 Q/K/V因果注意力之上。如果还不清楚"为什么注意力要算 QKᵀ 再乘 V",建议先看 Q/K/V 核心讲透大模型注意力机制

一、先建立直觉:自回归生成里藏着大量"重复劳动"

Transformer 解码器是自回归的:它一次只产出一个 token,而每个新 token 的注意力必须"看到"之前所有 token(因果掩码)。问题是——这些"之前的 token"每生成一个新字,都得重新参与计算一次。

如果不加任何优化,每一步都要把整段上下文从头再过一遍网络。生成 N 个字,相当于把长度为 N 的序列前向计算了 N 次,总计算量约 O(N²)。绝大多数算力都花在了"重复算已经算过的东西"上。

关键洞察:每一步真正"新"的信息,其实只有最后那一个 token。前面所有 token 的表示并不会变——那为什么还要重算它们的 K、V?直接用缓存不就行了?这就是 KV Cache 的出发点。

二、KV Cache 是什么:把"历史的 K、V"存进内存

回忆注意力公式(单层、单头、省略缩放与 softmax 细节):

Attention(Q, K, V) = softmax( Q · Kᵀ / √d ) · V

要算位置 i 的输出,需要:

KV Cache 的做法:在网络前向时,把每一层、每一个注意力头的 K 和 V 矩阵按序列长度方向"追加式"缓存起来。这样下一步只需计算新 token 自己的 Q、K、V,然后把它的 K、V 接到缓存末尾,用"新 Q"去和"缓存里的全部 K、V + 自己的 K、V"做注意力即可。

一句话定义:KV Cache = 在自回归生成中,缓存已经算过的 Key 与 Value 张量,使每个新 token 只做"自己的那一份"计算,而不必重算历史。它是推理引擎(vLLM、TensorRT-LLM、Ollama、llama.cpp 等)的标准配置,是长文本生成能跑得动的前提。

三、为什么只缓存 K 和 V,不缓存 Q?

这是高频面试题。答案来自"谁会被后续 token 反复需要":

张量被谁需要是否需要缓存
Q(Query)只有"当前正在生成的那个 token"用它去查别人❌ 不需要。过去的 Q 再也不会被任何未来 token 用到
K(Key)未来每一个 token 都要拿自己的 Q 来和它对匹配度✅ 必须缓存
V(Value)匹配度算完后,要按权重从 V 里取内容✅ 必须缓存

换句话说:Q 是"提问方",用过即弃;K 和 V 是"被查阅的资料",会被后来者反复翻看,所以只缓存 K、V。缓存 Q 既无必要,还会白白多吃一份显存。

注意:KV Cache 里"KV"指的就是注意力里的 Key 和 Value,跟键值数据库(Key-Value Store)没关系,名字撞了而已。

四、图文:一次生成里 KV Cache 怎样工作

阶段 A:Prefill(一次性处理整段 Prompt) t₁ t₂ t₃ t₄ 线性投影 → 每层算 Q,K,V KV Cache(缓存) K₁ V₁ K₂ V₂ K₃ V₃ K₄ V₄ … 按层/头/序列长度存储 阶段 B:Decode(每步只处理"新来的那一个 token") 新 token t₅ 算 Q₅(新查询) 算 K₅ V₅(新,入缓存) Attention(Q₅, [K₁…K₅], [V₁…V₅]) 新隐藏状态 复用缓存的 K₁…K₄ K₅ V₅ 同时入缓存 Q K / V(缓存) 注意力输出 复用 / 缓存写入

看图就明白两件事:

五、代价:它快了,但要吃显存

KV Cache 不是免费的。它要常驻显存,且随序列长度线性增长。每一层、每个注意力头的缓存形状为:

K, V 各为 [batch, num_heads, seq_len, head_dim]

每个 token 在每一层要存 2 × num_heads × head_dim 个数(K 一份 + V 一份)。以 fp16(2 字节)为例,单 token 单层的显存 ≈ 2 × num_heads × head_dim × 2 字节

≈0.5 MB
Llama-2-7B 每 token 的 KV Cache(fp16)
32 层 × 32 头 × 128 维 × 2(K,V) × 2B
≈2 GB
4K 上下文时的 KV Cache 占用
O(N)
显存随序列长度线性增长
所以"长上下文为什么贵"有两层含义:一是计算注意力本身随长度上升;二是KV Cache 的显存随长度线性膨胀——序列翻倍,KV Cache 显存也翻倍,这往往是长文本推理的硬瓶颈。工程上常用分页注意力(PagedAttention)、KV 量化(INT8/INT4)、分组查询(GQA/MQA)减少头数等手段来压它。

六、交互:有/无 KV Cache,算力差多少?

拖动滑块设定"已生成的 token 数 N"。左图蓝线为有 KV Cache时的累计计算量(每步只算 1 个新 token,累计 ∝ N);橙线为无 KV Cache时(每步要把整段重算一遍,累计 ∝ N²)。差距随 N 爆炸式拉大。

已生成 token 数 N = 40
生成步数(token 序号)→ 累计计算量(相对单位)
有 KV Cache:累计 ∝ N(线性) 无 KV Cache:累计 ∝ N²(平方)
在当前 N 下,无缓存的累计计算量约为有缓存的 20.5×; 若推到上下文长度 4096,这个倍数约为 2048×
这就是为什么推理引擎默认必开 KV Cache:不是"优化项",而是"不这样根本跑不动长文本"的刚需。KV Cache 只解决单次生成内部的重复;如果很多不同请求共享同一段长前缀(系统提示、RAG 资料、多轮历史),还有一层浪费没解决——这正是下一节的 Prompt Caching。

七、Prompt Caching 原理:把"相同前缀的 KV"跨请求复用

KV Cache 的生命周期通常止于单次请求的结束。但现实中大量请求会复用同一段前缀:

如果每次请求都把这段长前缀重新做一遍 Prefill,既慢(首 token 延迟 TTFT 高)又贵(按 token 计费重复付钱)。Prompt Caching 的做法:

核心思想:当新请求的前缀与已缓存请求的前缀逐 token 一致时,推理引擎直接复用那段前缀已经算好的 K、V,跳过对应的 Prefill,只对新出现的后缀做计算。本质就是"把 KV Cache 跨请求、跨多轮地持久化下来"。

它怎么知道"前缀相同"?——块级哈希

引擎不会傻傻逐字符比对,而是把 token 序列切成固定大小的块(block,常见 128 个 token),对每个块算哈希并建索引。新请求来时,按块匹配:已缓存的块直接命中(cache hit),缺失的块才现场计算并写入。这样既快又支持"前缀部分命中"。

八、图文:多轮对话里 Prompt Caching 怎样省

System Prompt + 历史前缀(所有轮次共享,KV 只算一次并缓存) K₁ V₁ · K₂ V₂ · … · Kₘ Vₘ ← 第一次算完即缓存,后续轮次直接命中 第 1 轮:用户新消息 A Prefill:前缀 + A 全算 → 生成回复 ① 第 2 轮:用户新消息 B ✓ 前缀命中,只算 B → 生成回复 ② 第 3 轮:用户新消息 C ✓ 前缀命中,只算 C → 生成回复 ③ 第 1 轮:长前缀完整 Prefill(写入缓存,成本最高)。 第 2、3 轮:相同前缀 ✓ 缓存命中,免重算、读取价更低、TTFT 大幅下降。 注意:多轮对话里"可缓存前缀"= 到上一轮助手回复为止的历史;本轮新消息是变量,仍需计算。

主流实现一览

提供方名称命中条件 / 特点
Anthropic ClaudePrompt Caching显式设缓存断点;前缀 ≥1024 token;命中读取价约为写入的 1/10;默认 TTL 5 分钟(持续使用可到 1 小时)
OpenAIAutomatic Prompt Caching自动对 ≥1024 token 的前缀缓存;无需改代码;缓存输入 token 计费折扣(如 50% off)
Google GeminiContext Caching显式创建带 TTL 的缓存;按存储时长 + token 分别计费
开源(vLLM 等)Automatic Prefix Caching块级(如 128 token)哈希自动匹配;服务于本地/自部署推理

九、两者到底差在哪?(对比表)

维度KV CachePrompt Caching
作用范围单个请求内的多次 decode 步骤跨请求 / 跨多轮对话共享前缀
复用对象已生成 token 的 K、V相同前缀 token 的 K、V
生命周期一次生成过程(请求结束即释放)多次请求(带 TTL,如 5 分钟~1 小时)
命中条件必然命中(同一次生成内部)前缀 token 逐块一致(哈希匹配)
主要目的避免自回归重复计算,让生成本能跑降低 TTFT 与算力/计费,省重复前缀
典型节省每步计算 O(N) → O(1),总 O(N²) → O(N)长前缀 Prefill 免重算,读取价更低
实现层级推理引擎必备(解码机制)引擎/API 提供的复用策略(可配置)
关系一句话总结:Prompt Caching 是 KV Cache 思想的跨请求推广——把"一次请求里别重算历史"升级成"多个请求里别重算相同前缀"。两者缓存的都是注意力里的 K 和 V,区别只在作用的时间/空间尺度

十、失效条件与注意事项

十一、小结

相关阅读

Q / K / V 核心讲透
理解 K、V 从哪来、为什么注意力要算 QKᵀ·V。
大模型注意力机制
直观看懂注意力如何聚焦上下文关键信息。
大模型为什么没记忆
为什么缓存 ≠ 记忆,以及记忆如何实现。
← 返回 AI 总览
回到 artificial-intelligence 索引页。
本页为人工智能可视化系列之一 · 主题:Transformer 推理优化(KV Cache / Prompt Caching)· 内容基于公开原理整理,具体数值因模型与实现而异。