内容简介

《大模型推理系统揭秘:从 vLLM 看 LLM Serving Infra 核心技术》以 vLLM v0.27.1 为主要分析对象,从 LLM Serving 的问题本质出发,系统讲解请求生命周期、性能指标、调度、KV Cache、GPU 执行、多卡并行、模型适配、硬件抽象、Prefill/Decode 分离与集群化部署。

本书不局限于算子优化,也不止于源码解读,而是试图回答一个更完整的问题:

一个文本生成请求,为什么会逐渐演化成一个涉及计算、显存、调度、通信与状态管理的复杂系统?

在这个视角下,LLM Serving 不再只是“把模型跑起来”,而是一个持续协调请求、Token、计算资源、中间状态和网络通信的动态系统。

文章将按照以下主线展开:

问题定义 → 指标体系 → 系统全景 → 单机性能优化 → 多卡与集群扩展 → 模型与硬件适配 → 未来演进展望 → 源码落地

读者可以按顺序建立完整认知,也可以根据自身关注点选择调度、KV Cache、GPU 执行、多卡并行或集群 Serving 等主题阅读。

为什么写这个系列?

大模型能力快速演进,但真正决定其能否稳定、低成本、大规模服务用户的,往往不是模型本身,而是模型背后的 Serving Infra。

目前关于 LLM 推理的讨论,常常分散在几个局部方向:

  • 有的关注 CUDA Kernel、量化和算子性能;
  • 有的关注 Batch、调度和吞吐;
  • 有的关注 KV Cache 或 PagedAttention;
  • 有的直接进入源码,罗列类名和调用链。

这些内容各自重要,却容易让读者难以形成整体认识:不同技术究竟在解决什么问题?它们之间如何相互影响?为什么某项优化在一个场景有效,在另一个场景却可能带来新的瓶颈?

本系列文章希望提供一种系统化视角:

LLM Serving 的本质,是围绕生成过程,对请求、Token、计算资源和中间状态进行持续协调。

从这个角度看:

  • 调度解决“这一轮为哪些请求计算多少 Token”;
  • KV Cache 解决“历史状态如何保存、复用和释放”;
  • 执行优化解决“已经分配的计算如何高效完成”;
  • 多卡并行解决“计算如何切分、状态如何组织”;
  • 集群化部署解决“计算、状态和请求如何跨设备、跨实例流动”。

选择 vLLM,是因为它集中体现了现代 LLM Serving 的许多关键思想,也提供了观察推理系统演进的典型样本。本书既关注 vLLM 的具体实现,也希望借此建立一套可以迁移到其他推理框架和 AI 基础设施的分析方法。

适合哪些读者?

本系列主要面向以下读者:

AI Infra 与推理系统工程师

适合负责模型部署、推理服务、GPU 资源管理、性能优化和在线系统建设的工程师。

如果你已经能够部署模型,但希望进一步理解以下问题,本系列会比较适合:

  • 吞吐和时延究竟由什么决定;
  • Continuous Batching 与 Chunked Prefill 如何工作;
  • KV Cache 为什么会成为核心瓶颈;
  • 多卡并行和 Prefill/Decode 分离如何进行工程权衡;
  • 如何从源码定位性能和稳定性问题。

大模型应用与平台工程师

适合负责 LLM API、RAG、Agent、模型网关和推理平台的开发者。

即使不直接编写 CUDA Kernel,也有必要理解:

  • 请求为什么会排队;
  • 长上下文为什么会显著增加成本;
  • 不同模型和硬件为什么需要不同适配;
  • 如何根据业务目标选择部署和扩展方案。

计算机系统与机器学习系统研究者

适合关注操作系统、分布式系统、编译器、计算机体系结构和机器学习系统的学生、研究人员与技术人员。

本系列将从一个真实的工程系统出发,讨论:

  • 生成式工作负载如何改变传统推理范式;
  • 动态调度与状态管理之间的关系;
  • GPU、网络和分布式系统如何共同影响服务性能;
  • AI Serving 为什么逐渐呈现出分布式系统甚至操作系统的特征。

希望系统学习 LLM Serving 的开发者

适合已经掌握 Python、深度学习和 Transformer 基础,希望从“会调用推理框架”进一步走向“理解推理框架如何工作”的读者。

不要求一开始就掌握 CUDA、分布式训练或 vLLM 的全部源码,但需要具备基本的模型推理和系统知识。

章节结构与分章导读

1. 先定义问题:Serving 到底难在哪里?

第一章从工作负载本质出发,解释 LLM 推理为什么不同于传统的静态 Batch 推理。

我们会看到,Prefill 更像一次高并行度的批量计算,而 Decode 更像大量低计算量、强状态依赖的迭代计算。两者混合在同一个服务系统中,带来了批处理、调度、显存管理和时延控制上的连锁问题。

这一章的目标不是介绍某个具体实现,而是回答:

  • LLM Serving 的基本计算单元是什么?
  • 为什么请求之间很难保持同步?
  • 为什么“模型能跑”并不等于“服务系统能高效运行”?
  • 后续所有优化究竟是在解决哪一类瓶颈?

只有先把问题定义清楚,后面的技术才不会变成彼此孤立的名词。

2. 再建立指标:系统到底好不好?

当问题边界明确之后,第二章讨论如何衡量系统。

吞吐、TTFT、ITL、E2E Latency、并发数、显存占用等指标,分别描述了系统的不同侧面。它们并不是可以随意替换的“性能数字”,而是对应不同的用户体验、资源瓶颈和优化方向。

例如:

  • TTFT 变差,可能意味着 Prefill 排队或调度受阻;
  • ITL 变差,可能意味着 Decode 阶段受到带宽、通信或批次膨胀影响;
  • 吞吐下降,可能意味着 GPU 利用率不足,也可能意味着 KV Cache 容量限制了并发;
  • 显存占用升高,未必代表计算更充分,也可能意味着状态管理效率较差。

因此,本系列会把指标与系统动作连接起来:

先判断哪个指标出了问题,再判断问题发生在哪个阶段,最后决定应该优化调度、内存、执行还是通信。

3. 接着画全景:一个请求如何穿过系统?

第三章不急于深入某个局部,而是先建立 vLLM 的全局地图。

我们会从两个视角观察系统:

  • 静态视角:有哪些核心组件、对象和执行角色;
  • 动态视角:一个请求从进入、排队、Prefill、Decode,到完成和资源回收,经历了哪些状态变化。

这一章解决的是“对象在哪里、请求怎么流动、模块如何协作”的问题。后续章节中的 Scheduler、KV Cache Manager、Worker、Model Runner、Executor 等概念,都会回到这条请求链路中重新定位。

这样做的目的,是避免只记住局部类名和函数名,却无法理解它们在完整生命周期中的作用。

4. 然后进入第一个核心战场:调度

当多个请求同时进入系统,最直接的问题就是:

GPU 下一轮计算,究竟应该服务哪些请求、多少 Token,以及以什么顺序服务?

第四章围绕这个问题展开,讨论 Continuous Batching、Chunked Prefill、Token Budget、Admission Control 和 Preemption。

这里的调度并不是简单的队列管理,而是在多个目标之间持续做权衡:

  • 尽可能提高 GPU 利用率;
  • 控制请求的首 Token 时延;
  • 保证 Decode 的持续推进;
  • 防止长 Prefill 阻塞短请求;
  • 在显存不足时决定是否暂停、换出或拒绝请求。

调度因此成为连接“用户体验”和“硬件利用率”的第一层控制面。

5. 再进入第二个核心战场:内存与状态

调度决定“谁来计算”,但系统还必须回答另一个问题:

这些请求已经计算过的历史状态,应该放在哪里、如何复用、何时释放?

第五章以 KV Cache 为中心,解释 PagedAttention、Block 管理、分配与回收、Prefix Cache 以及相关的生命周期控制。

KV Cache 并不是普通的临时张量。它是 Decode 阶段持续依赖的请求状态,也是限制并发规模、影响调度策略和决定扩展方式的关键资源。

因此,本系列会把 KV Cache 放在比“显存优化技巧”更高的位置来理解:

LLM Serving 的核心,不只是执行模型,更是持续管理模型生成过程中的状态。

这一视角也会自然引出后面的 PD 分离、KV Transfer 和集群路由问题。

6. 再看第三个核心战场:执行效率

有了调度和内存管理之后,还需要回答:

在已经选定的请求和 Token 上,GPU 如何把每一步计算做得更快?

第六章进入执行层,讨论 Kernel Launch、CUDA Graph、算子融合、显存带宽、低精度、投机解码等技术。

这一章重点区分两类常被混淆的问题:

  • 系统没有把 GPU 喂饱:通常与调度、Batch 组织或数据准备有关;
  • GPU 已经在工作,但每一步仍然很慢:通常与 Kernel、访存、同步、通信或执行形态有关。

通过这种区分,可以更准确地理解为什么 GPU 算力很强,LLM Serving 仍然可能受限于带宽、Launch Overhead 或小规模 Decode。

7. 从单卡走向多卡:扩展会引入什么新问题?

单卡上的调度、内存和执行问题,在多卡环境中会进一步叠加通信和拓扑约束。

第七章比较 DP、TP、PP、EP、CP 等并行方式,重点不在于罗列概念,而在于说明它们分别解决什么问题、引入什么代价,以及适合什么场景。

核心关注点包括:

  • 计算如何切分;
  • KV Cache 如何组织;
  • 卡间通信发生在哪里;
  • 通信能否与计算重叠;
  • 并行策略如何受到模型结构和硬件拓扑影响。

这一章希望建立一个基本判断框架:

多卡扩展不是简单地“增加 GPU 数量”,而是重新设计计算、状态和通信之间的关系。

8. 从固定模型走向模型生态:抽象如何承受变化?

模型结构正在快速演进。不同模型可能在 Attention、MoE、位置编码、缓存布局、权重格式和执行路径上存在明显差异。

第八章讨论 Serving 系统如何承接这些差异,并分析模型适配从临时 Patch 走向体系化抽象的过程。

这里关注的并不只是“新模型能不能运行”,还包括:

  • 模型差异应该被隔离在哪一层;
  • 通用执行路径如何复用;
  • 特殊结构如何获得专门优化;
  • 新增适配是否会污染核心代码;
  • 正确性、性能和可维护性如何同时保证。

最终需要区分两个层次:

能跑,是模型适配的起点;能够高效、稳定、可维护地运行,才是 Serving Infra 的真正目标。

9. 从单一硬件走向多后端:如何保持核心稳定?

当 Serving 系统需要支持不同 GPU、不同加速器和不同软件栈时,硬件差异不能无限向上渗透。

第九章围绕 Platform、Backend、Device、Kernel 和执行后端之间的边界展开,讨论硬件抽象的价值与局限。

真正的硬件解耦,并不是把所有差异都藏起来,而是明确:

  • 哪些逻辑属于 Serving 核心;
  • 哪些逻辑属于硬件平台;
  • 哪些算子必须针对设备单独实现;
  • 哪些性能特性无法通过统一抽象抹平;
  • out-of-tree 适配在什么情况下合理、又会付出什么维护成本。

这一章会把“可移植性”从口号还原成具体的代码组织和职责边界问题。

10. 从资源混部走向计算解耦:为什么需要 PD 分离?

当模型规模、请求量和服务目标继续增长时,单个实例同时承担 Prefill 和 Decode,可能不再是最优选择。

第十章讨论 Prefill/Decode Disaggregation,以及由此带来的 KV Transfer、路由、网络、状态亲和性和故障恢复问题。

PD 分离并不是简单地把两个阶段部署到不同机器上。它重新定义了请求状态的流动方式:

  • Prefill 产生的 KV Cache 如何传给 Decode;
  • 请求应该路由到哪一个实例;
  • 网络传输成本是否抵消了计算收益;
  • 如何处理实例负载变化和状态迁移;
  • 故障发生时,状态是否能够恢复或重建。

因此,是否采用 PD 分离,最终取决于工作负载、硬件资源、网络条件和服务目标,而不是某个单一的性能结论。

11. 从执行器走向系统:Serving Infra 的下一站

前面的章节主要围绕“如何把请求执行得更好”,第十一章则进一步抽象:

未来的 Serving 系统,是否会从一个模型执行器,演化为管理计算、内存、通信和状态的分布式系统?

这一章讨论状态平面、自动并行、弹性伸缩、故障恢复、异构资源调度以及面向 Agent 的长生命周期任务等方向。

随着请求变长、交互变多、模型组合变复杂,Serving 系统管理的对象将不再只是一次推理,而可能是持续存在的上下文、工具调用、缓存状态和跨服务任务。

因此,所谓“AI Serving Operating System”,并不是一个简单的新名词,而是对这一演进方向的概括:

把模型推理从一次函数调用,提升为由系统统一管理的计算与状态过程。

12. 最后回到源码:把抽象还原成工程事实

最后一章回到 vLLM v0.27.1 源码,将前面建立的概念映射到具体对象、模块和调用链。

我们会沿着一次请求的真实生命周期,串起:

  • 请求如何进入系统;
  • Scheduler 如何决定本轮执行内容;
  • KV Cache 如何分配和更新;
  • Worker 与 Model Runner 如何执行计算;
  • 输出如何返回;
  • 请求结束后资源如何回收。

源码阅读不会被当作独立的“附录”,而是作为前面所有抽象的验证过程:

如果一个概念无法在对象、状态变化和调用链中找到对应关系,它就还没有真正落地。

最终,这组文章希望形成的不是一份 API 说明,也不是若干优化技巧的集合,而是一套理解 LLM Serving 的方法:

  1. 先从工作负载定义问题;
  2. 再用指标定位矛盾;
  3. 用请求生命周期建立全局视角;
  4. 从调度、内存和执行三个核心战场深入;
  5. 将问题扩展到多卡、模型、硬件和计算解耦;
  6. 最后回到源码,用实现细节验证系统抽象。

沿着这条线阅读,vLLM 不再只是一个“推理框架”,而会呈现为一个持续协调请求、Token、状态、计算、显存和通信的动态系统。

章节目录(建议按顺序阅读)

  1. 为什么 LLM Serving 比传统 DL 推理难?
  2. 如何衡量一个 LLM Serving 系统?
  3. 鸟瞰 vLLM:一个请求如何穿过整个推理系统?
  4. Scheduler:GPU 这一轮到底给谁用?
  5. KV Cache:LLM Serving 的第一号内存问题
  6. GPU 执行:如何让每个 Token 算得更快?
  7. Multi-GPU:一张卡不够时如何扩展?
  8. 模型适配:如何跟上变化极快的模型世界?
  9. 硬件解耦:如何不让芯片差异污染 Serving 核心?
  10. PD 分离:从资源混部走向计算解耦
  11. Serving Infra 的下一站:从模型执行器到分布式智能操作系统
  12. 回到源码:一次请求在 vLLM 内部的真实旅程

版本说明:本系列基于 vLLM v0.27.1(tag 6e448d0,2026-08-11)源码分析。文中路径、类名和行号均以该版本为准;由于 vLLM 迭代较快,阅读时请结合实际版本进行对照。


×