← 返回题目列表

Prefix Caching 的原理是什么?它与普通 KV Cache 有什么区别?

高频 中等 第 7 / 25 题 更新于 2026/09/25
Prefix CachingKV CachePrompt Cache多轮对话
学习 AI 实战项目

简化版

普通 KV Cache 只在一次生成内复用当前请求已算过的历史 token,请求结束就释放;Prefix Caching(前缀缓存) 则把可复用前缀的 KV 块跨请求、跨轮保存下来——当新请求的开头与之前某请求完全相同时,直接跳过这段前缀的 Prefill、复用已算好的 KV。它只省「重复输入的 prefill 计算」,不加速未缓存的后缀和后续 Decode。命中条件很严格:模型、token 序列、以及所有影响 KV 的配置都必须完全一致。

详细版

系统按 token 块 + 其完整前缀计算哈希,映射到物理 KV 块。新请求从开头逐块查找:连续命中的块直接引用(跳过 prefill),第一个未命中块之后正常 prefill。块级 Copy-on-Write + 引用计数 让多请求安全共享只读前缀。

适用场景(前缀高度重复时收益大):

  • 公共 System Prompt(所有请求共享同一段系统指令);
  • 多轮对话(每轮都带着相同的历史前缀);
  • 同一长文档被反复提问;
  • 相同的 Few-shot 示例前缀。

失效场景:若每次 prompt 开头都插入动态时间戳、随机 ID、不同模板,缓存几乎无法命中。

完整版教学

记忆钩子:前缀缓存只有在 token、模型、位置与权限域都一致时才能安全命中。

一、两种缓存的范围区别

普通 KV Cache:自回归生成时,当前请求保存已处理 token 的 K、V,让下一步不必重算历史。它的生命周期随请求结束而释放,目标是加速同一序列的 Decode。

Prefix Cache:把 KV 的生命周期延长到跨请求,让以后的请求复用「相同输入前缀」产生的 KV。简要说——普通 KV Cache 是「一次回答内不重读前文」,Prefix Cache 是「以后遇到同一前缀也不重读」。

二、为什么必须是”完全相同的前缀”

这是理解前缀缓存的关键。Transformer 里,某位置的 K、V 依赖它之前的全部 token(通过多层注意力)。所以只有当前缀的 token、顺序、位置全部一致时,缓存的 KV 才能直接复用——哪怕只改了前缀里一个 token,它之后所有位置的 KV 都变了,不能复用。

几个容易忽略的命中条件:

  • 相同自然语言,但 tokenization 不同 → 不是同一缓存键(比如多了个空格切法就变了);
  • 模型权重、LoRA/Adapter、RoPE 配置、精度不同 → KV 不同,必须隔离;
  • 多模态输入等任何影响前向结果的东西,都要纳入哈希键。

三、块级缓存与 PagedAttention 配合

为了高效,缓存按固定 token 数分块(如每 16 token 一块),和 PagedAttention 的分页机制天然配合:

System Prompt(512 token,32 个块)── 所有请求共享这 32 个物理块
   请求A:[共享的32块] + [A独有的后缀块]
   请求B:[共享的32块] + [B独有的后缀块]

完整块命中才能共享物理页;最后一个不完整块可能选择不缓存或单独处理。块大小是权衡:块越大元数据越少,但更难命中细小差异;块越小管理开销越高。

四、收益边界:只省 Prefill,不省别的

必须清楚前缀缓存的收益边界。命中 L 个前缀 token,主要省下的是这 L 个 token 的 prefill 计算:

省下的 ≈ L 个 token 的 prefill(TTFT 下降)
不省的 :新后缀的 prefill、全部输出的 Decode

所以它直接降低的是 Prefill 工作量和 TTFT,不会减少后续每个 Decode 步骤所需的注意力计算。实际 TPOT 仍可能因缓存占用、调度或并发变化而间接受影响,不能承诺绝对不变。在短 Prompt、一次性无重复请求或瓶颈完全位于 Decode 的场景,收益通常很小。

五、显存竞争与淘汰

前缀缓存占用显存,且会和活跃请求的 KV Cache 竞争容量。可采用 LRU、LFU 或按“预计复用次数 × 节省 Prefill 时间 ÷ 占用字节”排序的价值策略;LRU 只依据最近访问,并不等价于保留最高频条目。真正的目标是在命中收益、条目大小和活跃请求容量之间动态平衡。

六、安全与隔离(易被忽略的坑)

跨请求共享缓存带来安全风险:

  • 时序侧信道:攻击者可能通过「某前缀命中快、未命中慢」推断别人用过什么 prompt;
  • 错误复用:不同权限域若错误共享缓存,可能通过输出或时序泄露信息,也可能直接产生与当前请求不一致的结果。

防护:租户命名空间隔离、缓存盐(salt)、访问控制。此外,更新模型、LoRA、prompt 模板后必须让旧缓存失效——否则会用错 KV 产生错误输出。缓存的是「中间 KV 状态」,不是「最终回答」,别搞混。

七、用判断表校验缓存键与失效边界

前缀缓存键不仅要避免“同文本不同计算”误命中,也要支持版本升级和权限撤销后的定向失效。工程上通常把模型 revision、Tokenizer/模板版本、Adapter、位置配置、token 块哈希和权限命名空间共同纳入键或其上层索引。

命中条件可复用必须失效
token ids 完全一致前缀 KV 块模板或 tokenizer 改变
模型 revision 一致对应层缓存权重/LoRA 切换
位置配置一致RoPE 后的 K/Vposition offset 改变
权限域相同经批准的共享前缀跨租户敏感内容

假设公共前缀为 2,048 token,未命中 Prefill 需要 80 ms,缓存条目占 512 MiB;若每分钟只复用一次,长期占用显存未必划算,而每秒复用 20 次时收益就很显著。是否开启应以节省的计算、显存机会成本和命中长度共同评估。

八、常见误区与追问

  • 误区:普通 KV Cache 与 Prefix Cache 是同一层缓存。 普通 KV 属于单请求历史;Prefix Cache 让多个请求复用相同 token 前缀已经计算出的 KV。
  • 误区:文本看起来相同就一定命中。 必须保证 token 序列、模型、位置编码、Adapter 和影响计算的配置一致。
  • 误区:前缀缓存只会节省显存。 它主要避免重复 Prefill 计算,但缓存本身占显存,需要淘汰与引用计数。
  • 追问:缓存键应包含什么? 至少包含模型与权重版本、Tokenizer 后的前缀 token、位置/模板配置和租户隔离信息。
  • 追问:如何判断值得开启? 测前缀重复率、命中长度、节省的 Prefill 时间、缓存占用和淘汰开销;低复用流量可能得不偿失。

九、加强记忆

Prefix Caching 记「跨请求复用相同前缀的 KV」:普通 KV Cache 在一次生成内避免重算历史,前缀缓存则延长兼容 KV 的生命周期。它直接节省命中前缀的 Prefill,不减少未命中后缀和后续 Decode 的数学工作;命中要求 token、模型、位置、Adapter 与权限域等条件一致。块级共享要配引用计数和失效策略,跨租户还要防侧信道;最终用命中长度、节省时间、显存占用和质量正确性共同验收。