KV Cache 是什么?

KV Cache 是什么?让大模型学会"偷懒"的秘密
上一节我们聊完上下文窗口,你应该已经明白:模型能"看见"多长的内容,是由它的上下文窗口决定的。但这里有个隐藏的坑——看见归看见,每次生成新词的时候,模型都要把之前的内容重新算一遍。
你可能觉得:算就算呗,反正计算机快。
但问题在于,这条"重复计算"的链条会随着文本变长而急剧膨胀。第一次生成要算10个词的注意力,第十次生成就要算100个词,第一百次生成就要算1000个词——而这1000次计算里,绝大部分是在重复劳动。
这才是大模型推理慢的真正原因之一。
那有没有办法让模型"记住"已经算过的内容,只算新的部分?
有。这个让模型学会"偷懒"的技术,就叫 KV Cache。
自回归生成:模型是怎么"吐字"的
要搞懂 KV Cache,得先明白大模型是怎么生成文字的。
现在的语言模型,几乎都采用自回归(Autoregressive)的生成方式。通俗点说,就是模型一次生成一个词(token),然后把这个词当作下一轮输入,继续生成下一个词。
这听起来像什么?
就像你写一篇作文,每次只能写一个字,写完的字会成为下一句的"提示"。第一个字决定了第二个字可能是什么,第二个字又决定了第三个字……一环扣一环,形成一条长长的因果链。
输入提示词 → 模型输出第1个词 → 加上第1个词再输入 → 模型输出第2个词 → ...生成第5个字时,模型需要回头看第1-4个字;生成第100个字时,模型需要回头看第1-99个字。每一步都在"回头看",这在专业术语里叫Attention(注意力机制)——模型需要计算当前位置和之前所有位置的关系。

这个设计保证了生成内容的连贯性。但代价是:每生成一个新词,模型都要完整地重新计算一遍对历史的注意力。
重复计算的巨大浪费
让我们具体算一笔账。
假设生成第5个词。此时模型已经生成了4个词。
第5次注意力计算包括:
- 第1个词的 Key-Value 被用到了第2、3、4、5次计算里
- 第2个词的 Key-Value 被用到了第3、4、5次计算里
- 第3个词的 Key-Value 被用到了第4、5次计算里
- 第4个词的 Key-Value 被用到了第5次计算里
第1个词被算了4次,第2个词被算了3次,第3个词被算了2次……
这像什么?像一个翻译员,每次翻译下一个句子时,都要从头翻一遍之前的整篇文章,即使那句话昨天刚翻过。
随着生成的词越来越多,重复计算的问题越来越严重。
数学上,这种重复计算的复杂度是 O(n² × d),其中 n 是序列长度,d 是模型维度。n 越大,计算量增长得越快。
生成一篇1000词的文章,第1000次生成时,前999个词的 Key-Value 都要被重新算一遍。而这些 Key-Value 其实是固定的——它们算出来什么样,以后就是什么样,根本不需要重复计算。
这就是 KV Cache 要解决的核心问题。

KV Cache:让模型学会"记笔记"
KV Cache 的想法其实很简单:算过的东西,就别再算了。
具体怎么做?
每个词进入模型后,会被转换成三个向量:Query(Q)、Key(K)、Value(V)。
- Query 是"我在找什么"——当前这个词想要从上下文里获取什么信息
- Key 是"我提供什么"——每个词自己能提供什么信息
- Value 是"信息的实际内容"——真正要传递的内容
注意力分数就是 Query 和 Key 做点积,再和 Value 加权求和得到。
问题的关键在于:对于已经生成过的词,它的 Key 和 Value 是永远不会变的。只有当前正在生成的词的 Query 是新的。
所以 KV Cache 的策略是:
把已经算好的 Key-Value 对缓存起来,只计算当前新 token 的 QKV,然后直接和缓存里的历史 KV 拼接做注意力。
这就像学生做课堂笔记。第一遍听讲时认真记,之后复习只翻笔记,不用重新抄写一遍。每一轮学习(生成)都建立在前面的积累上,而不是推倒重来。

没有 KV Cache 时,生成第 N 个 token 要计算 N 个词的注意力。
有了 KV Cache,生成第 N 个 token 只需要计算 1 个词的注意力,加上一次简单的拼接查找。
这就是加速的来源:用存储空间换计算时间。
为什么训练不需要 KV Cache
你可能会问:既然 KV Cache 这么好,训练的时候为什么不用?
答案是:训练和推理的注意力模式完全不同。
训练时用的是双向注意力(Bidirectional Attention)。模型可以看到当前位置前后的所有内容,所有词的 Key-Value 是一次性算出来的,天然是完整计算。不存在"先生成一半,再回头看"的问题。
推理时用的是单向注意力(Unidirectional Attention)。模型只能看到之前的内容,必须逐 token 顺序生成。正是这种"逐个生成"的特性,让重复计算问题变得严重,也让 KV Cache 成为可能。
打个比方:
考试时让你翻书看(训练)vs 闭卷凭记忆答题(推理)。翻书考试不需要"记住之前查过的内容",因为书就在那儿。但闭卷答题必须靠记忆——而记忆就需要缓存。
KV Cache 本质上是推理专用的优化技术。
让 KV Cache 更快更强的工程技巧
基础版 KV Cache 已经能大幅提升推理速度,但工程师们还在不断打磨。这里介绍几种主流的优化技术。
多查询注意力(MQA)
标准 Transformer 每个注意力头都有自己独立的 Key 和 Value。这意味着 KV 缓存的体积和头数成正比。
多查询注意力(Multi-Query Attention) 让多个 Query 头共享一组 Key-Value。
形象地说,原来每个 Query 都要翻一本独立的字典。现在改成大家共用一本字典,省了一半多的存储空间,内存占用减少 50% 以上。
分页注意力(PagedAttention)
这是 vLLM 框架的看家本领。
传统 KV Cache 把每个序列的缓存当作一整块连续内存。但实际生成中,每个序列的长度是动态变化的——有的序列生成到一半就停了,有的还在继续。整块内存容易产生碎片,浪费严重。
PagedAttention 把 KV 缓存分成固定大小的"页"来管理,像操作系统的内存分页一样动态分配。
这就解决了内存碎片问题,让显存利用率大幅提升。vLLM 能用更少的 GPU 跑起更大的模型,靠的就是这个技术。
KV 量化
标准 Transformer 用 FP32(32位浮点)存储每个值。
KV 量化把 FP32 压成 INT8(8位整数),精度略微下降,但内存直接减少到原来的四分之一。配合合适的量化策略,实际效果几乎不受影响。
内存再省 50-75%,同样的硬件能跑更长的序列。
流式注意力(StreamingLLM)
传统 KV Cache 的容量和上下文窗口绑定。要支持超长生成,缓存必须足够大。
StreamingLLM 引入"汇(sink)"机制,把最近的 KV 分成两部分:频繁被引用的"热数据"和历史累积的"冷数据"。热数据常驻缓存,冷数据按需加载。
这样,即使缓存空间有限,也能支持远超缓存容量的序列生成。


实际用起来有多简单
好消息是:你基本不需要自己实现 KV Cache。
主流推理框架已经内置支持:
- vLLM:开源推理框架,KV Cache 管理是核心特性
- HuggingFace Transformers:只需
model.generate(..., use_cache=True)一行开启 - TensorRT-LLM:NVIDIA 官方优化,支持动态批处理下的 KV Cache
对于大多数场景,默认配置就足够好。
有一点值得注意:KV Cache 适合较长的序列生成。如果只生成一两个词,缓存的管理开销可能反而大于节省的计算。实践证明,生成 50+ token 时 KV Cache 的收益才开始明显。
你不需要懂发动机构造,只需要会踩油门——框架替你处理好了 KV Cache 的细节。
KV Cache 看似简单,却是大模型推理优化的基石。从它衍生出的 MQA、PagedAttention、量化等技术,正在让大模型的部署成本不断降低。
但这里还有个问题没解决:模型生成的内容是随机的,即使参数固定,每次生成的结果也可能不一样。
这又是怎么回事?
下一次,我们会聊聊控制随机性的三大参数:Temperature、Top-k、Top-p。它们才是决定 AI"发挥"稳定还是"放飞自我"的关键。
