演示 / 大语言模型 / KV Cache:Prefill 与 Decode 算了什么?
KV Cache:Prefill 与 Decode 算了什么?
对照两条完全相同的因果注意力路径:一条每次从头重算,一条缓存 K/V。看清新算的向量、重复读取的历史和逐项一致的输出。
蓝色:复用的历史缓存;橙色:本步新增;灰色:未处理。每个 chunk 两步:先投影写入缓存,再计算注意力。
K / V 缓存:保存历史,不重新投影
带因果遮罩的注意力权重
行为 Q 位置,列为 K 位置,从 0 开始。右上角未来位置始终被遮罩,概率为 0。历史行仅为教学而保留展示,decode 不会重新计算它们。
本步临时 Q:不进入持久缓存
Prefill 批量投影所有提示 token;decode 只投影当前一个 token 的 Q、K、V,但新 Q 仍需读取所有历史 K/V。缓存并没有消除这部分注意力计算。
逐行对照:缓存与全量重算
每个注意力步骤,都用相同输入重新执行无缓存因果注意力,与缓存路径所有已完成行逐项比较。
算得更少,存得更多
投影数按一个 token 的一个 Q、K 或 V 向量记 1 次;点积数按一个 Q 与一个 K 记 1 次。无缓存基线每步重算完整前缀的所有因果行。计数不是 FLOPs,也不是实测延迟;对照验证的额外计算不计入两条推理路径。缓存字节数仅含本页单层单头 FP32 K/V,不含 Q、权重、输出、分配器及教学用历史记录。
观察路线与模型边界
试一试:增加续写步数,观察两条路径累计投影数的差距。再增加提示词长度,看 decode 每个新 Q 所需读取的缓存变长。修改任何参数会清空缓存并重置,避免复用不匹配的状态。
本页是真实数值计算的单层、单头、4 维缩放点积注意力。固定正弦输入与固定投影矩阵用于可复现比较,不包含位置编码、残差、MLP 或训练。续写 token 的输入向量预先给定,不是采样生成的自然语言;真实生成先由 prefill 的最后输出预测下一 token,再将该 token 输入 decode。
因果性保证旧 token 不受未来 token 影响,所以其 K/V 可以复用。多层模型需逐层缓存。GQA 通过让多组 Q 共享更少的 KV 头进一步缩小缓存;本页未实现 GQA、多请求调度或 PagedAttention。