vLLM introduced PagedAttention, which borrows the paging abstraction that operating systems use for RAM and applies it to the GPU’s KV cache. During LLM inference, the KV cache – the stored key and value tensors for all previous tokens – is the dominant memory consumer. Managing it efficiently is the central challenge of high-throughput inference.
vLLM 引入了 PagedAttention 技术,该技术借鉴了操作系统为内存(RAM)设计的分页抽象机制(paging abstraction),并将其应用于 GPU 的 KV 缓存。在大语言模型推理过程中,KV 缓存——即所有先前 token 的存储KV张量——是主要的内存消耗者。高效管理 KV 缓存是高吞吐量推理的核心挑战
KV Cache 计算公式
BF16 每个数值占 2 Byte
MHA → MQA → GQA
MHA 多头注意力(原始标准,LLaMA1 7B/13B 用)
Multi-Head Attention:Q、K、V 头数量完全相等
40 个 Q 头 = 40 个 K 头 = 40 个 V 头。推理时 KV Cache 要存和 Q 一样多的 KV 头,显存占用极大,就是 KV 公式里的 H 会很大
MQA 多查询注意力(极端简化)
Multi-Query Attention
很多 Q 头 共享同一组 K/V 头。例:40 个 Q 头共用 1 个 K 头 + 1 个 V 头。KV Cache 极小,但精度掉得比较明显
GQA 分组查询注意力(LLaMA2/3 70B、大模型主流方案)
Grouped-Query Attention,GQA 分组查询注意力,MHA 和 MQA 的折中方案
把全部 Query 头分成若干组;
每一组内所有 Q 头,共用同一对 K/V 头;KV 头数量远少于 Q 头,但比 MQA 的单 KV 头多,精度损失可控
Llama3-70B 真实配置:
Query 头总数:128 个,分成 16 组,每组 8 个 Q 头;每组对应 1 组 KV 头,所以 KV 头 H = 8
GQA 优点
- KV 头变少,KV Cache 显存占用暴跌,推理吞吐大幅提升
- 相比 MQA,分组保留更多 KV 信息,模型能力、生成质量衰减很小
- 训练、推理框架原生支持(vLLM、TensorRT-LLM、Transformers)
缺点
- 训练成本比纯 MHA 略高
- 小模型(7B 及以下)一般不用 GQA,收益不明显,还是 MHA
KV Cache Fragmentation 的问题
fragmentationˌfræɡmenˈteɪʃnn. 破碎,分裂;分段储存
传统推理系统会为每条请求序列的 KV Cache 预分配一块连续显存(contiguous memory),分配大小按模型支持的最大序列长度预留。
这种朴素分配方式会造成两类显存浪费:
内部碎片(Internal fragmentation)
一条实际只生成 500 个 token 的对话,却独占一块预留 4096 token 容量的连续显存块;剩余 3596 个 token 对应的缓存空间全程闲置,造成显存空洞浪费。
外部碎片(External fragmentation)
大量对话请求执行完毕释放显存后,空闲显存会分裂成大量零散、不连续的小块。此时若新到来一条长序列请求,即便整体空闲显存总量充足,也找不到一块足够大的连续内存来完成分配,导致请求无法执行。
工程实测:采用这种简单预分配方案时,GPU 显存实际利用率通常仅 20%–40%
PagedAttention – Virtual Memory for KV Caches
analogousəˈnæləɡəsadj. 相似的,类似的;(器官)同功的
PagedAttention (Kwon et al., 2023) borrows the paging abstraction from operating systems. Instead of one contiguous block per sequence, the KV cache is carved into fixed-size pages (blocks), and an indirection table—analogous to a CPU page table—translates each sequence’s logical token positions into scattered physical GPU memory addresses.
PagedAttention(Kwon 等,2023)借鉴了操作系统中的分页抽象机制。与每个序列(sequence)对应一个连续区块不同,KV缓存被划分为固定大小的页面(块),并通过一个间接表(类似于CPU的页表)将每个序列中逻辑令牌的位置映射到分散的GPU物理内存地址上
Block size(块大小)
通常每块存储 16 个 token(可配置调参)。单块存储元素总量公式:16 × 2 × L × H × d
16:块内 token 数量;2:Key Cache + Value Cache 两份缓存
Block table(块映射表)
每条对话序列独立维护一张映射表:建立逻辑块编号 → GPU 显存池内物理块编号的对应关系
作用:逻辑上连续的 KV 序列,底层可以分散存储在不连续的物理显存块中
Physical block pool(物理块显存池)
提前预分配一批固定尺寸的显存块,统一管理空闲块链表
分配操作复杂度为 O(1):需要新块时直接从空闲链表头部取出一块即可,无内存拷贝开销
Attention kernel(注意力计算内核)
计算注意力时,依靠块映射表,从多个不连续的物理显存位置收集分散的 KV 块数据完成计算
Llama3-70B BF16 中,L=80,H=8,d=128,BF16 每个元素占 2 Byte,单块总字节为5MB
4096 token 总 KV 显存单序列总块数:256块
PagedAttention的好处
近乎零显存浪费(Near-zero waste)
内部碎片被严格限制,每条序列最多只会存在1 块未填满的分页(最后一块)。若分页大小为 16 token,单条序列最坏仅浪费 15 个 token 对应的 KV 空间,损耗可忽略不计;同时彻底消除外部碎片 —— 所有分页尺寸统一、可互相复用
对比传统方案:传统预分配整块 4096token 缓存,短会话会浪费数千 token 空间;分页仅末尾一块有少量空洞
动态按需分配(Dynamic allocation)
序列随着 token 生成按需申请分页,无需提前预知整条对话最终长度。这对大模型生成任务至关重要,因为模型输出 token 数量无法提前确定
优势:不用上线前强制设定全局最大序列长度,不会为未知长文本预留大量闲置显存
前缀共享 Prefix sharing(写时复制 copy-on-write)
多条拥有相同前置文本的会话(例如统一系统提示词),可以共用这套前缀对应的物理分页。多条会话的块映射表,仅需同时指向同一批物理显存块;当某条会话在前缀后生成新内容、需要修改共享分页时,会触发写时复制机制,单独拷贝一份分页供该会话独立使用
场景:
固定 1000 token 系统提示词,同时在线 128 位并发用户,沿用 Llama3-70B 单 token 占用 327680 字节参数
不开启前缀共享:所有用户独立存储系统提示词 KV 缓存128 × 1000 × 327680 ÷ 10^9 ≈ 42 GB
开启前缀共享:仅存储 1 份系统提示词 KV 缓存 1 × 1000 × 327680 ÷ 10^9 ≈ 0.33 GB
显存节省:共享前缀部分显存占用直接缩减约 128 倍
显存交换抢占(Preemption via swap)
Swap 交换(vLLM PagedAttention 原生支持)
当 GPU 显存耗尽时,vLLM 可对低优先级会话执行抢占:将该会话全部 KV 分页交换至 CPU 内存(也可直接丢弃分页,后续需要时重新计算 KV)。该功能仅在分页架构下可行;传统连续整块分配方案交换时,必须拷贝整块巨大缓存,开销极高
落地价值:实现 GPU 显存软扩容,提升系统并发承载上限,避免直接 OOM 报错
GPU 显存全部物理块被占满,新序列需要分配 KV 块,但空闲链表为空
框架挑选低优先级 / 长时间无交互的会话做抢占(Preemption)
把该会话对应的全部物理 KV 块,批量拷贝到 CPU 主内存,同时在块表标记 “已交换到 CPU”
释放这批 GPU 物理块,分给新进来的请求
若被抢占会话恢复交互,再把它的 KV 块从 CPU 内存拷贝回 GPU,恢复推理
优缺点
优点:不用直接拒绝新请求,提升整体并发承载上限
缺点:CPU ↔ GPU 内存拷贝存在 PCIe 带宽延迟,恢复生成时会卡顿;频繁 swap 吞吐会明显下跌
重计算(Recompute,备选方案,不长期占用 CPU 内存)
不把 KV 缓存存在 CPU,直接丢弃被抢占序列的所有 KV 块
等会话再次交互时,重新前向走一遍模型,从头算出全套 KV Cache,代替从 CPU 加载
适用:上下文很短、重计算成本低于 PCIe 传输开销的场景
代价:需要重复执行 Transformer 层计算,消耗算力
PCIe
The Host-Device Link
PCIe is used for:
• CPU ↔ GPU data transfers (model loading, CPU offloading)
• Cross-node GPU communication when NVLink is unavailable (rare, very slow)
• NVMe storage access (via CPU)
Host(主机端):CPU + 系统主内存 DRAM
Device(设备端):GPU、NVMe SSD、网卡等 PCIe 外设
PCIe:Host 和 Device 之间唯一的高速物理互联链路(Host-Device Link)