PagedAttention · 把 OS 页式内存搬进 GPU
场景:两个请求(A=34 token,B=20 token)同时推理,KV cache 怎么存?传统框架按 max_model_len 连续预分配 → 相对预留长度浪费约 95%;PagedAttention 把 KV cache 切成 16 token/block 的小块按需分配、离散映射(Block Table 逻辑→物理)+ 共享前缀写时复制 → 内碎片压缩到"最后一块装不满"。示意数据:Llama-2-13B,max_model_len=4096,A100-80G。⚠ 本页所有百分比都标注分母——不同分母的数字不能直接相减(见 ⑩)。
1x2x
待播放
问题(连续预分配) → 相对预留浪费 95% → Block Table(逻辑→物理) → 分页按需分配 → 共享前缀 CoW → 内碎片压缩到最后一块
光点 = 当前环节 · 三思想:分块 / 离散映射 / 写时复制
KV cache 内存布局(每格 = 1 个 16-token 块)—
🟦 已分配(预留未用)|🟧 实际使用|🟪 共享前缀(A/B 共读)|⬜ 空闲/外部碎片
碎片率对比—
传统预分配(连续空间)—
PagedAttention(分页)—
有效 KV 显存占比从约两三成抬升(分母=总 KV 池),同一张卡并发约 2 倍量级
就绪点 ▶ 播放,看传统预分配如何浪费 95%,分页如何救回来。PagedAttention
⚡ 运行时动作:正在发生什么💡 知识讲解:为什么这么设计
内存日志16 token/block · Block Table 逻辑→物理
知识点一句话总结:PagedAttention 把 OS 虚拟内存管理搬进 GPU——KV cache 不再是一整块连续内存,而是切成 16 token/block 的小块,按需分配、离散映射(Block Table 逻辑块 → 物理块,像页表)。解决三问题:① 内碎片:传统按 max_model_len=4096 预分配(每请求 ~3.2GB),实际只生成 ~34/20 token,按预留长度口径浪费约 95%;分页按需分配后,内碎片被压缩到最后一块最多 block_size−1 个 token。② 外碎片:不是消失,而是不再要求连续大块——任何空闲块都能被任何序列使用。③ 无法共享:即使两个请求共享同一 system prompt,传统做法存 N 份;分页后共享物理块(只读共享 + 引用计数 + 写时复制 CoW)。收益:有效 KV 显存占比从约两三成抬升(分母=总 KV 池,随预留长度与长度分布变化),同一张卡并发约 2 倍量级(公开资料给到 2–3 倍,随长度分布与预留长度变化)。报数字必须同时报分母:95%(预留长度)/40–60%(总 KV 池)/4%=8/200(有效 token)/29%=14/48(已分配 slot)是四个不同口径,短请求占比越高,分页的相对开销越明显,所以块大小要按负载调。