在大型语言模型推理过程中,键值缓存(KV Cache)占据了大量显存,而传统推理框架往往要求这部分缓存以连续内存形式存在。当请求长度不一、并发量上升时,连续分配策略会产生严重的内部碎片和外部碎片,使得宝贵的GPU显存利用率常常跌至百分之四十以下。vLLM提出的PagedAttention,借鉴了操作系统的分页内存管理思想,将KV Cache划分为固定大小的块,通过块表完成逻辑到物理的映射,从而让显存使用变得灵活且紧凑。

分页式KV缓存的底层设计
PagedAttention最核心的改变,是把原本必须连续存放的注意力键值对,拆成若干个大小固定的页面,一般称为block。每个block保存固定数量的token所对应的Key和Value张量。模型在自回归生成时,如果当前序列已写满一个block,就向内存管理器申请一个新的物理block,并在该序列对应的块表中追加映射项。这样一来,一个请求的KV Cache在物理显存上可以是不连续的,完全由块表来记录逻辑块编号与物理块编号的对应关系。
这种设计与传统方式形成鲜明对比。旧方案通常在序列开始前就按最大可能长度预分配一整段连续显存,无论实际生成多少token,预留部分都不能被别人使用。而PagedAttention只在需要时分配block,且block可被调度器在不同序列间灵活回收。下面的伪代码展示了块表的基本结构:
class BlockTable:
def __init__(self):
# 逻辑块到物理块编号的映射
self.mapping = []
def append_block(self, physical_id):
self.mapping.append(physical_id)
def get_physical(self, logical_id):
return self.mapping[logical_id]
# 序列A的块表
table_a = BlockTable()
table_a.append_block(0)
table_a.append_block(3)
# 逻辑块1实际存在物理块3中
print(table_a.get_physical(1))
从实现角度看,分页机制还要求注意力计算内核能够接收非连续地址并正确读取。vLLM的CUDA内核会依据块表把各物理block中的KV拼成计算所需的完整序列视图,对上层算法而言序列仍是连续的,但底层显存完全离散。这种抽象隔离让显存管理效率和计算正确性同时得到满足。
写时复制与显存共享机制
在真实服务场景中,经常出现多个请求共享同一前缀的情况,例如系统提示词完全相同,或并行采样的多个输出来自同一上下文。传统框架会为每个请求复制一份前缀KV Cache,造成成倍显存消耗。PagedAttention引入了写时复制(Copy-on-Write)策略:初始时多个序列的块表指向同一个物理block,并将该block标记为只读;只有当某个序列需要修改其中内容时,才真正分配新block并拷贝数据。
这一机制极大提升了显存复用率。以下示例说明两个序列如何共享前缀块,又在写入时分裂:
# 序列A和B共享物理块0、1
table_a = BlockTable()
table_b = BlockTable()
for pid in [0, 1]:
table_a.append_block(pid)
table_b.append_block(pid)
# B要生成新token,需写入新逻辑块,触发复制
new_pid = alloc_block()
table_b.append_block(new_pid)
copy_from(src=1, dst=new_pid)
mark_readonly(1)
写时复制不仅省显存,也降低了启动延迟,因为共享前缀无需重复计算。在beam search等需要保留多候选路径的解码方法中,大量中间前缀都可被不同beam共享,PagedAttention使得这种共享成为默认行为而非额外优化。相比每次都完整克隆,显存占用可缩减数倍,尤其对长系统提示和批量采样价值明显。
相比连续缓存的吞吐与碎片对比
连续缓存方案由于预分配和长度对齐,内部碎片来自短请求占用长空间,外部碎片来自释放后留下的无法利用的小空洞。PagedAttention以固定block为最小单位,分配粒度更细,几乎消除了外部碎片;内部碎片仅限最后一个block未写满部分,比例由block大小决定,通常可控制在百分之十以内。实测中,同等并发下vLLM显存利用率可超过百分之九十。
高显存效率直接转化为更高吞吐。因为同样显存能容纳更多并发序列的KV Cache,GPU计算单元等待数据的空闲减少,请求排队时间缩短。我们可用一张简表对比两类方案:
| 维度 | 连续缓存 | PagedAttention |
|---|---|---|
| 分配方式 | 按最大长度预分配连续段 | 按需分block,非连续 |
| 碎片类型 | 内外部均严重 | 仅末块内部碎片 |
| 前缀共享 | 需手动复制 | 写时复制自动共享 |
| 典型显存利用率 | 低于40% | 高于90% |
当然,PagedAttention也带来一定实现复杂度,例如块表维护和异构内核改造。但其收益在大规模部署中远超成本。理解PagedAttention原理,有助于我们在自研推理系统或选型时,准确评估显存与并发的平衡点,也能更清晰地看懂vLLM为何成为高吞吐大模型服务的代表框架。
PagedAttentionvLLMLLM推理显存修改时间:2026-08-17 20:22:34