Release HybridEP dispatcher state after combine - #975
Merged
Merged
Conversation
MCore's HybridEP manager keeps routing_map, token_probs and dispatched_probs after combine. The dispatched probabilities keep each MoE layer's checkpoint graph, its recomputed input and that input's gradient alive until the layer's next dispatch. Clear them after combine_postprocess for exact flex dispatchers with a HybridEP manager, as #858 and #861 do for the EP1 all-to-all. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
bradhilton
deployed
to
trainer-rank-gpu-validation
September 25, 2026 16:04 — with
GitHub Actions
Active
…P cases Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
bradhilton
had a problem deploying
to
trainer-rank-gpu-validation
September 25, 2026 16:24 — with
GitHub Actions
Error
…h layer Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
bradhilton
deployed
to
trainer-rank-gpu-validation
September 25, 2026 16:37 — with
GitHub Actions
Active
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #949. #858 and #861 stopped MCore's EP1 all-to-all dispatcher from keeping each MoE layer's checkpoint graph alive after backward. The flex dispatcher that ART uses at EP>1 with HybridEP has the same retention and was left out.
MCore's
_HybridEPManagerkeepsrouting_map,token_probsanddispatched_probsaftercombine, until that layer's nextsetup_metadataanddispatch. The dispatched probabilities are a differentiable output of the dispatch, so their graph keeps the following alive:.grad;TrainerRanknow adapts exactMoEFlexTokenDispatcherinstances whose manager is exactly_HybridEPManager, in the model it is given, the same way #861 adaptscombine_postprocess. After the upstreamcombine_postprocessreturns, it clears those three manager fields. Installation also clears any state already held. Backward keeps what it needs through its own graph, and the next setup and dispatch recreate these fields. Not adapted:combine_postprocess;Evidence
Qwen3.6-35B-A3B with random weights, 8 layers, CP2/EP2, 194,753 tokens, on two local H200s with #955. The allocator traces are the ones from #963's requalification:
random.py:630, autograd input-buffer accumulation).dispatchreplacesdispatched_probsandhandle, and 1.03 GB of router state insetup_metadata. That is about 1 GB per MoE layer at this size, scaling with layers and tokens. Admission counts it as used memory.Validation on two H200s
Three EP2/CP2 runs of 3 calls each, with random seeded weights. The weight and input fingerprints are identical across runs. Two base runs used #963's head
4b3d1e059; the third added this change. All figures are for rank 1 (105,153 tokens), except the rank-0 bullet.The second base run's warm call also took 5.1 s. That is ordinary variance: collection time alone varies by 0.6 s between the two base runs.
Schulman's independent audit of a full-depth (40 MoE layer) diagnostic run found the same retention: after a final GC, 40 managers still held these three fields, 9.64–10.23 GB of CUDA tensors directly, all with
HybridEPDispatchBackward.Full-depth run (Schulman, independently audited). This change alone was added to a frozen ART tree, and a synthetic 19-history step was run: 1,073,093 tokens in groups of 10 and 9, on two H200s. Everything else in that setup stayed as it was: the original callback, probe, lane and compiler-GC settings, and the selective FC1 offload.
The before and after runs used different physical GPU pairs and fresh allocator and compiler state. So these are a historical comparison, not an exclusive attribution. The audit makes no claim about numerical parity, one-GPU fit or production throughput. The remaining first-group estimator miss it reports belongs to that frozen tree's planner, not to current
mainor #963.Tests
tests/integration/megatron/model_support/test_dispatcher_graph_retention.pyis in the Megatron lightweight CI lane. It drives the pinned MCore flex dispatcher and_HybridEPManagermethods (dispatch_preprocess,setup_metadata,dispatch,combine, the post-processing steps) throughCheckpointFunction. Only HybridEP's fused dispatch and combine kernels are replaced, by CPU equivalents. The tests cover:aot_eager: the compiled case installs into an already warmed model without a compiler reset, and the adaptation is also installed with the checkpoint backward still pending;retain_graphbackward, eager and compiled, with and without checkpointing, matching the unadapted model bitwise;combine_postprocessoverrides, or dispatcher and manager subclasses;The whole file passes locally (38 tests, run with GPUs hidden). Deleting either release makes its tests fail: without the release after combine, 11 fail; without the release at installation, the installation test fails. ruff and ty are clean on the changed files.
🤖 Generated with Claude Code