KV Cache(Key-Value Cache,键值缓存)是大模型推理过程中为了加速生成和节省计算量而设计的一种核心技术。
为了让你直观理解,我们需要先回顾一下 Transformer 生成文本的过程。
- 为什么要用 KV Cache?(背景)
大模型生成文本是一个字一个字往外"蹦"的(自回归生成)。
假设你让模型写一句话:"我爱 artificial intelligence"。
模型生成这句话的过程是这样的:
输入: "我爱"
模型计算: 预测下一个词是 "artificial"
输入: "我爱 artificial"
模型计算: 预测下一个词是 "intelligence"
......以此类推。
问题来了:
在第 4 步生成 "intelligence" 时,模型需要处理整个序列"我爱 artificial"。
在这个过程中,模型需要计算 Attention(注意力机制)。
"artificial" 需要看"我"。
"artificial" 需要看"爱"。
"artificial" 需要看"artificial"(自己看自己)。
但是!在前面的第 2 步(生成 "artificial" 时),模型其实已经计算过"我"和"爱"的 Key (K) 和 Value (V) 矩阵了。
如果没有 KV Cache:
每次生成新词,模型都要把"我"和"爱"拿出来重新计算一遍 K 和 V。这就好比你每次做饭都要重新种菜、收割,这太浪费时间了(计算量巨大)。 - KV Cache 是什么?
KV Cache 就是把之前已经计算过的所有 Token 的 K 和 V 矩阵存起来,放在显存里,下次要用的时候直接拿来用,不再重新计算。
K (Key): 用来做查询匹配的索引(比如"书签")。
V (Value): 实际存储的内容信息(比如"书页里的内容")。 - KV Cache 是如何工作的?
我们还是看"我爱 artificial intelligence"的例子:
第一步(生成 "artificial"):
输入:"我爱"
计算:计算出"我"的 K, V 和"爱"的 K, V。
动作: 将这组 K, V 存入 KV Cache。
输出:"artificial"
第二步(生成 "intelligence"):
输入:"artificial" (只输入新词!)
计算:
计算"artificial"这个新词的 K, V。
从 KV Cache 里把"我"和"爱"的 K, V 直接读出来(不需要重算)。
合并:用新词的 K 去匹配 Cache 里所有的 K(我、爱、自己),计算注意力,获取对应的 V。
动作: 把"artificial"的 K, V 也存入 KV Cache,供下一个词使用。
输出:"intelligence" - KV Cache 带来的好处与坏处
好处:速度快(省计算)
它避免了大量的重复计算。虽然随着对话变长,Cache 越来越大,计算 Attention 的时间还是会增加,但至少省去了重复计算历史 Token K、V 矩阵的昂贵开销。
坏处:吃显存(占内存)
这是 KV Cache 最大的副作用。
因为模型是一字一字生成的,生成的序列越长,KV Cache 里存的东西就越多。
显存占用公式: 序列长度×层数×Hidden维度×2×数据类型大小\text{序列长度} \times \text{层数} \times \text{Hidden维度} \times 2 \times \text{数据类型大小}序列长度×层数×Hidden维度×2×数据类型大小
现象: 你可能遇到过这种情况:显卡明明还有很多剩余显存,但长对话报错 Out of Memory (OOM)。这通常不是模型参数装不下,而是 KV Cache 把显存塞满了。 - 回扣 DeepSeek 的 MLA
这就是为什么 DeepSeek 的 MLA(多头潜在注意力机制) 如此重要!
传统模型的 KV Cache: 存的是完整的、巨大的 K 和 V 矩阵。显存很快就爆了,且搬运数据慢。
DeepSeek 的 MLA: 它在存入 KV Cache 之前,先把 K 和 V 压缩成极小的"潜在向量"。
结果: KV Cache 的体积大幅缩小(比如变成原来的 1/10)。这意味着在同样的显卡显存下,DeepSeek 可以推理更长的文本,或者更快速地生成文本。