07. vLLM 为什么快?PagedAttention 的核心思路是什么?
整理 vLLM 的性能优势与 PagedAttention 的核心思路。
简单回答
vLLM 快的核心原因是 PagedAttention——借鉴操作系统虚拟内存分页管理的思想来管理 KV Cache。传统实现预分配连续显存给每个请求的最大可能序列长度,导致大量显存碎片和浪费。PagedAttention 把 KV Cache 分成固定大小的"页",按需分配、不必连续,大幅减少了显存浪费,使得同样的 GPU 能同时服务更多请求,直接提升吞吐量。结合 Continuous Batching,vLLM 的吞吐量比 HuggingFace Transformers 高 10~24 倍。
详细解释
传统 KV Cache 管理的问题
在传统的推理实现中,每来一个请求,系统需要为它预分配一块连续的显存来存放 KV Cache。问题是:在请求开始时,系统不知道这个请求最终会生成多少 token。为了保险,通常按最大序列长度(比如 4096 token)预分配。
这带来两个问题。内部碎片——如果实际生成只用了 200 token,剩下 3896 个 token 位置的显存全被浪费了。外部碎片——即使总剩余显存够,但因为被已分配的请求切割成不连续的小块,无法给新请求分配足够大的连续空间。
这两种碎片在实际部署中导致 KV Cache 的显存利用率通常只有 20%~40%。大量显存被浪费意味着能同时服务的请求数更少,吞吐量下降。
PagedAttention 怎么做
PagedAttention 的思路直接来自操作系统的虚拟内存管理。在操作系统中,进程看到的是连续的虚拟地址空间,但实际的物理内存是按固定大小的"页"(通常 4KB)分配的,虚拟页到物理页的映射由页表维护。
PagedAttention 对 KV Cache 做了同样的事情。KV Cache 被分成固定大小的"块"(block),每块存放固定数量 token 的 KV(比如 16 个 token 的 KV 为一块)。每个请求有一个"块表"(block table)记录它的 KV Cache 用了哪些块以及顺序。
新请求到来时不预分配最大长度的空间,而是生成一块就分配一块。一个请求如果生成了 200 个 token,只占用 个块。这些块在显存中不需要连续——通过块表记录逻辑顺序到物理位置的映射。
请求完成后释放其占用的块,这些块可以立刻被新请求复用。没有外部碎片(因为分配单位是固定大小的块),内部碎片也很小(最多浪费一个块中剩余的位置)。
KV Cache 共享
PagedAttention 的分页机制还天然支持 KV Cache 共享。如果多个请求共享相同的前缀(比如相同的 System Prompt),它们的 KV Cache 前缀部分可以共享同一组物理块,通过类似"写时复制"(Copy-on-Write)的机制——只有当某个请求的生成开始产生分化时,才为它分配新的块。
这对于 Beam Search 和 Parallel Sampling(同一个 Prompt 生成多个候选)特别有价值——多个候选共享 Prompt 的 KV Cache,只为各自不同的生成部分分配独立块。
vLLM 的其他优化
除了 PagedAttention,vLLM 还集成了 Continuous Batching(前面讲过的动态批处理)、高效的 CUDA kernel(优化的 Attention 计算、量化推理 kernel)、以及完善的调度器(管理请求优先级、抢占和恢复等)。
vLLM 的调度器在显存不足时会做抢占(preemption)——暂停低优先级请求、释放其 KV Cache 块、让高优先级请求先处理。被抢占的请求后续可以从检查点恢复或重新计算。
实际效果
根据 vLLM 的论文和实测,在相同硬件上 vLLM 的吞吐量比 HuggingFace Transformers 高 10~24 倍,比 TGI 高 2 ~ 4 倍。主要收益来自于 KV Cache 利用率的提升——同样的显存能同时服务更多请求。
面试时可以这样答
vLLM 快的核心在 PagedAttention。传统做法为每个请求预分配最大长度的连续显存放 KV Cache,导致大量内部碎片(实际用不了那么多)和外部碎片(空间不连续无法利用),显存利用率只有百分之二三十。
PagedAttention 借鉴操作系统的虚拟内存分页——把 KV Cache 分成固定大小的块,按需分配不必连续,通过块表维护逻辑到物理的映射。生成多少就分配多少块,请求结束立刻释放。内部碎片最多一个块,外部碎片几乎为零。KV Cache 利用率从二三十提升到九十以上。
这直接意味着同样的 GPU 能同时跑更多请求,吞吐量大幅提升。再加上 Continuous Batching 和高效 CUDA kernel,vLLM 比原生 HuggingFace 快十到二十多倍。
PagedAttention 还天然支持 KV Cache 共享——多个请求如果有相同的 Prompt 前缀,可以共享同一组物理块,进一步节省显存。这对 System Prompt 很长的场景特别有用。
常见追问
- PagedAttention 的块大小怎么选?对性能有什么影响?
- vLLM 的抢占机制具体怎么工作?
- PagedAttention 对 Attention 计算本身有性能开销吗?