Skip to content

perf: use HybridEP in AutoModel MoE recipes - #4037

Open
seonjinn wants to merge 11 commits into
NVIDIA-NeMo:mainfrom
seonjinn:sna/hybridep-automodel-recipes-20260906
Open

seonjinn wants to merge 11 commits into
NVIDIA-NeMo:mainfrom
seonjinn:sna/hybridep-automodel-recipes-20260906

Conversation

@seonjinn

@seonjinn seonjinn commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Use dispatcher: hybridep in AutoModel MoE recipes that previously selected DeepEP.
  • Replace the removed enable_deepep option with the explicit dispatcher setting.
  • Preserve existing expert backends and recipes that explicitly require the Torch dispatcher.

This is separate from #3438, which covers Megatron performance recipes.

Container requirement

Multi-node recipes require DeepEP to be built with HYBRID_EP_MULTINODE=1. The corresponding container build change is tracked separately.

Testing

  • 18/18 resolved AutoModel recipe cases passed.
  • Verified inherited recipes preserve explicit dispatcher: torch overrides.
  • ruff check
  • ruff format --check
  • git diff --check

Runtime H100 validation will be added separately.

Signed-off-by: seonjinn <sna@nvidia.com>
@seonjinn
seonjinn requested review from a team as code owners September 7, 2026 04:31
@copy-pr-bot

copy-pr-bot Bot commented Sep 7, 2026

Copy link
Copy Markdown

Auto-sync is disabled for ready for review pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@seonjinn seonjinn added the CI:L1 Run doctests, unit tests, and functional tests label Sep 7, 2026
@seonjinn

seonjinn commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test abfcffd

@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test 3051348

@seonjinn seonjinn added CI:Lfast Runs a fast test suite and re-use nightly `main` container (but sync dependencies to PRs version) and removed CI:L1 Run doctests, unit tests, and functional tests labels Sep 17, 2026
yuekaizhang added a commit to yuekaizhang/RL that referenced this pull request Sep 18, 2026
Plain "deepep" hangs with "DeepEP error: timeout (dispatch CPU)" on this
EP=32, 4-node/32-rank layout under the deep_ep pin bumped by
NVIDIA-NeMo#3436 (deep_ep 29d31c0 -> 17cfb81, "enable HybridEP on
H100/B200"). The container's deep_ep is already built with
HYBRID_EP_MULTINODE=1 (NVIDIA-NeMo#4038, merged), and "hybridep" is
already a supported nemo_automodel BackendConfig.dispatcher value -- just
not yet the repo-wide default for AutoModel MoE recipes (that's
NVIDIA-NeMo#4037, still open). Switching these two recipes now rather
than waiting on NVIDIA-NeMo#4037: verified with a live 4n8g eagle3 run past the exact
point (policy.get_logprobs()'s first post-refit call) that failed twice
under plain deepep.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Yuekai Zhang <zhangyuekai@foxmail.com>
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test 27ac693

@seonjinn
seonjinn requested a review from terrykong September 18, 2026 06:59
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test 8cd048d

@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test 2eb68fa

Comment thread examples/configs/recipes/llm/grpo-glm47-flash-4n8g-automodel.yaml
Comment thread tests/unit/tools/test_hybridep_automodel_recipes.py Outdated
Comment thread tests/unit/tools/test_hybridep_automodel_recipes.py

@sharonyu-115 sharonyu-115 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the AutoModel enable_deepep -> dispatcher: hybridep migration. The dispatcher swap itself checks out (cross-referenced against Automodel's own upstream reference configs, e.g. DeepSeek V4 Flash matches exactly), and the new regression test is a good addition.

Left inline notes (on the earlier review) on: 3 recipes left experts: unset rather than pinning it explicitly (unlike 9 of the other 11 recipes in this PR) -- not claiming a specific value is wrong, since Automodel's own examples use both gmm and torch_mm for these same model families, just flagging the inconsistency; 2 more AutoModel MoE recipes that still use the removed enable_deepep flag and appear to need the same migration; and a couple of test-coverage gaps tied to both.

[E2E-VALIDATION-EVIDENCE] This PR swaps the MoE token dispatcher (deepep -> hybridep, or removes enable_deepep) across all 11 changed recipes. 10 of them are gated by automated convergence checks, not just launch-smoke tests:

  • tests/test_suites/nightly.txt: dapo-nanov3.5-30BA3B-4n8g-automodel, dpo-nanov3-30B3AB-1n8g-fsdp8ep8-automodel.v2, grpo-deepseek-v4-flash-0731-16n8g-automodel-cp8ep128, grpo-moonlight-16b-automodel-1n8g-ep8, grpo-nemotron3-super-120BA12B-16n8g-automodel-ep8.v2, grpo-qwen3.5-35ba3b-2n8g-automodel-ep16, sft-gpt-oss-20b-1n8g-fsdp8ep8-automodel
  • tests/test_suites/release.txt: grpo-glm47-flash-4n8g-automodel, grpo-minimax-m27-dapo-8n8g-automodel, grpo-qwen3.5-35ba3b-dapo-4n8g-automodel

For example, grpo-moonlight-16b-automodel-1n8g-ep8.sh asserts concrete thresholds via check_metrics.py (gen_kl_error < 0.001, reward["30"] > 0.4, grad_norm["30"] < 0.2) -- a real convergence gate, not a smoke test. The PR description's Testing section only covers config-resolution-level checks (the new unit test + ruff/format) and explicitly notes "Runtime H100 validation will be added separately." Since a dispatcher swap changes the communication/kernel path for these recipes, could you link the nightly/release run(s) against this commit (or a manual wandb comparison) once available, to confirm no regression on these metrics before merge?

Generated by Claude Code

Comment thread examples/configs/recipes/llm/grpo-glm47-flash-4n8g-automodel.yaml
Make expert backends explicit, migrate the remaining Nano recipes, and preserve HybridEP alignment through dynamic batching and Gemma CP2. Cover resolved recipe inheritance and intentional backend choices.

Signed-off-by: seonjinn <sna@nvidia.com>
@seonjinn

Copy link
Copy Markdown
Contributor Author

Review follow-up at 5cb48a7 (merged main fd7112c374af23b3bcc392637fb737495f8a3f31):

  • Addressed all six inline configuration/test requests; replies above describe each fix.
  • Preserved expert kernel choices and explicit Torch overrides; migrated the two missing Nano recipes.
  • Fixed input alignment, including both padding and dynamic-batch rounding for Gemma CP2.
  • Local checks: 131 passed, 242 skipped (28 PR recipe checks plus 103 related checks). Skips are unrelated recipes outside enabled AutoModel EP scope. Ruff lint/format and git diff --check passed.

These were CPU configuration checks on macOS, not GPU execution or convergence tests. The requested new-head nightly/release convergence evidence remains pending, and Lfast does not satisfy that requirement by itself. No convergence thresholds were changed.

Container clarification: the merged main Dockerfiles already build DeepEP with HYBRID_EP_MULTINODE=1; older images may still lack that option. This supersedes the PR body's older statement that the container change is separately pending.

Requesting CI:Lfast for this exact head next.

@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test 5cb48a7

Signed-off-by: seonjinn <sna@nvidia.com>
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test d72a905

…60921

Signed-off-by: Seonjin Na <sna@nvidia.com>
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test ffc8e30

@yuki-97 yuki-97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scope: the 14 recipe changes and the new test_hybridep_automodel_recipes.py.

Checked:

  • Pinning experts: torch_mm on GLM / MiniMax / Moonlight / Super keeps the backend those recipes already ran with: the pinned Automodel ignores enable_deepep (utils.py:303-314) and defaults experts to torch_mm (utils.py:243-245).
  • The 64-token alignment holds on every HybridEP recipe under dynamic batching: input padding and sequence_length_round are both multiples of 64, Gemma CP2 pads to 128, and DeepSeek-V4 CP8 is covered by the model's own per-rank padding to 128 (deepseek_v4/model.py:895).
  • The guard test finds EP recipes from the resolved config rather than the filename, so inherited variants like the DPO 1n4g torch override are covered.
  • Multi-node HybridEP in the container (HYBRID_EP_MULTINODE=1) already landed in #4038, and this branch includes it.

Remaining comments are on leftover DeepEP usages (three VLM expert-parallel recipes, the enable_deepep schema key, the DeepSeek-V4 guide and nightly labels) and on where the new recipe tests should live.

Comment on lines +22 to +28
RECIPE_DIR = Path(__file__).parents[3] / "examples/configs/recipes/llm"
RECIPES = tuple(sorted(RECIPE_DIR.rglob("*.yaml")))


@pytest.mark.parametrize(
"recipe_path", RECIPES, ids=lambda path: str(path.relative_to(RECIPE_DIR))
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three AutoModel expert-parallel VLM recipes still use dispatcher: deepep, and this test can't catch them because it only globs recipes/llm:

vlm_grpo-gemma4-e4b-geo3k-1n8g-automodel.yaml:36 also says deepep; the model is dense so it is a no-op there, but worth flipping too so no AutoModel recipe is left on DeepEP.

Suggest fix:

  1. Switch those recipes to dispatcher: hybridep and add make_sequence_length_divisible_by: 64 under policy: (they inherit 1 from grpo_math_1B.yaml today).
  2. Move test_automodel_moe_recipes_use_hybridep_or_explicit_torch into test_config_validation.py:103 and parametrize it over the existing config_files with load_config_with_inheritance, as test_all_config_no_tp_size_accuracy_issues does; config_files already includes recipes/vlm/.
  3. After switching them, rerun those recipes' nightly scripts under tests/test_suites/vlm/ to confirm they still pass with HybridEP.

pytest.skip("Not an AutoModel expert-parallel recipe")

backend = dtensor_cfg.automodel_kwargs.backend
assert "enable_deepep" not in backend

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enable_deepep is still declared in the schema even though this test now forbids it in every recipe:

Nothing in nemo_rl reads it, and the pinned Automodel ignores it with a warning (utils.py:303-314).

Suggest fix:

  1. Delete init.py:137-139 and add "hybridep" to the dispatcher comment on init.py:135.
  2. Drop "enable_deepep": True from test_automodel_types.py:56 (optionally replace it with "dispatcher": "hybridep").

rms_norm: torch_fp32
experts: torch_mm
dispatcher: deepep
dispatcher: hybridep

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DeepSeek-V4 guide still says this recipe uses DeepEP: deepseek-v4-flash.md:26-27 lists "the DeepEP expert dispatcher" under Validated Scope. The two gpt-oss nightly entries are also still labelled # gpt-oss 20b DeepEP test (nightly.txt:255, nightly_gb200.txt:74), though their recipe moves to HybridEP in this PR.

Suggest fix:

  1. Change the guide line to "the HybridEP expert dispatcher" once the DSV4 HybridEP run is in.
  2. Rename both nightly comments to # gpt-oss 20b HybridEP test.

)


def test_gemma4_cp_keeps_local_hybridep_inputs_aligned() -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_gemma4_cp_keeps_local_hybridep_inputs_aligned (line 55) and test_automodel_recipes_preserve_backend_choices pin the settings of specific recipes, and tests of this kind are already spread across tests/unit/tools/ and tests/unit/models/generation/.

Suggest fix:

  1. Move these two tests into a new tests/unit/test_recipe_settings.py.
  2. Optional for this PR, since they predate it: move the existing recipe-setting tests there too.

#3724, #3733 and #4077 add similar tests as well.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI:Lfast Runs a fast test suite and re-use nightly `main` container (but sync dependencies to PRs version)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants