深入 KV Cache 的运作过程
深入 KV Cache 的运作过程
KV Cache 的工作主要发生在 Transformer 模型的 Decoder Block 中,特别是其多头自注意力(Multi-Head Self-Attention)层。
整个推理过程通常分为两个阶段:预填充阶段 (Pre-fill) 和 解码阶段 (Decoding)。
1. 预填充阶段 (Pre-fill / Prompt Encoding)
这个阶段处理用户的整个输入 Prompt(比如 100 个 token)。
步骤详解:
-
输入与投影: 完整的输入序列 进入 Transformer 的每一层。
-
计算 : 在自注意力层中,模型使用权重矩阵 对输入向量进行投影,一次性计算出所有 token 的 、 和 矩阵:
-
-
自注意力计算: 模型计算完整的自注意力,生成 Prompt 的编码表示。
-
缓存 和 : 关键步骤。 计算得到的
矩阵被存储到 GPU 显存中的 KV Cache 区域。
特点: 这是一个高度并行化的过程(所有 token 同时计算),速度快,但计算量大(二次复杂度 )。
2. 解码阶段 (Decoding / Token Generation)
这个阶段是模型逐个生成新的输出 token。假设模型现在要生成第 101 个 token 。
步骤详解:
-
输入 Q: 模型的输入是上一步生成的最后一个 token
。
- 模型计算
对应的
向量。
- 模型计算
-
获取 K和 V: 模型计算
对应的
和
向量。
- 模型从 KV Cache 中读取上一个阶段存储的所有
和
。
- 模型从 KV Cache 中读取上一个阶段存储的所有
-
拼接 K 和 V:
-
将新的
向量追加到缓存的
后面,形成完整的 K’ 矩阵:
-
同样,将
追加到缓存的
后面,形成完整的 V’ 矩阵:
-
-
注意力计算: 模型使用新的
与拼接后的 K’ 和 V’ 进行注意力计算:
-
生成下一个 Token: 注意力输出经过后续的 Feed-Forward 层和 Softmax 预测,生成下一个 token
。
-
更新缓存: 和 向量被永久保存并追加到 KV Cache 中,供下一个
使用。
特点: 这是一个串行自回归的过程(一次只能生成一个 token)。最重要的是,**每次计算 K’ 和 V’ 时,不需要重新计算 Prompt 部分的 K/V。**计算量大大降低(线性复杂度 O(L)),但因为是串行的,总耗时依赖于生成长度。
总结:KV Cache 的本质和优势
| 维度 | 无 KV Cache | 使用 KV Cache |
|---|---|---|
| 计算 | 每生成一个 token,都需要重新计算所有先前 token 的 K/V。 | 只计算当前新 token 的 K/V,并从缓存中获取历史 K/V。 |
| 时间复杂度 | 在 L长度的序列上,每次计算 K/V 的复杂度是 O(L^2)。 | 每次生成一个 token 的计算复杂度是 O(L)。 |
| 显存代价 | 极低(仅存储模型权重)。 | 高,需要存储所有 Transformer 层、所有注意力头的历史 K/V 向量。 |
| 推理速度 | 极慢(尤其在长序列上)。 | 显著加快。 |

