vLLM 推理内核深度解析

前言:走进 LLM 推理引擎的心脏

作者 杨艺韬 · 4,218 字

前言:走进 LLM 推理引擎的心脏

"The best engineering is indistinguishable from physics — it makes the impossible feel inevitable."

推理引擎是 AI 应用真正的瓶颈。模型再强,喂不进 GPU 也是白搭。

一切的起点:伯克利实验室那条 40% 的利用率曲线

2023 年春,加州大学伯克利分校一间挤满了监控屏的实验室里,几个研究生盯着 GPU 利用率曲线发愁。

他们在用 HuggingFace Transformers 部署一个 13B 参数的语言模型,GPU 显存看上去已经被占满,但 GPU 计算核的利用率始终在 40% 上下徘徊——大量显存被浪费在碎片化的 KV Cache 分配上,请求排着队,首 Token 延迟飙升,而 GPU 的 TensorCore 却一直在"发呆"。

GPU 利用率:     ████████████░░░░░░░░░░░░░░░░░░  40%
GPU 显存占用:   ██████████████████████████████  95%
实际有效显存:   ████████████████░░░░░░░░░░░░░░  40%
浪费在碎片上:   ░░░░░░░░░░░░░░░░██████████████  55%

"操作系统早就解决了这个问题,"其中一个人说,"内存分页。"

这句话成了一切的起点。

从 OS 到 GPU:一次跨领域的思想迁移

他们把操作系统里虚拟内存的分页机制引入到 KV Cache 管理中,设计出 PagedAttention 算法。KV Cache 不再按请求整块预留,而是被切分为固定大小的 Block,按需映射,动态回收——就像操作系统管理物理内存一样优雅。

传统 KV Cache:
  请求 A: ████████████████────────     (预留 512,实际用 320,浪费 192)
  请求 B: ████████────────────────     (预留 512,实际用 160,浪费 352)

PagedAttention:
  Block Pool: [B1][B2][B3][B4][B5][B6][B7][B8][B9][B10]...
  请求 A → 用 B1/B3/B7                     (按需分配)
  请求 B → 用 B2/B5                        (按需分配)
  释放的 B4/B6 → 立即给新请求              (动态回收)

这个想法最终凝结成一篇 SOSP'23 论文和一个开源项目——vLLM

论文发表后不到一年,vLLM 的 GitHub 星标突破 6 万。从硅谷创业公司到国内大厂,从学术实验室到千卡集群,几乎所有严肃对待 LLM 推理效率的团队都在用它。它成了 LLM 推理基础设施的事实标准

一个数字说明一切

2023 年 H100 单卡价格:  $30,000
全球部署的 H100 数量:  ~300 万张 (2025 年估计)
总硬件价值:             ~$900 亿

如果推理效率提升 2 倍:
等价节省:              $450 亿的硬件成本
或者:                  服务 2 倍的用户

每提升一个百分点的推理效率,都是在给 AI 产业腾挪万亿级的空间。vLLM 的历史地位就建立在这个数字上。

为什么又一本 vLLM 书

如果你搜 "vLLM tutorial",能找到几十篇博客、十几个视频教程、一份越来越厚的官方文档。它们大多数的套路是:

这些都有用,但合起来仍然只是**"使用手册"**——告诉你按哪些按钮,却不告诉你按钮背后有什么线路。

工程师真正想知道的

而工程师真正想知道的是另一组问题:

这些"为什么"藏在代码注释里、PR 讨论里、issue 追踪里、作者在 GTC 大会上的一句口误里。你要把它们拼起来,才能真正理解 vLLM。

本书的定位

本书做的就是这件事——把源码、PR 讨论、benchmark 数据和生产踩坑经验串成可读的章节——不是源码导读,是源码之后的思考

graph LR
    A["官方文档<br/>&quot;怎么用&quot;"] --> B["社区博客<br/>&quot;为什么这样用&quot;"]
    B --> C["源码<br/>&quot;到底是怎么做的&quot;"]
    C --> D["本书<br/>&quot;为什么这样设计&quot;"]

    style A fill:#fef3c7,stroke:#f59e0b
    style B fill:#fef3c7,stroke:#f59e0b
    style C fill:#dbeafe,stroke:#3b82f6
    style D fill:#dcfce7,stroke:#22c55e,stroke-width:2px

本书基于的源码版本

本书基于 vLLM v0.8.x,这是一个里程碑版本:V1 引擎在这个版本中正式成为默认架构

V1 是对整个推理引擎的重新设计——多进程架构、统一 Token 调度、零开销前缀缓存、分段 CUDA 图、有状态 Worker——几乎每个核心子系统都被重写过。

为什么选 V1 而非 V0

选择 v0.8.x 而不是更早的 V0 版本,是因为 V1 代表了 vLLM 团队对"推理引擎应该长什么样"这个问题的最新答案。理解 V1,就是理解 LLM 推理系统设计的当前边界。

源码对照指南

我建议你在阅读时同步打开源码对照:

git clone --branch v0.8.5 https://github.com/vllm-project/vllm.git
cd vllm

# V1 引擎核心路径
ls vllm/v1/engine/    # EngineCore、EngineCoreProc、EngineCoreClient
ls vllm/v1/core/      # Scheduler、KVCacheManager、BlockPool
ls vllm/v1/worker/    # Worker、GPUModelRunner、InputBatch
ls vllm/v1/executor/  # UniProc / Multiproc / Ray 三种执行器
ls vllm/v1/attention/ # FlashAttention / FlashInfer 等 Attention 后端

# 为对照理解 V1 重构动因,保留一份 V0 源码很有帮助
ls vllm/engine/       # V0 的 LLMEngine / AsyncLLMEngine
ls vllm/core/         # V0 的 Scheduler / BlockSpaceManager

引用标注规范

书中所有源码引用都标注了具体路径,形如:

vllm/v1/engine/core.py:142      ← 精确行号引用
vllm/v1/core/sched/scheduler.py ← 模块级引用

遇到一个精确的行号引用,说明那一行的代码足够关键,值得你停下来对照读一遍。

为什么是 vLLM

在 vLLM 之前,LLM 推理领域并不缺方案:

方案 擅长 不足
HuggingFace Transformers 直接从训练流程衔接,生态最广 推理效率低,批处理原生支持弱
NVIDIA TensorRT-LLM 极致 kernel 优化,延迟最低 C++ 为主,模型转换门槛高,迭代慢
DeepSpeed-Inference 大模型 TP / PP 的工程先行者 后续维护放缓,社区活跃度下降
llama.cpp CPU / Apple Silicon 本地推理之王 不是为多卡云端服务设计的
SGLang / LMDeploy / MLC-LLM 新一代竞争者 功能覆盖不如 vLLM 全
Ollama 桌面端开箱即用 单用户 only,不适合服务化

vLLM 找到的黄金平衡点

vLLM 找到的是一个黄金平衡点

无与伦比的教育价值

更重要的是,vLLM 源码的教育价值独一无二:

项目 复杂度 学习成本
TensorRT-LLM CUDA + C++ 深水区 一个 kernel 看一天
llama.cpp GGML 后端 对 Python 工程师陌生
HF Transformers 训练 + 推理混合 路径被"污染"得复杂
vLLM Python + 必要 CUDA 一两小时读懂一个子系统

vLLM 用 Python(加上必要的 CUDA kernel)实现了生产级的推理引擎,代码可读性和系统复杂度之比恰到好处——足够复杂能教会你真实的工程权衡,又足够清晰能让你在一两小时内读懂一个子系统。

对想"真正理解推理引擎"的工程师来说,vLLM 就是当下最好的教材。

V0 → V1:一次激进且必要的重构

V0 是 vLLM 的第一代实现,从 2023 到 2024 年支撑了社区爆发性增长。但代码积累到一定程度,V0 开始显露出难以修补的病:

V0 的五大病症

症状 表现 影响
God Object LLMEngine 单文件 1500+ 行 维护噩梦
调度重复 Prefill/Decode/Chunked 三套代码 Bug 容易,优化难做
无状态 Worker 每 step 广播 KB 级冗余数据 网络成为瓶颈
职责耦合 Block 分配/前缀缓存/抢占在一起 改一处动全身
单进程 API 和 Engine 在同一个进程 前端压力卡住推理

V1 的七大架构革新

2024 年下半年 vLLM 团队启动 V1 重构。V1 不是"给 V0 打补丁",是推倒重来的架构级改造。主要思想:

graph TD
    V1[V1 架构革新]
    V1 --> F1[① 单线程 EngineCore 主循环<br/>消除并发复杂度]
    V1 --> F2[② 统一 Token 调度<br/>Prefill/Decode/Spec 都是分配 N 个 Token]
    V1 --> F3[③ Block Pool / KVCache / Scheduler 解耦<br/>每层只做自己的事]
    V1 --> F4[④ 有状态 Worker + 差量同步<br/>O-全状态 → O-变化量]
    V1 --> F5[⑤ 多进程 + ZMQ<br/>API 和 Engine 分离]
    V1 --> F6[⑥ Executor 抽象<br/>UniProc/Multiproc/Ray 同一接口]
    V1 --> F7[⑦ Attention Backend 抽象<br/>Flash/FlashInfer/Triton/ROCm 可插拔]

    style V1 fill:#dbeafe,stroke:#3b82f6,stroke-width:2px
  1. 单线程 EngineCore 主循环——消除并发复杂度
  2. 统一 Token 调度——Prefill / Decode / Spec Decode 都是"给请求分配 N 个 Token"
  3. Block Pool / KVCacheManager / Scheduler 解耦——每层只做自己的事
  4. 有状态 Worker + 差量同步——通信量从 O(总状态) 降到 O(变化量)
  5. 多进程 + ZMQ——API Server 和 EngineCore 分离,前端扩展不阻塞推理
  6. Executor 抽象层——UniProc / Multiproc / Ray 同一套接口,部署拓扑和业务逻辑彻底脱钩
  7. Attention Backend 抽象——FlashAttention-2/3、FlashInfer、Triton、ROCm 可插拔

V0 的重要组件在 V1 几乎都有对应的重新实现,但形态完全不同。本书以 V1 为主线讲解,V0 的历史经验作为对照出现——"当年的 V0 是怎么做的 / 后来为什么要改"是理解 V1 设计意图的最短路径。

本书的读者

本书面向这几类人:

读者 典型问题 对应章节
AI 基础设施工程师 生产部署、容量规划、调优 ch02/ch03/ch14/ch17
推理系统研发者 架构设计、工程实践 ch01-ch18 全书
研究者 新算法的工程实现 ch04/ch05/ch10/ch12
技术好奇者 "数十亿 Token 怎么跑" ch01 + ch18
模型部署工程师 选型、参数调优 ch03/ch08/ch13/ch16

前置知识

你不需要精通 CUDA C++,但需要具备:

没有这些前置也能读,只是在某些段落需要查一下维基。

本书的组织

全书 18 章,按"从外到内 → 从核心到外围"的顺序组织:

graph TD
    P1[第一篇 · 全景<br/>ch01]
    P2[第二篇 · 引擎核心<br/>ch02-05]
    P3[第三篇 · 执行层<br/>ch06-09]
    P4[第四篇 · 性能优化<br/>ch10-13]
    P5[第五篇 · 分布式与工程<br/>ch14-18]

    P1 --> P2 --> P3 --> P4 --> P5

    style P1 fill:#dbeafe,stroke:#3b82f6
    style P2 fill:#fef3c7,stroke:#f59e0b
    style P3 fill:#dcfce7,stroke:#22c55e
    style P4 fill:#f3e8ff,stroke:#a855f7
    style P5 fill:#fce7f3,stroke:#ec4899

第一篇 · 全景(第 1 章) : 从一个推理请求的完整生命旅程出发,建立对整个系统的直觉。这是全书的地图。

第二篇 · 引擎核心(第 2-5 章) : 深入 vLLM 的心脏: : - ch02 EngineCore —— 协调者的艺术 : - ch03 Scheduler —— Token 的交通指挥 : - ch04 PagedAttention —— 虚拟内存的启示 : - ch05 KV Cache Manager —— 寸土寸金的显存

第三篇 · 执行层(第 6-9 章) : 从调度决策到 GPU 计算: : - ch06 Worker & Executor —— GPU 军团 : - ch07 模型加载 —— 权重从磁盘到显存 : - ch08 ModelRunner —— 前向计算与 CUDA Graph : - ch09 采样 —— 从 logits 到 Token

第四篇 · 性能优化(第 10-13 章) : 让 vLLM 快人一步的四把利器: : - ch10 前缀缓存 —— 零开销的"记忆" : - ch11 Chunked Prefill —— 把长 prompt 切开 : - ch12 投机解码 —— 以小博大 : - ch13 量化 —— 精度与速度的取舍

第五篇 · 分布式与工程(第 14-18 章) : 从单机走向千卡: : - ch14 分布式并行 —— TP / PP / EP / DP : - ch15 多模态 —— 图像视频入场 : - ch16 LoRA 热切换 —— 一个引擎服务百个微调 : - ch17 API Server & 生产部署 —— 到一线士兵 : - ch18 设计哲学 —— 回看整幅画

每一章的写作节奏

每一章都遵循同样的节奏:

为什么需要 → 怎么设计 → 怎么实现 → 生产中怎么调

(问题域)    (架构思想)  (源码解析)  (实战经验)

理论 → 设计 → 代码 → 实战,循环往复,螺旋上升。

阅读建议

线性读

从第 1 章读到第 18 章,建立完整的知识地图。适合第一次系统学 vLLM 的读者。

模块读

如果你已经熟悉 LLM 推理,直接进第 2-5 章引擎核心,再根据兴趣跳读后面的优化章节。适合想"快速看懂 vLLM 做了什么"的工程师。

问题驱动读

带着具体问题读对应章节:

生产问题 对应章节
线上 p99 TTFT 不稳定 ch03 Scheduler + ch11 Chunked Prefill
KV OOM 频繁 ch04 PagedAttention + ch05 KV Cache + ch10 Prefix Cache
想加一个新模型 ch07 模型加载 + ch08 ModelRunner
想做低延迟推理 ch12 Spec Decode + ch13 量化 + ch08 CUDA Graph
想上多机部署 ch06 Executor + ch14 分布式
想做多租户服务 ch16 LoRA + ch17 API Server
想加新的采样策略 ch09 采样
想优化 batch 大小 ch03 Scheduler + ch10 Prefix Cache
想支持图片输入 ch15 多模态
想做 8-bit/4-bit 部署 ch13 量化

反复读

好的系统设计需要反复回味。第一遍看觉得复杂,第二遍看理解动机,第三遍看感叹优雅。

vLLM 的很多段代码——第一次读和第五次读的理解完全不是一个层次。耐心反复,是读懂它的必要代价。

动手实验:跟着书一起跑 benchmark

每一章都鼓励你亲手实验,不只是读。vLLM 团队提供了现成的 benchmark 工具:

# 启动一个服务
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Meta-Llama-3-8B-Instruct \
  --max-model-len 8192

# 跑 benchmark
python benchmarks/benchmark_serving.py \
  --model meta-llama/Meta-Llama-3-8B-Instruct \
  --dataset-name sharegpt \
  --num-prompts 200

# 对比调度参数
python benchmarks/benchmark_serving.py \
  ... --max-num-batched-tokens 2048      # 默认
python benchmarks/benchmark_serving.py \
  ... --max-num-batched-tokens 8192      # 更大

边读边跑,比任何文档都更深入

一点私心

推理引擎是 AI 基础设施里最"隐形"的一层——用户看到的是 ChatGPT 流畅的回答,应用开发者看到的是 OpenAI 兼容的 API,但很少有人关心中间那个把 Token 一个一个"挤"出来的引擎在干什么。

它就像自来水管道——打开水龙头就有水,但没人想过水是怎么从水库送到你家的。

我希望这本书能让更多人看到管道里的风景。

为什么这很重要

不是每个人都需要自己造管道。但理解管道的人,才能在需要时修好它、改进它,甚至设计出更好的管道

在 AI 大规模落地的今天,推理效率决定了 AI 能服务多少人:

理解推理引擎,就是理解 AI 普惠的底层逻辑

源码不会骗人

vLLM 源码里很多设计第一遍读会疑惑"为什么要这么复杂",对照 issue 和 PR 才理解它解决的是哪个具体问题,再回头读就能看出它的优雅。本书尝试把这个"为什么"前置给读者,让你少走那两遍。

源码不会骗人。框架在变、API 在变,但好的设计思想不会过时。

vLLM 今天用 PagedAttention,明天可能有更好的算法替代它——但"用操作系统的思想管理 GPU 资源"这个跨领域思维,会在你未来的工程生涯里反复发挥价值。

让我们开始这段旅程。


杨艺韬 2026 年 4 月 · 于北京


源码导航