返回课堂

完整深入材料 · 保留原页与全部停点。回到相关主讲

新 token 读取旧 K/V,再把自己的 K/V 留下来

N53/b0 · 旧缓存与新 Q/K/V

固定投影参数 W_Q / W_K / W_V新 token当前层表示 xQ = xW_QK = xW_KV = xW_V本层·此请求 K/V(1…5)KV1122334455下一步:新 Q 读取允许的位置旧 K/V 留在各自的位置
旧缓存与新 Q/K/V

现在只看decode中的一层。为看清这次增加的状态,我们把已有缓存简画成五个位置;这不是上一页整份材料的真实分词数。左下两排分别保存这些位置的K和V。新token先在当前层得到表示x,再沿上方分开的三条路径,分别经过W_Q、W_K、W_V,形成新的Q、K和V。上方参数没有更新,下面新算出的状态却不同。这里每一列都有一个位置,缓存属于这一层、这一个请求。

教师备课:指图与模拟问答

指图与推进 · 不朗读先指左下K/V的1到5列,再从新token指到当前表示x;沿三条分支依次指W_Q→新Q、W_K→新K、W_V→新V。

N53/b1 · 新 Q 读取允许的 K/V

固定投影参数 W_Q / W_K / W_V新 token当前层表示 xQ = xW_QK = xW_KV = xW_V本层·此请求 K/V(1…5)KV1122334455Q / K 匹配得到读取权重按权重汇总 V旧 V + 新 V
新 Q 读取允许的 K/V

现在沿紫色路径:新Q与允许的K比较,既包括前五个位置,也包括当前位置的新K,得到读取权重。再沿权重箭头进入V汇总,把旧V和新V按同一组权重合起来。旧K/V省掉的是重算,但它们仍要被读取;缓存没有把这次attention的访问成本变成零。

教师备课:指图与模拟问答

指图与推进 · 不朗读推进到b1;先沿Q和K进入读取权重框,再沿权重箭头指向V汇总,最后核对旧V和新V的进入方向。

N53/b2 · 追加本层缓存,输出交下一层

固定投影参数 W_Q / W_K / W_V新 token当前层表示 xQ = xW_QK = xW_KV = xW_V本层·此请求 K/V(1…6)KV1122334455Q / K 匹配得到读取权重按权重汇总 V旧 V + 新 V66追加 K追加 V本层输出交给下一层
追加本层缓存,输出交下一层

这一步有两种去向。右边的本层输出交给下一层,继续完成模型计算;上面新产生的K和V则分别追加到本层缓存的第六列。看两条绿色追加线,它们从新K、新V出发,落在对应的K行和V行。缓存的标题也已经从一到五变成一到六。输出不是产生K/V的来源,K/V在前面的投影步骤就已经形成了。

教师备课:指图与模拟问答

指图与推进 · 不朗读推进到b2;先指右侧本层输出→下一层,再沿两条标有“追加”的线分别找到第六列K和V;核对缓存标题变为1…6。

N53/b3 · 参数固定,缓存继续增长

固定投影参数 W_Q / W_K / W_V新 token当前层表示 xQ = xW_QK = xW_KV = xW_V本层·此请求 K/V(1…6)KV1122334455Q / K 匹配得到读取权重按权重汇总 V旧 V + 新 V66追加 K追加 V本层输出交给下一层
参数固定,缓存继续增长

这一轮结束,上方参数仍是原来的参数,本层缓存从五列变成六列。以后继续生成,缓存还会增长;其他请求也会有自己的状态。现在不仅要问它省了多少重算,也要问这些状态占多少空间。下一页指定一个明确配置,我们从一个token开始计量。

教师备课:指图与模拟问答

指图与推进 · 不朗读推进到b3;对照上方不变的参数与下方六列缓存,停在“5列→6列”的对照,再转入N54。

补充推导、边界与来源

因果计算使旧位置的表示不依赖后来追加的 token,因此旧 K/V 可以复用。每个新 token 在当前层生成自己的 Q、K、V:Q 匹配允许的旧 K 和当前位置 K,权重用于汇总对应的 V,输出送往下一层,新 K/V 追加本层缓存。

缓存复用省掉的是旧位置重算,不是后续读取成本。旧 Q 通常不需要为所有后续步骤持久保存;临时激活和其他运行状态仍然存在。图示一层,各层有各自的缓存。改变参数、前缀或位置计算条件后,应重新判断兼容性,不能任意修改旧文本而沿用缓存。

完整 KV 机制 · 服务主题与兼容条件 · PagedAttention §2.1–2.2,物理 p3。

本页证据与条件

单层 KV 教学示意:已有序列简画为 5 列;非模型实测

进入主题正文