vLLM V1:vLLM 核心架构的重大升级

我们非常激动地宣布 vLLM V1 的 alpha 版本发布,这是对 vLLM 核心架构的一次重大升级。基于我们在过去一年半 vLLM 开发中积累的经验,我们重新审视了关键设计决策,整合了各项功能,并简化了代码库以提升灵活性和可扩展性。V1 已经实现了业界领先的性能,并计划引入更多优化。最棒的是,用户可以无缝启用 V1——只需设置 VLLM_USE_V1=1 环境变量,无需对现有 API 进行任何更改。在接下来的几周里,经过测试和反馈收集,我们计划将 V1 转变为默认引擎。
为什么选择 vLLM V1?
从 vLLM V0 中汲取经验
在过去的一年半里,vLLM 在支持多种模型、功能和硬件后端方面取得了卓越的成就。然而,随着社区规模的扩大,我们在简化系统和在整个堆栈中垂直整合各种优化方面面临挑战。功能往往是独立开发的,导致难以有效且整洁地结合它们。随着时间的推移,技术债务不断积累,促使我们重新审视基础设计。
V1 的目标
基于上述动机,vLLM V1 旨在:
- 提供一个简单、模块化且易于修改的代码库。
- 确保高性能,并将 CPU 开销降至接近零。
- 将关键优化整合到一个统一的架构中。
- 默认启用各项功能/优化,从而实现零配置使用。
V1 的范围
vLLM V1 对其核心组件进行了全面的架构重构,包括调度器、KV 缓存管理器、工作进程 (Worker)、采样器和 API 服务器。不过,它依然与 vLLM V0 共享大量代码,如模型实现、GPU 内核、分布式控制平面和各类工具函数。这种方法使 V1 能够利用 V0 建立的广泛覆盖范围和稳定性,同时在性能和代码复杂度方面实现显著提升。
vLLM V1 有哪些新功能?
1. 优化的执行循环与 API 服务器

作为一款成熟的连续批处理引擎和兼容 OpenAI 的 API 服务器,vLLM 的核心执行循环依赖 CPU 操作在模型前向传播之间管理请求状态。随着 GPU 速度的提升并大幅缩短了模型执行时间,API 服务器运行、调度任务、准备输入、反标记化 (de-tokenization) 输出以及向用户流式传输响应等任务的 CPU 开销变得越来越明显。在 NVIDIA H100 GPU 上运行 Llama-8B 等较小模型时,这一问题尤为突出,因为 GPU 上的执行时间甚至低至 ~5ms。
在 v0.6.0 版本中,vLLM 引入了利用 ZeroMQ 进行 IPC 的多进程 API 服务器,实现了 API 服务器与 AsyncLLM 的重叠运行。vLLM V1 在此基础上进一步将多进程架构深度集成到 AsyncLLM 的核心中,创建了一个隔离的 EngineCore 执行循环,专注于调度器和模型执行器。这种设计允许更多 CPU 密集型任务(如分词、多模态输入处理、反分词和请求流式传输)与核心执行循环重叠,从而最大化模型吞吐量。
2. 简单且灵活的调度器

vLLM V1 引入了一个既简单又灵活的调度器。它消除了“预填充 (prefill)”和“解码 (decode)”阶段之间的传统区别,将用户给定的提示词标记和模型生成的输出标记统一处理。调度决策表示为一个简单的字典,例如 {request_id: num_tokens},指定了每个步骤中每个请求需要处理的标记数量。我们发现这种表示法非常通用,足以支持分块预填充 (chunked prefills)、前缀缓存和推测解码等功能。例如,分块预填充调度得以无缝实现:在固定的标记预算下,调度器动态决定为每个请求分配多少标记(如上图所示)。
3. 零开销的前缀缓存 (Prefix Caching)
与 V0 一样,vLLM V1 使用基于哈希的前缀缓存和基于 LRU 的缓存驱逐策略。在 V0 中,启用前缀缓存有时会导致显著的 CPU 开销,从而在缓存命中率较低时导致性能下降,因此默认情况下它是关闭的。在 V1 中,我们优化了用于常量时间缓存驱逐的数据结构,并仔细最小化了 Python 对象的创建开销。这使得 V1 的前缀缓存即使在缓存命中率为 0% 时,也能实现近乎零的性能损耗。

以下是一些基准测试结果。在我们的实验中,观察到即使在缓存命中率为 0% 时,V1 的前缀缓存导致的吞吐量下降也低于 1%,而在缓存命中率高时,性能则提升了数倍。得益于近乎零的开销,我们现在在 V1 中默认启用了前缀缓存。
4. 用于张量并行推理的整洁架构

vLLM V1 为张量并行推理引入了一种整洁高效的架构,有效解决了 V0 的局限性。在 V0 中,调度器和 Worker 0 位于同一进程内,以减少向工作进程广播输入数据时的进程间通信开销。然而,这种设计引入了非对称架构,增加了复杂性。V1 通过在工作进程端缓存请求状态并仅在每个步骤传输增量更新(差异)来克服这一问题。这种优化最小化了进程间通信,允许调度器和 Worker 0 在独立进程中运行,从而形成了一个整洁、对称的架构。此外,V1 抽象掉了大部分分布式逻辑,使得工作进程在单 GPU 和多 GPU 设置下都能以相同方式运行。
5. 高效的输入准备

在 vLLM V0 中,模型的输入张量和元数据在每一步都会被重新创建,这往往导致巨大的 CPU 开销。为了优化这一点,V1 实现了 Persistent Batch(持久化批处理) 技术,该技术缓存了输入张量,并仅在每一步对其应用差异。此外,V1 通过大量使用 Numpy 操作而非 Python 原生操作,最大限度地减少了更新张量时的 CPU 开销。
6. torch.compile 与分段 CUDA 图 (Piecewise CUDA Graphs)

V1 利用 vLLM 的 torch.compile 集成来自动优化模型。这使得 V1 能够高效支持各种模型,同时最大限度地减少编写自定义内核的需求。此外,V1 引入了分段 CUDA 图 (piecewise CUDA graphs) 来缓解 CUDA 图的局限性。我们正在准备关于 torch.compile 集成和分段 CUDA 图的专题博文,请敬请期待后续更新!
7. 对多模态 LLM 的增强支持
vLLM V1 将多模态大语言模型 (MLLM) 视为一等公民,并在对其支持方面引入了多项关键改进。
首先,V1 通过将多模态输入预处理移动到非阻塞进程中来优化它。例如,图像文件(如 JPG 或 PNG)在送入模型之前,必须转换为像素值张量、进行裁剪和转换。这种预处理可能会消耗大量 CPU 周期,导致 GPU 空闲。为了解决这个问题,V1 将预处理任务卸载到单独的进程,防止其阻塞 GPU 工作进程,并添加了预处理缓存,以便在请求共享相同的多模态输入时可以重复使用已处理的输入。
其次,V1 为多模态输入引入了前缀缓存。除了标记 ID 的哈希值外,图像哈希也被用于识别图像输入的 KV 缓存。这种改进对于包含图像输入的多轮对话特别有益。
8. FlashAttention 3
vLLM V1 的最后一块拼图是集成了 FlashAttention 3。鉴于 V1 中高度的动态性(例如在同一批次中组合预填充和解码),一个灵活且高性能的注意力内核至关重要。FlashAttention 3 有效地满足了这一需求,在保持各种用例卓越性能的同时,为广泛的功能提供了强大的支持。
性能
得益于广泛的架构增强,vLLM V1 实现了业界领先的吞吐量和延迟,与 V0 相比,吞吐量提升高达 1.7 倍(不包含多步调度)。这些巨大的性能提升源于整个堆栈中 CPU 开销的全面降低。对于 Qwen2-VL 等视觉语言模型 (VLM),由于 V1 对 VLM 的增强支持,这些改进更为显著。
- 文本模型:Llama 3.1 8B 与 Llama 3.3 70B

我们使用 ShareGPT 数据集测量了 vLLM V0 和 V1 在 Llama 3.1 8B 和 Llama 3.3 70B 模型上的性能。得益于更高的吞吐量,V1 在高 QPS 下表现出比 V0 始终更低的延迟。鉴于 V0 和 V1 使用的内核几乎相同,性能差异主要归功于 V1 中的架构改进(减少了 CPU 开销)。
- 视觉语言模型:Qwen2-VL

我们通过测试 Qwen2-VL 使用 VisionArena 数据集来评估 VLM 上的性能。V1 在 VLM 上实现了比 V0 更大的加速,这得益于其改进的 VLM 支持,主要是通过两项关键改进:将输入处理卸载到单独进程以及为多模态查询实现更灵活的调度。此外,我们还要指出,V1 现在原生支持多模态模型的前缀缓存,但此处跳过基准测试结果。
- 展望未来
虽然这些改进意义重大,但我们认为这仅仅是个开始。重新设计的架构提供了一个坚实的基础,将推动新功能的快速开发。我们期待在接下来的几周内分享更多增强功能。敬请关注更多更新!
局限性与未来工作
虽然 vLLM V1 展示了令人期待的结果,但它仍处于 alpha 阶段,且缺少 V0 中的部分功能。以下是说明:
模型支持
V1 支持仅解码器 (decoder-only) 的 Transformer 模型(如 Llama)、混合专家 (MoE) 模型(如 Mixtral)以及多种 VLM(如 Qwen2-VL)。支持所有量化方法。但是,V1 目前不支持编码器-解码器架构(如多模态 Llama 3.2)、基于 Mamba 的模型(如 Jamba)或嵌入模型。请查看我们的文档以获取支持模型的详细列表。
功能局限性
V1 目前不支持 log probs、prompt log probs 采样参数、流水线并行、结构化解码、推测解码、Prometheus 指标和 LoRA。我们正在积极工作以弥补这一功能差距,并为 V1 引擎添加全新的优化。
硬件支持
V1 目前仅支持 Ampere 或更新的 NVIDIA GPU。我们正在积极努力将支持扩展到 TPU 等其他硬件后端。
最后,请注意,如果不设置 VLLM_USE_V1=1,您可以继续使用 V0 并保持向后兼容性。
如何开始使用
要使用 vLLM V1
- 使用
pip install vllm --upgrade安装最新版本的 vLLM。 - 设置环境变量
export VLLM_USE_V1=1。 - 使用 vLLM 的 Python API 或兼容 OpenAI 的服务器(
vllm serve <model-name>)。您无需对现有 API 进行任何更改。
请尝试使用并分享您的反馈!
致谢
我们衷心感谢 vLLM V1 的设计基于并增强了多个开源 LLM 推理引擎,包括 LightLLM, LMDeploy, SGLang, TGI, 以及 TRT-LLM。这些引擎极大地影响了我们的工作,我们从中获得了宝贵的见解。
V1 的重构是整个 vLLM 团队和社区持续共同努力的结果。以下是这一里程碑的贡献者名单(不完整):
- 加州大学伯克利分校 (UC Berkeley)、Neural Magic(现属于 Red Hat)、Anyscale 和 Roblox 主要共同推动了这项工作。
- Woosuk Kwon 发起了该项目并实现了调度器和模型运行器。
- Robert Shaw 实现了优化的执行循环和 API 服务器。
- Cody Yu 实现了针对文本和图像输入的高效前缀缓存。
- Roger Wang 领导了 V1 中多模态大语言模型 (MLLM) 的整体增强支持。
- Kaichao You 领导了 torch.compile 集成并实现了分段 CUDA 图。
- Tyler Michael Smith 实现了基于 Python 多进程的张量并行支持。
- Rui Qiao 实现了基于 Ray 的张量并行支持,目前正在实现流水线并行支持。
- Lucas Wilkinson 添加了对 FlashAttention 3 的支持。
- Alexander Matveev 实现了优化的多模态输入预处理器,目前正在实现 TPU 支持。
- Sourashis Roy 在采样器中实现了 Logit 惩罚。
- Cyrus Leung 领导了 MLLM 输入处理重构工作,并协助将其集成到 V1 中。
- Russell Bryant 解决了多个与多进程相关的问题。
- Nick Hill 优化了引擎循环和 API 服务器。
- Ricky Xu 和 Chen Zhang 协助重构了 KV 缓存管理器。
- Jie Li 和 Michael Goin 协助了 MLLM 的支持和优化。
- Aaron Pham 正在实现结构化解码支持。
- Varun Sundar Rabindranath 正在实现多 LoRA 支持。
- Andrew Feldman 正在实现 log probs 和 prompt log probs 支持。
- Lily Liu 正在实现推测解码支持。
- Kuntai Du 正在实现预填充解耦和 KV 缓存传输支持。
- Simon Mo 和 Zhuohan Li 对 V1 的系统设计做出了贡献。