年份与会议
2023 · arXiv
把操作系统的分页思想引入 KV Cache 管理,显著提升大模型服务吞吐,是现代推理系统论文中的关键代表。
年份与会议
2023 · arXiv
作者
Woosuk Kwon、Zhuohan Li、Siyuan Zhuang、Ying Sheng、Lianmin Zheng、et al.
主题
推理系统
阅读时长
约 3 分钟
收录时间
2023/09/12
很多大模型论文关注的是模型本身,但真正到了线上服务阶段,工程团队很快会发现:模型强不强只是第一步,能不能稳、快、省地服务大量请求才是真正决定产品体验的环节。
vLLM 论文之所以重要,是因为它抓住了 LLM serving 里一个极其现实、又长期被低估的问题:
KV Cache 很大,而且会随着请求动态增长和释放;如果管理不好,显存会被严重浪费。
PagedAttention 的贡献,不是提出一个更强的模型,而是让现有模型在同样硬件上更高效地被服务出来。这类工作在真实产品里往往价值巨大。
在自回归生成中,模型会为每个请求、每一层、每个历史 token 保存 K/V 缓存。随着上下文增长,这块缓存会越来越大。
问题在于,线上请求是高度动态的:
如果系统为每个请求分配连续的大块显存,很容易产生两个问题:
这也是为什么很多服务系统理论上 GPU 很强,实际吞吐却上不去。
PagedAttention 的灵感非常直观,来自操作系统中的虚拟内存和分页机制。
与其为每个请求分配一整块连续显存,不如:
这样做的直接收益是:
这个想法看上去像系统细节,但它几乎直接决定了能同时跑多少请求。
把“连续大块显存”与“分页式 KV Cache”放在一起看,PagedAttention 的价值会更直观:
<rect x="86" y="108" width="320" height="44" rx="10" fill="#e8f1ff" stroke="#98b7e1" />
<text x="246" y="136" text-anchor="middle" font-size="17" font-weight="700">请求 A 的连续缓存</text>
<rect x="86" y="164" width="188" height="44" rx="10" fill="#eef6e8" stroke="#a8c48e" />
<text x="180" y="192" text-anchor="middle" font-size="17" font-weight="700">请求 B</text>
<rect x="292" y="164" width="114" height="44" rx="10" fill="#ffffff" stroke="#d1d5db" />
<text x="349" y="192" text-anchor="middle" font-size="14" fill="#8b4b4b">空洞 / 碎片</text>
<rect x="86" y="220" width="136" height="44" rx="10" fill="#fff4dc" stroke="#e2c36f" />
<text x="154" y="248" text-anchor="middle" font-size="17" font-weight="700">请求 C</text>
<text x="243" y="300" text-anchor="middle" font-size="15" fill="#8b4b4b">问题:请求长度动态变化,显存碎片越来越多</text>
<g>
<rect x="568" y="106" width="142" height="164" rx="18" fill="#ffffff" stroke="#b8d8cf" />
<text x="639" y="130" text-anchor="middle" font-size="17" font-weight="700">逻辑页表</text>
<text x="639" y="156" text-anchor="middle" font-size="13" fill="#4b5563">A: 3 -> 7 -> 9</text>
<text x="639" y="182" text-anchor="middle" font-size="13" fill="#4b5563">B: 1 -> 6</text>
<text x="639" y="208" text-anchor="middle" font-size="13" fill="#4b5563">C: 2 -> 8</text>
<text x="639" y="242" text-anchor="middle" font-size="12" fill="#4b5563">逻辑顺序与物理位置解耦</text>
</g>
<g>
<rect x="748" y="106" width="150" height="40" rx="10" fill="#e8f1ff" stroke="#98b7e1" />
<text x="823" y="131" text-anchor="middle" font-size="16" font-weight="700">物理页块 1</text>
<rect x="748" y="154" width="150" height="40" rx="10" fill="#eef6e8" stroke="#a8c48e" />
<text x="823" y="179" text-anchor="middle" font-size="16" font-weight="700">物理页块 2</text>
<rect x="748" y="202" width="150" height="40" rx="10" fill="#fff4dc" stroke="#e2c36f" />
<text x="823" y="227" text-anchor="middle" font-size="16" font-weight="700">物理页块 3</text>
<rect x="748" y="250" width="150" height="40" rx="10" fill="#fce7ef" stroke="#e2a8bd" />
<text x="823" y="275" text-anchor="middle" font-size="16" font-weight="700">更多页块...</text>
</g>
<line x1="710" y1="188" x2="748" y2="188" stroke="#5b6b7f" stroke-width="3" marker-end="url(#page-arrow)" />
<text x="737" y="314" text-anchor="middle" font-size="15" fill="#355c52">收益:近零浪费、更灵活扩容与回收、更适合动态请求</text>
</g>
论文特别强调 near-zero waste,并不是一个夸张宣传,而是服务系统最实际的痛点之一。对推理系统来说,显存浪费会带来连锁反应:
因此,PagedAttention 的意义不是“让某个请求更快一点”,而是让整机吞吐和资源利用率明显改善。这种改进在商业环境里往往比单次 benchmark 提升更有价值。
很多人提到 vLLM 时会只记住 PagedAttention,但论文真正重要的是“PagedAttention + serving system”这个整体。
除了分页式缓存管理外,它还强调:
也就是说,vLLM 并不是单一算子优化,而是围绕 LLM serving 做了完整系统层设计。
PagedAttention 和 continuous batching 很容易被混在一起,但它们解决的层级不同:
两者结合后,效果才会真正明显:
一个解决调度效率,一个解决内存效率。vLLM 的强处就在于它们是配套工作的,而不是只优化其中一半。
论文最重要的实验结论,不是某个绝对 token/s 数字,而是它在相同延迟水平下,相比当时强基线系统显著提升了吞吐,尤其在以下情况下更明显:
这说明 PagedAttention 的收益并不是“玩具环境里的小修小补”,而是会随着真实服务压力增大变得更有价值。
vLLM 很快成为开源推理服务的关键选项,原因并不神秘:
这和某些只在单一 benchmark 上表现漂亮、却难以接入生产环境的系统论文很不一样。vLLM 成功的一个重要原因,是它解决的是“大家已经被卡住的问题”。
如果你已经读过站内的 KV Cache 与推理性能优化,可以把两者这样对应:
因此,KV Cache 教程更偏原理层,vLLM 论文更偏系统层。两者连起来看,才能真正理解为什么线上推理优化是一个完整链路。
虽然它非常重要,但也要看到它不能单独解决所有服务问题:
PagedAttention 主要优化的是内存管理与吞吐,不是把模型计算本体变轻。
显存利用率提高了,不等于所有 SLA、优先级和隔离问题自动消失。
系统论文的效果从来都依赖环境,不能机械地把某个倍数复制到任何场景。
缓存管理只是 serving stack 的一个关键环节,而不是全部。
因此,PagedAttention 是推理系统中的关键地基,但不是完整大楼。
它最重要的贡献,也许不是“提出了一个 clever 的内存技巧”,而是把 LLM serving 的关注点正式推向了:
也就是说,它让大家更清楚地意识到:LLM 服务不是把模型塞进 GPU 就结束,而是一门接近操作系统和数据库调度风格的系统工程。
如果你只想记住三点,请记住:
把这三点想清楚,你再去看推理框架选型、batch 策略、显存优化时,就会更有抓手。
沿着相近主题继续阅读,加深对方法边界与实践场景的理解。