目录
- 摘要
- 扩容如何建立在恢复机制之上
- 一个逻辑部署,三层协同
- 在线 EP 组如何增长
- 衡量过渡过程
- 路线图
- 扩容后的 EPLB
- CUDA 图重新捕获
- 多 rank DP 注意力分片
- 缩容与恢复
- 试用弹性 EP 扩容
- 结论
- 参考文献
- 致谢
推理部署在变化的负载下运行,必须在保持吞吐量和延迟目标的同时调整容量。对于大型混合专家(MoE)模型,标准选项是水平扩展(增加另一个完整副本)和垂直扩展(以更宽的专家并行拓扑重启部署)。
水平扩展保持当前服务运行,但会增加完整的模型占用。垂直扩展可以用更小的增量达到所需拓扑,但需要重建分布式状态、重新加载模型并预热新部署。
弹性扩容基于恢复流程中已实现的原则。在恢复中,活动成员会意外变化;而在扩容中,变化是计划内的,新的 GPU rank 在运行时加入。在下面的示例中,一个 20 GPU 的部署通过增加四个 rank 扩展到 24 GPU,而无需替换正在运行的部署。

图 1:一个说明性的 20→24 GPU 示例。弹性 EP 扩容向正在运行的部署增加四个 rank,而不是分配另一个 20 GPU 副本或替换作业。
摘要
-
弹性 EP 扩容让 MoE 模型能够以细粒度增量增加 GPU,而无需部署完整副本或重启正在运行的部署。
-
max_ep_size定义了部署可达到的最大 EP 拓扑。元数据和通信缓冲区容量在启动时预留,而额外的 GPU rank 仅在需要时启动。 -
在报告的对比中,弹性 EP 扩容完成首个请求的速度比重启快 5.3×–8.2×。
扩容如何建立在恢复机制之上
在每次 MoE 前向计算中,token 激活会传输到拥有所选专家的 rank,输出则返回其源 rank。SGLang 的 大规模 EP 工作 解释了为什么这条专家分发路径对高并发和长上下文服务很重要。使用数据并行(DP)注意力时,每个逻辑 DP worker 保留自己的调度器和 KV 缓存,而专家层则跨 EP 拓扑通信。
运行时扩容直接建立在 SGLang 的 弹性 EP 故障恢复工作之上。两者都使用活动/非活动成员关系、Mooncake 进程组(Mooncake PG)准入以及前向结束时的过渡钩子。恢复将 rank 带回现有槽位及其原始进程组。扩容则激活最大尺寸 active_ranks 向量中未使用的尾部槽位,并准入加入的 rank。
一个约束塑造了该设计:启动时的进程组是静态的。因此,原始 rank 和每个加入组保持固定的张量并行(TP)和引导组,而 Mooncake WORLD 和逻辑 EP 成员关系在其上增长。

图 2:EP4→EP6 保持原始四 rank 启动组不变,将两个加入 rank 准入 Mooncake WORLD,并扩展 NIXL 的目标对等集合。
一个逻辑部署,三层协同
-
SGLang 拥有服务控制平面。 它等待请求的加入 rank,分别跟踪
pending_ep_size和effective_ep_size, 在前向结束时安装目标专家和 DP 状态,并且仅在提交后暴露新的调度器槽位。 -
Mooncake PG 实现弹性成员关系和同步。 其可扩展的
WORLD准入加入者,并提供覆盖现有成员和加入者的屏障。SGLang 还使用 Mooncake PG 集合通信和 P2P 来协调扩容后的 EPLB。 -
NIXL 提供专家数据平面。 NIXL EP 在每次 MoE 前向中分发 token 激活并合并专家输出。SGLang 的集成位于 NIXL 调度器.
中。随着 SGLang 扩展 EP 组,NIXL 保留已建立的对等连接。在 EP4→EP6 中,原始 rank 保留现有连接并添加 rank 4 和 5;加入者连接到 EP6 对等集合。SGLang 预先为 max_ep_size 配置 NIXL 元数据和 RDMA 缓冲区,而最初只连接活动 rank。连接仍然是惰性完成的,因此第一次更宽的分发可能包含一些设置成本。
将 max_ep_size 设置为部署预期达到的最大拓扑。更高的上限会在活动 GPU 上预留更多通信缓冲区内存,从而为 KV 缓存留下更少内存。
在线 EP 组如何增长
在高层次上,SGLang 先准备加入者,然后提交更宽的拓扑:
-
预留上限。 主节点通过
max_ep_size分配元数据和通信缓冲区容量。非活动槽位不会启动进程或占用 GPU。 -
启动加入的 rank。 外部编排器分配 GPU 并启动它们,而现有 EP 组继续服务。
-
准入并提交。 SGLang 等待完整的请求 rank 范围,扩展 Mooncake
WORLD, 安装目标活动 rank、专家、DP 和 NIXL 状态,并同步每个 rank。启用 CUDA 图时,rank 会在提交新尺寸之前重新捕获它们。只有到那时,commit_scale()才会推进有效尺寸。 -
路由并重新平衡。 数据并行控制器暴露新的逻辑 worker。NIXL 执行第一次更宽的专家分发,之后 EPLB 可以重新分配专家。
加入的 rank 进入 Mooncake WORLD后,尚不支持自动回滚;最终化期间的失败可能需要重启部署。
衡量过渡过程
我们使用 DeepSeek-V3-Lite FP8 在 8×H100 上对比了 Elastic EP Scaling 与重启。对于 Elastic EP Scaling,加入者在后台初始化,而现有部署继续提供服务。重启计时在源部署终止之前开始。在多次重复的 Elastic 运行中,每次过渡都已完成并通过扩容后的 GSM8K 验证。图 3 报告了 Elastic 的平均时间,以及具有相同 CUDA 图捕获范围的重启基线。
端点是在就绪后发出的短金丝雀请求。Elastic 就绪意味着在目标规模下 /is_scaling_elastic_ep 报告 serving_expanded ;重启就绪意味着 /health_generate 返回 HTTP 200。Elastic 金丝雀请求针对新的逻辑 DP rank,而重启使用轮询路由。

图 3:从扩容或重启请求到目标拓扑上首个完成请求的时间。Elastic 柱状图显示重复运行的平均值;重启柱状图显示对比基线。CUDA 图行捕获了直至批次 16 的五个完整解码形状。
在拓扑过渡期间,token 交付会暂停。图 3 测量从扩容请求到扩展部署上首个完成请求的时间,包括任何首次使用的连接建立。
路线图
| 分期 | 能力 | 2026 年 10 月 4 日状态 |
|---|---|---|
| 1/N | 运行时 eager EP 扩容 | 已合并于 PR #30164 |
| 2/N | 扩容后的 EPLB | 已合并于 PR #30553 |
| 3/N | 完整解码 CUDA 图重新捕获 | 已合并于 PR #33723 |
| 4/N | DP-attention 分片粒度的扩展 | 已合并于 PR #33728 |
| 稍后 | 缩容与回增 | PR #33111 审核中 |
| 稍后 | 完全空闲进度 | 计划中 |
| 稍后 | 扩容后的恢复 | 计划中 |
扩容后的 EPLB
扩容提交后,SGLang 在扩展后的拓扑上恢复现有的 EPLB 重新洗牌,使新加入的 rank 能够接收专家。
CUDA 图重新捕获
在 EP4 捕获的图包含依赖拓扑的状态,无法在 EP6 原样重放。最初的扩容路径支持 eager 执行。随着 PR #33723 现已合并,SGLang 还会在提交前为扩展后的拓扑重新捕获完整解码 CUDA 图。预填充和分段重新捕获仍不受支持。
在 256 个 GSM8K 示例和 50 个请求线程的多次重复运行中,扩容后的平均输出吞吐量为:
| 过渡 | Eager | 完整解码 CUDA 图 |
|---|---|---|
| EP4→EP6 | 371 tok/s | 1,241 tok/s |
| EP7→EP8 | 358 tok/s | 1,120 tok/s |
在此设置下,完整解码 CUDA 图的平均输出吞吐量比 eager 执行高 3.1×–3.3×。
多 rank DP-attention 分片
合并后的布局将一个物理 EP rank 映射到一个逻辑 DP worker。后续的 PR #33728 允许一个 DP-attention 副本跨越 attention TP × attention CP 物理 rank,其中 CP 表示上下文并行(Context Parallelism)。在 TP2 和 CP1 下,加入 rank 4–5 会将 DP2/EP4 扩展为 DP3/EP6;加入 rank 6–7 则达到 DP4/EP8。该 API 仍以物理 EP 单位表达目标。

图 4:DP-attention 后续工作将 rank 4–5 作为一个 TP2/CP1 分片接纳,将 DP2/EP4 扩展为 DP3/EP6。
缩容与恢复
后续的 PR #33111 探讨了通过预缩容和退役 rank 状态实现缩容与回增。扩容后的恢复同样必须恢复最后提交的扩展拓扑,而不是启动拓扑。
尝试弹性 EP 扩容
该扩容 API 负责接纳进程;它不分配 GPU。运维人员必须:
-
使用 Mooncake、NIXL、初始 EP 大小以及更大的
max_ep_size. -
启动加入的 rank,使用
--elastic-ep-join-mode scale以及下一个连续 rank 偏移量。 -
请求绝对目标并轮询,直到
effective_ep_size达到该目标。
此示例从 EP4 开始,添加四个 rank 以达到 EP8。有关完整的启动和验证序列,请参阅 扩容测试。以下标志展示了 eager 执行的扩容设置:
primary and joiners:
--elastic-ep-backend mooncake
--moe-a2a-backend nixl
--elastic-ep-initial-size 4
--max-ep-size 8
--enable-dp-attention --enable-dp-lm-head
--deepep-mode low_latency
--load-balance-method round_robin
--cuda-graph-backend-decode disabled
--cuda-graph-backend-prefill disabled
joiners:
--elastic-ep-join-mode scale
--elastic-ep-join-rank-offset 4
然后请求并轮询:
curl -X POST http://<PRIMARY_HOST>:21000/scale_elastic_ep \
-H 'Content-Type: application/json' \
-d '{"new_ep_size": 8}'
curl http://<PRIMARY_HOST>:21000/is_scaling_elastic_ep
POST 表示已接受,而非已完成。已完成的 EP8 过渡会报告 effective_ep_size: 8, pending_ep_size: null, scale_phase: serving_expanded,且没有错误。
结论
弹性 EP 扩展让 SGLang 最多可添加 GPU rank 至 max_ep_size 而不替换正在运行的部署。它为大型 MoE 模型提供了更细的扩缩单位:只添加下一个拓扑所需的 rank,而现有 rank 在准备期间继续提供服务。
剩余工作遵循相同的协议:准备依赖拓扑的状态,同步每个成员,并且仅在提交后暴露新拓扑。更宽的 DP-attention 布局、缩容、空闲进度以及扩容后的恢复,都建立在已合并的扩容和图重捕获工作之上。
参考文献
致谢
Cheng Wan 和 Shangming Cai 协助完成了上游集成,Xun Sun 构建了本工作所扩展的恢复机制。同时感谢 SGLang、NIXL 和 Mooncake 团队对本次集成的评审与支持。