开发者生态
morning
vLLM 内部:高通量 LLM 推理系统剖析 (2025)
2026-08-07
1 阅读
约7分钟阅读
sebg
字号:
在这篇文章中,我将逐步介绍构成现代高通量 LLM 推理系统的所有核心系统组件和高级功能。我将特别详细介绍 vLLM [1] 的工作原理。这篇文章是该系列的第一篇。它从广泛开始,然后详细分层(遵循反金字塔方法),这样您就可以形成整个系统的准确的高级心理模型,而不会淹没在细节中。后面的帖子将深入探讨特定的子系统。这篇文章分为五个部分: LLM 引擎和引擎核心:vLLM 的基础知识(调度、分页注意力、连续批处理等) 高级功能:分块预填充、前缀缓存、引导和推测解码、分解 P/D 扩展:从单 GPU 到多 GPU 执行 服务层:分布式/并发 Web 脚手架 基准和自动调优:测量延迟和吞吐量 📝 注释 分析是基于提交 42172ad(2025 年 8 月 9 日)。目标受众:任何对最先进的 LLM 引擎如何工作感到好奇的人,以及有兴趣为 vLLM、SGLang 等做出贡献的人。我将重点关注 V1 引擎。我还探索了 V0(现已弃用),这对于理解项目的演变非常有价值,并且许多概念仍然沿用至今。关于 LLM 引擎/引擎核心的第一部分可能有点令人难以承受/干燥 - 但博客的其余部分有大量的示例和视觉效果。 :) LLM 引擎和引擎核心 LLM 引擎是 vLLM 的基本构建块。就其本身而言,它已经可以实现高吞吐量推理 - 但仅限于离线设置。您还无法通过网络向客户提供服务。我们将使用以下离线推理片段作为我们的运行示例(改编自 basic.py )。 from vllm import LLM , SamplingParams提示 = [ "你好,我的名字是" , "美国总统是" , ] Sample_params = SamplingParams ( 温度 = 0.8 , top_p = 0.95 ) def main ( ) : llm = LLM ( model = "TinyLlama/TinyLlama-1.1B-Chat-v1.0" ) 输出= LL.M. generate (promps,sampling_params) if __name__ == "__main__" : main () 📝 环境变量: VLLM_USE_V1="1" # 我们使用引擎 V1 VLLM_ENABLE_V1_MULTIPROCESSING="0" # 我们在单个进程中运行此配置是:离线(没有 Web/分布式系统脚手架)同步(所有执行都发生在单个阻塞进程中)使用标准变压器的单 GPU(无数据/模型/管道/专家并行性;DP/TP/PP/EP = 1)[2](支持像 Jamba 这样的混合模型需要更复杂的混合 KV 缓存内存分配器)从这里开始,我们将逐步构建一个在线、异步、多 GPU、多节点推理系统 - 但仍提供标准变压器。在这个例子中,我们做了两件事: 实例化一个引擎 调用它的generate来从给定的提示中进行采样 让我们开始分析构造函数。 LLM 引擎构造函数 引擎的主要组件是: vLLM 配置(包含用于配置模型、缓存、并行性等的所有旋钮) 处理器(通过验证、标记化和处理将原始输入转换为 EngineCoreRequests) 引擎核心客户端(在我们的运行示例中,我们使用 InprocClient ,它基本上 == EngineCore ;我们将逐步构建到允许大规模服务的 DPLBAsyncMPClient) 输出处理器(转换原始 EngineCoreOutputs → RequestOutput用户看到的)📝注意:随着 V0 引擎被弃用,类名称和详细信息可能会发生变化。我将强调核心思想而不是确切的签名。我将抽象出一些但不是全部的细节。引擎核心本身由几个子组件组成: 模型执行器(驱动模型上的前向传递,我们目前正在处理 UniProcExecutor,它在单个 GPU 上有一个工作进程)。我们将逐步构建支持多个 GPU 的 MultiProcExecutor 结构化输出管理器(用于引导解码 - 我们稍后会介绍) 调度程序(决定哪些请求进入下一个引擎步骤) - 它还包含: 策略设置 - 可以是 FCFS(先到先服务)或优先级(首先服务较高优先级的请求) 等待和运行队列 KV 缓存管理器 - 分页注意力的核心 [3] KV 缓存管理器维护一个 free_block_queue -可用 KV 缓存块池(通常约为数十万,具体取决于 VRAM 大小和块大小)。在分页注意力期间,块充当索引结构,将令牌映射到其计算的 KV 缓存块。本节中描述的核心组件及其关系 标准转换器层(非 MLA [4] )的块大小计算如下: 2 (key/value) * block_size (default=16) * num_kv_heads * head_size * dtype_num_bytes (例如 2 for bf16) 在模型执行器构建期间,创建一个 Worker 对象,并执行三个关键过程。 (后来,使用 MultiProcExecutor ,这些相同的过程在不同 GPU 上的每个工作进程上独立运行。) 初始化设备:分配一个 CUDA d
这篇文章对您有帮助吗?
订阅66必读
每日精选科技资讯,直达你的邮箱