QuanZhou's Wiki

M2-C 工作表:Cached MHA

状态:Current · 未填写模板。当前任务与评分命令以 assignments/m2-c-cached-mha.md 为准;阶段依赖见阶段 2 路线页。

本文件是网站公开的空白模板。下载者可以在自己的副本中填写;本站维护者必须填写私人作答仓库中的同名文件,不得把答案写回这里。

学习合同

Question: 怎样证明逐 Token 追加 K/V 后,每一步 Cached Output 都等于完整前缀重算的最后一个位置?

Prediction: 运行前填写每一步 Cache、Weight、Output Shape,以及修改一个 Batch/Head 后允许变化的切片。

Action: 先写逐位置等价、Cache 内容、隔离与契约测试,再实现动态 Cache 追加。

Artifact: src/inference_lab/multi_head_attention.py
          tests/test_multi_head_attention.py
          checkoffs/m2-c-cached-mha.md

Acceptance: 全部位置数值等价;Shape、Cache 内容、旧 Cache 不变、隔离、非法输入和 M2-B 回归全部通过。

Next decision: 全部门禁通过后进入 M2-D GQA;否则只修正 M2-C。

运行前预测

固定:

B=2, H=3, T=4, D_head=5
完整 Q/K/V: [2,3,4,5]
当前 Q/K/V: [2,3,1,5]

关闭实现文件后填写:

t=0 时旧 Cache:
t=0 时新 K/V Cache Shape:
t=0 时 Weight Shape:
t=0 时 Output Shape:

t=1 时旧 Cache Shape:
t=1 时新 K/V Cache Shape:
t=1 时 Weight Shape:
t=1 时 Output Shape:

一般第 t 步的新 Cache Shape:
一般第 t 步的 Weight Shape:
一般第 t 步的 Output Shape:

K 应沿哪个 Axis 追加:
Softmax 应沿哪个 Axis:
为什么单步 Decode 不需要显式 Causal Mask:
为什么只缓存 K/V,不缓存 Q:

隔离性预测:

只修改当前 K/V[b,h],哪些新 Cache 切片允许变化:
只修改当前 Q[b,h],哪些 Output/Weight 切片允许变化:
调用下一步后,传入的旧 Cache 是否应被原地修改:

定向阅读

只读 Hugging Face Caching 中 Cache update、Attention mask 与逐 Token Shape 的段落:

它确认了哪条预测:
它修正了哪条预测:

第一次失败

在实现前运行 make m2-c,原样记录第一条失败:

命令:
失败信息:
失败发生在 Shape / Cache 更新 / Score / Softmax / Value / 返回顺序 / 输入契约中的哪一层:

逐位置等价记录

t=0 Cached Output 与 Full-Recompute 最后位置:
t=1 Cached Output 与 Full-Recompute 最后位置:
t=2 Cached Output 与 Full-Recompute 最后位置:
t=3 Cached Output 与 Full-Recompute 最后位置:

每一步 Cache 是否等于原始 K/V 前缀:
每一步 Weight 最后一维是否和为 1:
旧 Cache 是否保持不变:
Batch/Head 是否隔离:
触发的非法配置:

运行后记录

第一次修正后的规则:
定向测试:
完整评分:
已完成能力回归:

闭卷解释:为什么 Cached Decode 每步只计算一个 Query,但仍需要读取全部历史 K/V:
闭卷解释:为什么 Cached 与 Full-Recompute 应数值等价,却不代表两者性能相同:

M2-C 验收

待完成

全部通过后进入 M2-D GQA Head 映射;任一项未通过时继续修正 M2-C。