@_avichawla: 为什么 KV 缓存只存储 K 和 V 向量而不存储 Q?(一个流行的 LLM 技术面试问题)大语言模型是自回归的……

X AI KOLs Timeline 新闻

摘要

本文解释了在自回归大语言模型中,为什么 KV 缓存只存储键和值向量而不存储查询向量,并详细介绍了优化令牌生成的推理过程。

为什么 KV 缓存只存储 K 和 V 向量而不存储 Q? (一个流行的 LLM 技术面试问题) 大语言模型是自回归的,因此每个令牌都从它之前的所有令牌中逐个预测。 这种自回归特性在模型内部有直接影响。 对 <n> 个令牌的前向传播会产生 <n> 个隐藏状态,但只有最后一个被投影到 logits,并用于生成下一个令牌。 所以,要理解为什么 KV 缓存只存储 K 和 V 向量,我们必须回溯查看最后一个隐藏状态是如何产生的。 让我们用一个 10 个令牌的提示来逐步说明。 1) 预填充: 所有 10 个令牌在一个前向传播中并行通过模型(使用因果掩码),因为整个提示已知。 在每一层,10 个位置中的每个都产生一个查询、一个键和一个值向量,每个位置的注意力都与所有之前的位置运行。 这个过程计算量大,这就是为什么第一个令牌比后续令牌花费的时间明显更长。TTFT 主要是预填充。 2) 第一个输出令牌: 为了生成第 11 个令牌,只需要第 10 个令牌的隐藏状态。因此,它从隐藏维度投影到词汇维度以生成词汇上的 logits。 然后这些 logits 通过 softmax 和采样生成第 11 个令牌。 3) 回溯隐藏状态: 最后一个隐藏状态是前馈块输出的最后一行。前馈块是按位置应用的(每行独立应用),因此该行来自之前的注意力输出的最后一行。 所以现在我们需要查看注意力的最后一行是如何计算的。 4) 注意力矩阵: 对于 10 个令牌的提示,QKᵀ 会给出一个 10 × 10 矩阵。 第 <i> 行是查询 <i> 与每个键的点积。 因此第 10 行是 Q₁₀·K₁, Q₁₀·K₂, 一直到 Q₁₀·K₁₀。 注意只有 Q₁₀ 出现在其中。Q₁ 到 Q₉ 只属于对应的第 1-9 行,而这些行的隐藏状态我们已经丢弃,因为它们从未被需要。 注意力的最后一行通过 softmax 并乘以整个值向量堆栈 V₁ 到 V₁₀,给出注意力输出的最后一行。 所以最后一个隐藏状态仅取决于三件事:Q₁₀、每个键和每个值。 5) 生成第 12 个令牌: 添加第 11 个令牌,这次,我们需要第 11 行的隐藏状态来生成第 12 个令牌。 数学上,注意力操作变成 Q₁₁ 对比 K₁ 到 K₁₁,然后乘以 V₁ 到 V₁₁。 K₁ 到 K₁₁ 和 V₁ 到 V₁₁ 与预填充 + 第一个令牌产生的逐位相同,因为在因果掩码下,一个令牌的键和值取决于该令牌及其之前的令牌,从不依赖于之后的任何内容,所以添加第 11 个令牌不会改变位置 3 的任何内容。 6) 缓存状态: 总的来说,这意味着在每个解码步骤中,你只需要保留每个位置的键和值,并仅计算新位置的 Q、K 和 V。 每个解码步骤需要一个查询向量,它永远不会再次使用,因此在解码过程中从不被缓存。 下图解释了整个过程。 也就是说,KV 缓存只是 LLM 架构中四个独立缓存层之一。 其他三个是服务器上的前缀缓存、提供商计费的提示缓存,以及完全跳过模型的语义缓存。 我写了一篇关于 LLM 服务中所有四种缓存的完整分析,作为 AI 工程师你应该了解,包括每种缓存的代码。 阅读下文。
查看原文
查看缓存全文

缓存时间: 2026/08/31 02:24

为什么KV缓存只存储K和V向量而不存储Q?(大模型热门技术面试题)

LLM是自回归模型,每个token的生成都依赖于它前面的所有token。这种自回归特性在模型内部有直接影响:对token序列的前向计算会产生隐藏状态,但只有最后一个隐藏状态会被投影为logits并用于生成下一个token。

要理解为什么KV缓存只存储K和V向量,我们需要回溯最后一个隐藏状态的完整生成过程。我们用一个包含10个token的提示词来说明:

1) 预填充阶段 由于整个提示词已知,10个token会通过因果掩码并行完成一次前向计算。在每一层中,10个位置分别生成query、key和value向量,每个位置的注意力计算都会覆盖之前所有位置。这个过程计算密集,也是首token生成耗时明显更长的原因(TTFT主要消耗在预填充阶段)。

2) 生成第一个输出token 生成第11个token时,只需要第10个token的隐藏状态。该状态从隐藏维度投影到词表维度生成logits,再经softmax和采样得到第11个token。

3) 回溯隐藏状态 最终隐藏状态来自前馈网络最后一行的输出。由于前馈网络按位置独立计算,这一行实际来自注意力层的对应输出行。因此我们需要分析注意力最后一行的计算过程。

4) 注意力矩阵分析 对于10个token的提示词,QKᵀ会生成10×10的矩阵。第10行是Q10与所有key(K1到K10)的点积结果。注意这里只出现Q10,而Q1到Q9仅存在于各自的1-9行,这些行的隐藏状态已被丢弃(因为不需要)。注意力最后一行经softmax处理后与所有value向量(V1到V10)相加权,得到最终输出。因此最终隐藏状态仅依赖于三要素:Q10、所有key和所有value。

5) 生成第12个token 添加token11后,我们需要第11个位置的隐藏状态来生成token12。数学上,注意力计算变为Q11与K1到K11的点积,再与V1到V11加权求和。由于因果掩码的特性,token的key和value仅依赖自身及之前token,因此添加token11不会改变之前位置的计算结果。

6) 缓存机制 上述分析表明:每个解码步骤只需保留所有位置的key和value,新位置的Q/K/V可实时计算。每个解码步骤产生的query向量仅使用一次,因此无需缓存。

需要补充说明的是,KV缓存只是LLM系统中的四种独立缓存机制之一。另外三种包括:服务器端的前缀缓存、服务商的提示缓存,以及跳过模型直接返回结果的语义缓存。关于这四种缓存技术的完整解析,我已在《AI工程师必知的LLM服务缓存机制》中详细说明,并附有完整代码实现,欢迎阅读。

相似文章