PagedAttention 与 vLLM 推理加速

PagedAttention 与 vLLM 推理加速 1. 背景LLM 推理的瓶颈在哪里LLM 推理如 GPT、LLaMA采用自回归生成每次只生成一个 token每个新 token 都要看到之前所有 token 的信息。输入: 今天天气 Step 1: 今天天气 → 真 需要看 [今天天气] 的 KV Step 2: 今天天气真 → 好 需要看 [今天天气真] 的 KV Step 3: 今天天气真好 → 啊 需要看 [今天天气真好] 的 KV为了避免每一步都重新计算前面所有 token 的注意力我们把每层的 Key 和 Value 缓存下来这就是KV Cache。KV Cache 的显存问题KV Cache 的大小随序列长度线性增长KV Cache2×L×H×D×S×dtype_size\text{KV Cache} 2 \times L \times H \times D \times S \times \text{dtype\_size}KV Cache2×L×H×D×S×dtype_size其中LLL 层数HHH 注意力头数DDD 每头维度SSS 序列长度。以 LLaMA-13B 为例单条序列、2048 tokens → KV Cache 约1.6 GB批量处理多条请求时显存很快耗尽更大的问题显存碎片化。传统实现为每条请求预分配一块连续显存用于 KV Cache但实际序列长度不可预知导致预分配过大 →内部碎片浪费不同请求长度不同 →外部碎片空隙无法利用实测中60%~80% 的 KV Cache 显存被浪费2. PagedAttention核心思想2.1 灵感来源操作系统的虚拟内存操作系统如何管理内存——分页 (Paging)传统方式连续分配 进程A: [████████ ] ← 预分配大块后面浪费 进程B: [██████ ] ← 同样浪费 空闲: [ ] ← 碎片无法利用 分页方式 物理内存: [A][B][A][B][A][空][B][空] ← 按页分配按需使用 进程A的页表: 页0→物理块0, 页1→物理块2, 页2→物理块4 进程B的页表: 页0→物理块1, 页1→物理块3, 页2→物理块6PagedAttention 把同样的思路用到 KV Cache 管理上。2.2 PagedAttention 的工作方式核心把 KV Cache 切分为固定大小的页/块 (Block)按需分配不要求连续。传统 KV Cache连续分配 请求1: [K₁V₁ K₂V₂ K₃V₃ K₄V₄ ____________] ← 预分配 8 slots只用了 4 请求2: [K₁V₁ K₂V₂ ________________________] ← 预分配 8 slots只用了 2 显存利用率: 6/16 37.5% PagedAttention分页分配 Block 0: [K₁V₁ K₂V₂ K₃V₃ K₄V₄] ← 请求1 的 page 0满 Block 1: [K₁V₁ K₂V₂ ________] ← 请求2 的 page 0部分 Block 2: [空闲] ← 可随时分配给新 token 显存利用率: ≈ 100%只有最后一个 block 有内碎片每个 Block 存放固定数量如 16 个token 的 KV 向量Blockblock_size×(Khead_dimVhead_dim)\text{Block} \text{block\_size} \times (K_{head\_dim} V_{head\_dim})Blockblock_size×(Khead_dim​Vhead_dim​)2.3 Block Table页表每条请求维护一个Block Table记录逻辑页到物理块的映射请求 今天天气真好啊7 tokensblock_size4: Block Table: 逻辑页 0 → 物理块 3 存 token 0-3 的 KV 逻辑页 1 → 物理块 7 存 token 4-6 的 KV还剩 1 slot 计算 Attention 时 Q (当前 token) × K (遍历 Block 3, Block 7 中的所有 K) → Attention Scores物理块在显存中不需要连续通过页表间接寻址即可。2.4 关键优势优势说明近零浪费只有最后一个 block 可能有少量内碎片浪费 4%动态增长新 token 生成时按需分配新 block无需预分配内存共享多个请求的公共前缀如 system prompt可共享同一物理块高效批处理显存利用率高 → 同时服务更多请求 → 吞吐量提升3. vLLM基于 PagedAttention 的推理引擎3.1 vLLM 是什么vLLM 是由 UC Berkeley 开发的高性能 LLM 推理服务框架核心创新就是 PagedAttention。vLLM PagedAttention显存管理 Continuous Batching调度 高效 CUDA Kernel OpenAI 兼容 API3.2 核心技术栈(1) PagedAttention — 显存管理如上所述将 KV Cache 分页管理将显存利用率从 ~30% 提升到 ~96%。(2) Continuous Batching — 连续批处理传统 Batching vs Continuous Batching传统 Static Batching 时间 → ████████████████ 请求1长 ████░░░░░░░░░░░░ 请求2短但必须等批次结束 ████████░░░░░░░░ 请求3中同样等待 ↑ 短请求完成后 GPU 空转浪费算力 Continuous Batching 时间 → ████████████████ 请求1 ████ 请求2完成后立即换入请求4 ████████████ 请求4插入 ████████ 请求3 ████████ 请求5插入 ↑ 请求完成后立刻替换GPU 始终满载不需要等一个批次全部完成某条请求生成完毕后立即换入新请求显著提升 GPU 利用率和整体吞吐量(3) KV Cache 共享 — Prefix Caching多个请求共享相同的 system prompt 时KV Cache 可以共享物理块请求1: [System Prompt] 帮我写代码 请求2: [System Prompt] 翻译这段话 请求3: [System Prompt] 总结文章 物理块 0-5: System Prompt 的 KV Cache共享只存一份 请求1 → 物理块 0-5 (共享) 物理块 10-11 (独占) 请求2 → 物理块 0-5 (共享) 物理块 12 (独占) 请求3 → 物理块 0-5 (共享) 物理块 13-14 (独占) 节省显存 2 × (System Prompt KV Cache 大小)通过Copy-on-Write只要请求还在读取共享块就不复制写入新 token 时才分配新块。我4. 性能对比指标HuggingFace TransformersText Generation Inference (TGI)vLLM吞吐量 (tokens/s)1× (基准)~3-5×~8-24×显存利用率~30%~60%~96%批处理方式StaticContinuousContinuousKV Cache 管理连续分配连续分配PagedAttention6. 一图总结LLM 推理瓶颈 │ ├─ 显存瓶颈KV Cache 占用大且碎片化 │ └─ 解决 → PagedAttention分页管理按需分配 │ ├─ 计算瓶颈自回归串行生成慢 │ └─ 解决 → Speculative Decoding小模型猜测 大模型验证 │ └─ 调度瓶颈短请求等长请求GPU 空转 └─ 解决 → Continuous Batching请求完成即替换 三者结合 vLLM → 吞吐量提升 8~24 倍