内容简介
《大模型推理系统揭秘:从 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 的方法:
- 先从工作负载定义问题;
- 再用指标定位矛盾;
- 用请求生命周期建立全局视角;
- 从调度、内存和执行三个核心战场深入;
- 将问题扩展到多卡、模型、硬件和计算解耦;
- 最后回到源码,用实现细节验证系统抽象。
沿着这条线阅读,vLLM 不再只是一个“推理框架”,而会呈现为一个持续协调请求、Token、状态、计算、显存和通信的动态系统。
章节目录(建议按顺序阅读)
- 为什么 LLM Serving 比传统 DL 推理难?
- 如何衡量一个 LLM Serving 系统?
- 鸟瞰 vLLM:一个请求如何穿过整个推理系统?
- Scheduler:GPU 这一轮到底给谁用?
- KV Cache:LLM Serving 的第一号内存问题
- GPU 执行:如何让每个 Token 算得更快?
- Multi-GPU:一张卡不够时如何扩展?
- 模型适配:如何跟上变化极快的模型世界?
- 硬件解耦:如何不让芯片差异污染 Serving 核心?
- PD 分离:从资源混部走向计算解耦
- Serving Infra 的下一站:从模型执行器到分布式智能操作系统
- 回到源码:一次请求在 vLLM 内部的真实旅程
版本说明:本系列基于 vLLM v0.27.1(tag
6e448d0,2026-08-11)源码分析。文中路径、类名和行号均以该版本为准;由于 vLLM 迭代较快,阅读时请结合实际版本进行对照。