传统上,更改 vLLM 服务中的 GPU 数量需要添加或移除完整的模型副本,或者使用不同的 GPU 数量重启引擎。随着模型越来越大,每个副本需要更多 GPU,因此按副本扩缩所增加或移除的 GPU 数量也越来越大。将 vLLM 重启以把 DeepSeek V4 Pro 从 16 块 GB200 GPU 扩展到 20 块时,服务中断了 197秒 (详见 性能部分 ),导致这些昂贵的 GPU 被占用却无法生成 token。
在 首篇 Elastic EP 文章中,我们展示了 vLLM 如何在不重启的情况下向正在运行的 DEP 部署(数据并行注意力加专家并行 MoE)添加或移除 GPU。虽然我们避免了重启,但在重新配置的整个过程中服务仍然停止,因为我们要初始化新的 worker、准备扩展后的通信组、加载模型权重,并重复内核预热和 CUDA graph 捕获。在 DeepSeek V4 Pro 基准测试中,这一暂停持续了 从 16 GPU 扩展到 20 GPU 时为 100 秒 , 缩回 16 GPU 时为 56 秒 (完整细节见 性能部分).
。在本文中,我们描述了异步准备和 NIXL EP 如何实现近零停机的 Elastic EP 重新配置。在同一个基准测试中,我们将停机时间缩短为 从 16 GPU 扩展到 20 GPU 时为 0.82 秒 , 缩回 16 GPU 时为 1.96 秒,使我们能够在几乎不影响服务性能的情况下进行扩容和缩容。
将拓扑准备与服务重叠
我们将 vLLM 的重新配置流程重组为两个阶段:后台准备和短暂的提交。现有 worker 使用独立的后台线程来准备并预热目标通信、传输模型权重,并与加入的 worker 同步与执行相关的信息(例如自动调优结果),同时继续使用当前的通信组和 CUDA graph 服务请求。与此同时,加入的 worker 进行初始化、接收模型权重,并准备其通信和 GPU 执行。在提交阶段,vLLM 短暂停止其调度器,激活已准备好的拓扑,然后恢复服务。这些改动已在 异步准备 和 准备/提交优化.
中引入。准备工作涵盖四项主要任务:
- 初始化加入的 worker。 启动它们的进程,并为模型和执行分配存储空间。
- 准备通信。 设置目标通信组并扩展EP通信器。
- 转移模型权重。 通过 NVLink 或 RDMA 将所需的权重从现有 worker 转移到加入的 worker。
- 准备执行。 在加入的工作节点上完成所需的编译、内核预热、调优设置以及 CUDA 图构建。
在提交阶段之后,异步专家并行负载均衡(EPLB)允许新工作节点在现有工作节点处理专家计算的同时开始处理注意力。随后,EPLB 在后台将专家重新分配到扩展后的组中。
主要挑战在于在不涉及或干扰正在处理请求的工作进程的情况下准备通信和 GPU 执行。
就地扩展EP通信
在 NIXL EP 之前,vLLM 中可用的 EP 通信后端采用固定成员机制:每个实例都是针对特定的一组 rank 创建的。增加或移除 rank 需要创建新实例。即使该实例可以在后台创建,仍然存在两个问题。
首先,新旧实例需要各自独立的通信缓冲区和其他资源,包括内存注册、IPC句柄和RDMA队列对(QP)。同时保持两个实例存活会增加通信内存使用量,并且需要重新进行设置,而不是复用现有资源。
第二,切换 EP 通信器会改变 EP 通信内核所使用的缓冲区和通信状态。这会使之前捕获的 CUDA 图失效,必须在恢复服务之前重新捕获。这需要在所有保留的 worker 上针对多种批处理形状重复执行预热和图构建。在我们的 DeepSeek V4 Pro 基准测试中,即使采用异步准备,在提交阶段执行预热和图重新捕获也会导致服务暂停长达 扩容期间的 58 秒 和 缩容过程中的44秒.
为了解决这些问题,我们设计了 NIXL EP,一个为 Elastic EP 量身定制的 EP 通信库。它可以在原位添加或移除 rank,复用相同的 NIXL agent、缓冲区和连接。新对等端可以在现有工作节点继续服务的同时接入,且只有新加入的对等端需要新的连接和注册。NIXL EP 还能在重新配置后保持已捕获的 EP dispatch 和 combine 条目有效,使保留的工作节点能够复用其现有的 CUDA 图。
在准备阶段,vLLM 的后台线程会连接加入的对等节点,但不激活它们。随后提交阶段在不替换通信器的情况下激活已准备好的对等节点。

图 1. 连接并激活新的 EP 对等节点。绿色秩为活跃状态;灰色秩已连接但被屏蔽。在提交阶段,新对等节点被激活,而无需替换 agent 或缓冲区。
vLLM 仍会为目标拓扑创建新的 DP 协调组和 EPLB 组, 但其通信是在捕获的模型前向传播之外进行的因此切换到它们不会使 CUDA 图失效。
在现有 worker 上保留 CUDA graphs
CUDA 图会记录 GPU 操作,使 vLLM 能够重放前向传播,而不必从 CPU 反复启动每个操作。捕获的内核节点包含其启动配置和参数值,包括指向输入和输出张量的指针。内存内容在重放之间可以变化,但记录的指针必须保持有效。这些要求是……的一部分。 CUDA 图执行契约.
vLLM 针对不同的批处理形状和执行模式分别捕获图表 并在每次捕获前运行预热前向传递。
保留已捕获的CUDA图不仅仅需要保持通信器对象存活。NIXL EP还在重新配置时保持内核启动配置、图内可见的通信参数以及输入输出张量地址的稳定。其内核从可原位更新的设备状态中读取活跃组成员信息。
我们还修改了 vLLM,使其在重新配置时保持周围计算内核的捕获参数、启动配置以及输入输出张量地址稳定不变:
- 我们复用已保留 worker 的 fused-MoE 执行对象,而不是为不同的活跃 EP 大小重建它们。
- 我们在重新配置过程中保持图可见工作区的地址和布局以及分发输出的稳定,以便被捕获的专家内核能够继续使用它们。分发输出还作为专家计算的输入。如果它们的地址或布局随 EP 大小而改变,被捕获的专家内核仍会使用旧的指针和偏移量。
- 我们保留了专家路由张量的后备存储,并原位更新映射。这使 EPLB 能够在不移动被捕获内核所使用的张量的情况下更改映射内容。
这些变化共同使得留任的员工能够 复用其已有的 CUDA graphs 在扩容和缩容之后均可。
独立准备加入的 worker
现有 worker 有需要保留的 graphs。加入的 worker 则没有。
加入的 worker 通常通过运行带 EP dispatch 和 combine 的模型前向传播,并与其他 worker 交换 batch 信息来进行准备。这些步骤需要其他 worker 参与,但现有 worker 已经在当前拓扑上服务真实请求。
NIXL EP 允许每个加入的 worker 在预热和 graph 准备期间临时屏蔽所有远程 EP peer。只有该 worker 的本地 rank 参与 EP 通信。我们还修改了 vLLM,使这些准备过程不再等待来自其他 worker 的 DP batch 信息。这使得加入的 worker 能够运行其 dummy batch 并捕获 CUDA graphs,而无需现有 worker 参与。

图 2。绿色 rank 参与 EP 通信;灰色 rank 被屏蔽。现有 worker 一起服务,同时每个加入的 worker 在准备期间屏蔽所有远程 EP peer。
捕获完成后,NIXL EP 可以在不使 graphs 失效的情况下重新激活 peer。加入的 worker 在作为扩展后组的一部分开始服务时,会复用其本地捕获的 graphs。
DeepSeek V4 Pro 上的性能表现
本节中的所有实验均使用 DeepSeek V4 Pro 运行于 GB200 GPU,TP=1,DP/EP 大小分别为 16 和 20。模型权重已预先以 safetensors 格式下载到共享 Lustre 存储上,并使用默认的 --load-format auto加载。测量使用了已预热的内核编译缓存(Triton、TileLang 和 FlashInfer)。
扩容和缩容耗时
该表显示了哪些阶段在服务暂停时运行,哪些阶段在现有工作进程继续提供服务的同时在后台运行。
| 阶段 | A:阻塞 | B:异步准备 | C:异步准备 + 图复用 |
|---|---|---|---|
| 初始化加入的工作进程 | 服务暂停 | 后台 | 后台 |
| 准备目标通信 | 服务暂停 | 后台 | 后台 |
| 传输模型权重 | 服务暂停 | 后台 | 后台 |
| 在加入的工作节点上进行预热和图捕获 | 服务暂停 | 服务暂停 | 后台 |
| 在现有工作节点上进行预热和图捕获 | 服务暂停 | 服务暂停 | 不需要(现有图保持有效) |
| 激活目标拓扑 | 服务暂停 | 服务暂停 | 服务暂停 |
配置 C 受支持 仅由 NIXL EP 支持.
- 停机时间: 所观测到的服务中断时段,此时进行中的请求停止推进,且不接受新请求。
- 总时间: 整个扩缩容操作(包括准备工作)的持续时间。
这两个时长是分别测量的。
| 指标 | A:阻塞式 | B:异步准备 | C:异步准备 + 图复用 |
|---|---|---|---|
| 16 到 20 GPU:停机时间 | 99.62 s | 58.04 s | 0.82 s |
| 20 到 16 GPU:停机时间 | 56.25 s | 44.07 s | 1.96 s |
| 16 到 20 GPU:总时间 | 99.72 s | 97.27 s | 92.34 s |
| 20 到 16 GPU:总时间 | 56.21 s | 51.46 s | 9.32 s |
所有配置均通过了数值正确性检查,包括对每个加入的 worker 进行的检查。
在增加 GPU 的同时保持 SLO
我们在 16 个 GPU 上服务 DeepSeek V4 Pro,然后逐步将传入请求速率从约每秒 8 个请求提高到每秒 16 个请求。我们针对三种部署重放了相同的 11,391 个请求场景:一个保持在 16 个 GPU,一个以 20 个 GPU 重启,另一个使用 Elastic EP 与 NIXL EP 扩展到 20 个 GPU。服务水平目标(SLO)是滚动 p95 首 token 时间低于 5 秒。

图 3. 请求负载上升下的端到端服务。曲线显示 30 秒滚动 p95 结果,失败请求被赋予 30 秒的惩罚值而非实际测量的 TTFT。
- Elastic EP 完成了全部 11,391 个请求,并在整个场景中保持低于 SLO。
- 在准备期间,Elastic EP 与静态的 16 GPU 部署服务性能相当,后台准备没有造成可见的性能下降。
- 扩展完成后,Elastic EP 与恢复后的 20 GPU 部署性能相当,扩展后没有可见的性能下降。
试用 Elastic EP
后台准备、CUDA 图复用以及在加入的 worker 上独立进行图捕获,现已在最新版 vLLM 和 NIXL 发布版本中全部可用。使用 pip 安装它们并开始使用 Elastic EP。
完整的使用示例请参见 cuda_graphs_heavy_nixl_ep vLLM 的 Elastic EP 测试用例。该示例包含服务器配置和扩展 API 调用。它在发送请求的同时从两个 GPU 扩展到四个再缩回,并检查准备期间的服务状态以及每次缩放前后的模型准确性。
下一步计划
使用 Dynamo Snapshot 恢复热身 worker
我们已经有效解决了长时间服务中断的问题。下一个挑战是更快地准备好新容量。我们计划集成 Dynamo 快照 这样新加入的 worker 可以恢复已初始化的进程和 CUDA 状态,而不必重复编译、内核预热、图构建和其他启动工作。
目标拓扑的通信必须单独准备,因为它不会从快照中恢复。从 checkpoint 存储恢复大型模型权重可能占用大部分恢复时间,因此我们计划改为保留 Elastic EP 现有的 worker 之间 GPU 到 GPU 的权重传输。
通过 NIXL EP 实现最先进的 EP 通信
我们的目标是通过 NIXL EP 实现最先进的 dispatch 和 combine 性能,同时保持对 Elastic EP 和容错能力的完整支持。即将推出的 NIXL EP 性能更新是实现这一目标的下一步(参见 NIXL EP 路线图 RFC).
将 Elastic EP 连接到 Dynamo 和 llm-d 编排
在引擎级能力就绪之后,下一步是让编排器自动伸缩器使用 Elastic EP。相关的集成工作已经在 vLLM、Dynamo 和 llm-d 社区中展开。
这些工作包括 vLLM 的外部负载均衡器工作 以及 Dynamo 的 Elastic EP 提案.
如果您大规模运行推理,我们鼓励您尝试 Elastic EP 并分享您的工作负载和运维需求。如果您构建推理基础设施,我们欢迎为 vLLM Elastic EP 和 NIXL EP 做出贡献。让我们让 Elastic EP 在生产环境中运行起来。
致谢
- 感谢 Red Hat 的 Tyler Michael Smith 和 Sage Moore,他们在这项工作全程中提供了宝贵的反馈和细致的审阅。
- 感谢 Linoy Geva(NVIDIA)在准备期间在服务性能方面的工作。
- 感谢整个 NIXL 团队在 NIXL EP 上的努力。
- 感谢 Tzu-Ling Kan、Julien Mancuso 以及整个 Dynamo 团队在 Dynamo 中支持 Elastic EP 所付出的努力。
