先这样答
KV Cache 不缓存 Q 的根本原因在于,Q 是一次性使用的,而 K 和 V 是需要被高频复用的。在自回归生成任务中,模型每生成一个新 token,都会用它的 Q 去和所有历史 token 的 K、V 计算注意力权重。历史 token 的 K 和 V 在后续每一步都会参与计算,复用价值极高。
从注意力机制看,K 和 V 相当于被查询的内容字典,Q 是发起查询的钥匙。由于因果注意力特性,已生成 token 的 K 和 V 不会随新 token 变化。如果不存下来,每生成一个新词都要把之前所有词的 K 和 V 重新投影计算一遍,开销是平方级的。缓存它们就实现了增量计算。
反观 Q,它仅代表当前这一步的查询需求。当前 token 的 Q 算完注意力结果后就没用了。下一步模型会生成新 token 并算出新的 Q,旧 Q 在未来永远不会被用到。既然无复用场景,缓存就没有收益。业界提出的多查询注意力或分组查询注意力,以及 MLA 架构,本质都是压缩 K 和 V 的规模,这也印证了推理优化核心在 K 和 V 一侧,每步数量固定的 Q 无需存储优化。
面试时可以这样一句话收束:Q 是一次性的查询条件,K 和 V 是被反复查询的固定上下文——缓存只对有复用价值的项有意义。
面试官会怎么追问
- 「KV Cache 缓存的是什么,怎样复用」 缓存的是注意力层投影后的键向量和值向量矩阵。生成阶段每一层会把新 token 的 K 和 V 追加到缓存矩阵中。计算当前步注意力时,直接读取完整的 K 和 V 矩阵与新 Q 做矩阵乘法,省去重算历史 K 和 V 的过程。
- 「既然 K 和 V 带来显存压力,业界有哪些优化方法」 常见方法是改变注意力机制的头数映射。多查询注意力让所有查询头共享一组 K 和 V 头,分组查询注意力让几组查询头共享一组。这类方法通过减少 K 和 V 的头数直接降低显存占用,从而支持更大的批处理大小。
- 「Prefill 和 Decode 阶段对 QKV 的处理有何不同」 Prefill 阶段模型一次性处理整个提示词,并行计算出所有 token 的 Q、K、V,此时 K 和 V 被写入缓存。Decode 阶段每次只处理一个新 token,仅计算这一个 token 的 Q、K、V,利用缓存中已有的历史 K 和 V 完成计算,并将新的 K 和 V 追加进缓存。
回答的坑
- 认为 Q 不占显存所以不用缓存,实际上是因为 Q 在后续步骤中根本不参与数学计算,与占用空间大小无关。
- 混淆自注意力计算和缓存机制,错误说成缓存了前馈网络的激活值,正确方向应明确只缓存投影后的键值向量。
同系列的题
—— 本题完 ——