题目重点:解释因果前缀复用和位置偏移,量化缓存显存并区分算力、带宽与淘汰取舍。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练固定权重的decoder-only因果推理,dropout关闭;历史prefix不改,K/V按各层保存。
- 不把KV cache当训练反向缓存或普通响应缓存;滑窗与量化为额外策略。
解题路线
- 因果模型中历史位置隐藏状态不依赖未来token,因此在权重/上下文相同的推理中,各层旧K/V可复用。新token只生成本次Q/K/V并与缓存历史交互,不重跑全部前缀每层。
- 缓存K/V而不是所有历史Q,是因为当前输出只需要当前query读取所有keys/values;旧query的输出已经算过,无需再次用它们生成当前token。
- prefill先处理prompt并建cache,decode每步append新K/V;每层、每head、batch/请求都需独立对应位置,不能把一个层cache放给另一层。
- RoPE使用绝对position offset,与旧K缓存旋转一致;从0重置新token位置会改变相对关系。改权重、system prompt或前缀内容必须失效相关cache,不能仍称同一上下文。
- 缓存字节≈2·L·B·T·h_kv·d·bytes,长上下文和并发使显存/带宽瓶颈突出。GQA减少KV heads,分页管理减少碎片,量化减字节但需测精度,均不自动消除历史读取。
- dense decode当前query仍看T历史,单步attention线性T,整段生成累计约二次T;KV复用不是把所有生成计算变线性。prefix重用跨请求还需相同token/position/model版本与隔离。
- 测试整序列causal forward与逐tokencached输出一致、不同batch长度、缓存清空/append、EOS和位置偏移;不能仅测cache长度正确。
手动走一遍
L=32、B=1、T=4096、h_kv=8、d=128、每元素2字节,KV约512 MiB。改成32 KV heads则约2 GiB,不含权重/临时激活;此算式明确数据假设。
规模与取舍
新token每层注意力约O(T·h_q·d)及投影/FFN,cache O(LBT h_kv d)。prefill dense attention仍O(T²),缓存读写与带宽需独立测。
易错点与追问
容易失分的边界
- cache让整个生成线性。
- 新token位置从0重新算。
- 跨model或改prefix仍复用。
继续深挖
- 分页和prefix共享怎样隔离?
- 滑窗丢哪些上下文?
- KV量化误差如何测?
