VeRL Backend Parallelism

导言

判断并行能力不能只搜索配置名。一个并行轴至少要经过 配置校验、process group/device mesh、模型计算、loss/backward 和目标训练流程,才能算后端支持。

截至本文固定的 verl commit,结论最明确的一项是:原生 FSDP2 支持 Ulysses Sequence Parallel(USP),但不支持 Expert Parallel(EP)和 Context Parallel(CP)。如果希望 FSDP2 同时使用 EP,应选 VeOmni;如果需要 TP、PP、EP、CP 的完整模型并行组合,应选 Megatron。

![verl 后端并行齿轮](https://pic.shaojiemike.top/shaojiemike/2026/07/fd863bf6732cd10c09030db833142e1d.png){ width=95% }
自绘认知示意图:并行策略不是一排通用开关,每个后端只有特定齿轮真正接入计算路径。

结论矩阵

本文使用四种状态:支持表示通信拓扑和模型计算都已接线;条件表示代码具备能力,但目标 OPD/recipe 组合没有现成端到端证据,或必须调整相邻配置;不支持表示配置缺失、group 未实现或 validator 主动拒绝;不适用表示并行轴不属于该执行阶段。

后端路径 TP PP EP USP CP 关键边界
vLLM rollout / teacher 支持 不支持 支持 不适用 条件 EP 必须满足 EP = TP × DP;CP 仅指 decode DCP
Megatron training 支持 支持 支持 不支持 支持 sequence_parallel 是 Megatron SP,不是 Ulysses
原生 FSDP2 training 不支持 不支持 不支持 支持 不支持 只有 FSDP/HSDP 与 Ulysses mesh
VeOmni training 不支持 不支持 支持 支持 不支持 verl 路径固定为 FSDP2,可组合 EP + USP
MindSpeed-MM DanceGRPO recipe 条件 不支持 不支持 不支持 条件 它不是 OPD 后端;Ulysses 通过 CP 算法实现

不要把三个 Ulysses 混在一起

原生 FSDP2 的 ulysses_sequence_parallel_size 是 verl USP;Megatron 的 sequence_parallel=True 是依附 TP 的 activation sharding;MindSpeed-MM 的 ulysses_cp_algo 则挂在 context_parallel_size 上。三者的配置轴和通信组都不同。

OPD 中的角色

examples/on_policy_distillation_trainer 同时包含 FSDP/FSDP2、Megatron 和 VeOmni 脚本,但 rollout 和 teacher inference 都走 vLLM。Qwen3.5 的 FSDP 脚本显式把 actor/ref 设为 fsdp2,rollout 设置 TP,teacher 同时设置 TP 与 EP。[^opd-fsdp]

这意味着一次 OPD 任务至少有两套并行拓扑:

  1. 推理拓扑:vLLM 为 rollout 或 teacher 执行 TP、DP、EP,以及可选的 decode DCP。
  2. 训练拓扑:actor/ref 由 FSDP2、Megatron 或 VeOmni 之一执行自己的并行策略。

不能因为 teacher 用了 vLLM EP,就推断 actor 的 FSDP2 也有 EP。

原生 FSDP2

USP 是真实计算路径

FSDPEngineConfig 在 FSDP 专属字段之外只暴露 ulysses_sequence_parallel_size,策略允许 fsdpfsdp2;它没有 TP、PP、EP、CP 字段。[^engine-config]

FSDP engine 初始化时会建立两套 mesh:一套是 FSDP/HSDP mesh,另一套在 ulysses_sequence_parallel_size > 1 时建立 [dp, sp] mesh,并取得 SP group。随后模型 patch 收到 ulysses_sp_size,forward/backward 又用该 SP size 分配数据和归一化 token。[^fsdp-engine]

这不是“预留配置”。现有示例直接组合:

1
2
actor_rollout_ref.actor.strategy=fsdp2
actor_rollout_ref.actor.fsdp_config.ulysses_sequence_parallel_size=${sp_size}

同一个脚本也为 ref 使用 FSDP2 + Ulysses。[^fsdp2-usp-example]

EP 与 CP 都不存在

原生 FSDP2 的 get_model_parallel_group()get_context_parallel_group() 直接抛出 NotImplementedError。它没有 expert mesh,也没有把 expert 层按 rank 分割并执行 all-to-all 的路径。[^fsdp-groups]

因此应严格区分:

  • MoE 模型可在 FSDP2 下训练:模型包含 router 和 experts。
  • FSDP2 支持 EP:不同 rank 只持有或执行部分 experts,并通过 EP group 交换 token。

前者不推出后者。原生 verl FSDP2 当前属于前者,不是 EP 实现。CP 同理:没有 CP 配置、group 和 attention 计算路径,不能把 USP 改名为 CP。

Megatron

Megatron 的配置和初始化都完整覆盖 TP、PP、EP、expert TP 与 CP。engine 将这些 size 直接传给 initialize_model_parallel()。[^megatron-engine]

OPD 示例公开暴露 actor TP 与 PP,并走 Megatron distillation 路径。[^opd-megatron] TP 场景还需要处理 vocab-parallel logits:teacher 的 global top-k token id 要映射到本 rank 的局部词表后再归约。当前 distillation loss 已经实现该逻辑。[^megatron-distill]

对证据强度仍需留一层边界:

  • TP、PP:有 OPD 脚本和专门链路证据。
  • EP、CP:Megatron engine 和 OPD forward/loss 代码已经接线,但本文检查的标准 OPD 示例没有直接打开这两个轴,建议先做小规模精度与通信 smoke test。
  • USP:不支持。Megatron sequence_parallel 在 TP=1 时会被关闭,它不是 Ulysses all-to-all SP。[^engine-config]

VeOmni

verl 的 VeOmni engine 明确只运行 FSDP2,并把 expert_parallel_sizeulysses_parallel_size 一起交给 VeOmni parallel state。[^veomni-engine] 通用 Qwen3-VL MoE 示例也同时配置了 EP 和 USP,说明二者可以组合。[^veomni-example]

VeOmni OPD 脚本已经存在,但默认没有把 EP/USP 调大。对 OPD 而言,可以得出“后端能力已接线”,仍不能把它写成“所有 EP + USP distillation 组合已端到端验证”。

TP、PP、CP 当前则明确不支持:VeOmni 自身虽然定义了这些字段,但 validator 要求三者必须为 1。[^veomni-validator]

vLLM 推理

verl 的 vLLM adapter 会传入 tensor_parallel_size,并在 EP 大于 1 时设置 enable_expert_parallel。rollout 配置还要求 expert_parallel_size == tensor_parallel_size × data_parallel_size。[^rollout-config][^vllm-adapter]

需要注意两个集成边界:

  • PP:即使独立 vLLM 有 pipeline parallel 能力,verl rollout config 对 vLLM 的 pipeline_model_parallel_size > 1 主动抛出 NotImplementedError,所以本矩阵必须记为不支持。[^rollout-config]
  • CPengine_kwargs.vllm.decode_context_parallel_size 可以透传,且 verl 会为 DCP 调整 CUDA Graph 模式。它是复用 TP 通信域的 decode context parallelism,不是训练 CP。[^vllm-adapter][^vllm-dcp]

USP 是训练侧的 token/attention 切分语义,不应用到这里的 serving engine。

MindSpeed-MM recipe

verl-recipe/dance_grpo/dance_grpo_mindspeed_mm 不是 on_policy_distillation_trainer 的第四种 actor 后端。它要求 verl v0.7.0,面向 Wan2.2 扩散模型的 DanceGRPO,使用 MindSpeed-MM、Torch FSDP2 与直接 PPO update。[^mindspeed-recipe]

它的参数生成脚本暴露 TP、PP、CP,并选择 --context-parallel-algo ulysses_cp_algo;但 shipped 配置将 TP、PP、CP 都设为 1,并启用 Torch FSDP2 与 torch_dcp checkpoint。[^mindspeed-args]

逐层检查后,结论是:

  • TP:条件支持。MindSpeed-MM 的 Wan 模型有 TP 计算路径,FSDP2 validator 只给兼容性 warning;但该 recipe 使用的 torch_dcp 会校验 TP=1。要启用 TP,至少要先更换并验证 checkpoint 路径。[^mindspeed-checkpoint]
  • PP:不支持。MindSpeed-MM 明确拒绝 FSDP2 + PP;recipe 的 actor update 也是直接 forward、loss.backward(),没有 pipeline schedule。[^mindspeed-validator][^mindspeed-worker]
  • EP:不支持。MindSpeed-MM 明确拒绝 FSDP2 + EP;当前 Wan2.2 5B recipe 也不是 MoE expert 分片场景。[^mindspeed-validator]
  • USP:不作为独立轴支持。recipe 中的 Verl Ulysses manager 只设置 SP group/数据重排,actor 字段已标记 deprecated;在本文检查的 recipe 中,未发现 MindSpeed 模型计算接到 Verl Ulysses patch 的代码证据。[^mindspeed-usp-manager]
  • CP:条件支持。Wan DiT 会按 context_parallel_size 进入 Ulysses、Megatron 或 hybrid CP attention;recipe 选择的是 ulysses_cp_algo。这应计入 CP,而不是再重复记成 USP。[^mindspeed-wan]

另有一个 MindSpeed 后端

当前 verl 主仓还有继承 Megatron 配置的 MindSpeed-LLM engine,它与这里的 verl-recipe MindSpeed-MM DanceGRPO 不是同一条路径。前者可沿用 Megatron 的 TP/PP/EP/CP 语义;本文矩阵中的 MindSpeed-MM 行只描述后者。

选型建议

  1. Dense OPD,模型能被 FSDP2 放下:优先原生 FSDP2;长序列需要切分时使用 USP。
  2. MoE OPD,需要 expert sharding:选择 VeOmni 的 FSDP2 + EP + USP,或 Megatron EP;不要在原生 FSDP2 上寻找不存在的 EP 开关。
  3. 需要 TP/PP/EP/CP 组合:选择 Megatron,并针对具体 OPD 组合补精度与通信验证。
  4. teacher/rollout inference:vLLM 可使用 TP 与受约束的 EP;长 decode 可评估 DCP,但不要把它当作训练 CP。
  5. Ascend 扩散模型 DanceGRPO:MindSpeed-MM recipe 可评估 CP/Ulysses-CP;它不能直接证明 LLM OPD 的后端支持。

验证清单

对尚未由标准脚本覆盖的组合,至少验证:

  • world size 是否能被所有并行轴正确分解;
  • forward、loss normalization 和 backward 是否使用同一组切分语义;
  • teacher top-k、TP-local vocab、MoE router 与 EP token exchange 是否对齐;
  • checkpoint 保存/恢复是否覆盖新增 mesh;
  • rollout logprob、teacher logit、actor new logprob 的数值误差是否在可接受范围;
  • 1、2、4 个并行 rank 下的 loss 与单卡 reference 是否一致。

本文只把固定 commit 的代码事实写成“支持”。没有标准 OPD E2E 的组合仍保留为“条件”,直到测试补齐。

[^opd-fsdp]: Qwen3.5 FSDP2 OPD script
[^engine-config]: verl training engine configs
[^fsdp-engine]: verl FSDP/FSDP2 mesh and group methods
[^fsdp-groups]: verl FSDP model/context group methods
[^fsdp2-usp-example]: FSDP2 + Ulysses example
[^megatron-engine]: Megatron model-parallel initialization
[^opd-megatron]: Megatron OPD script
[^megatron-distill]: Megatron top-k distillation loss
[^veomni-engine]: VeOmni FSDP2, EP and Ulysses initialization
[^veomni-example]: VeOmni EP + USP example
[^veomni-validator]: VeOmni accelerator validator
[^rollout-config]: verl rollout parallel validation
[^vllm-adapter]: verl vLLM server arguments
[^vllm-dcp]: vLLM-Ascend context-parallel design
[^mindspeed-recipe]: MindSpeed-MM DanceGRPO recipe and version requirements
[^mindspeed-args]: MindSpeed-MM recipe training arguments
[^mindspeed-validator]: MindSpeed-MM FSDP2 and checkpoint validation
[^mindspeed-checkpoint]: MindSpeed-MM Torch DCP validation
[^mindspeed-worker]: MindSpeed-MM recipe direct actor update
[^mindspeed-usp-manager]: Verl v0.7.0 FSDP Ulysses sharding manager
[^mindspeed-wan]: Wan DiT context-parallel attention

Author

Shaojie Tan

Posted on

2026-07-20

Updated on

2026-07-20

Licensed under