[AMD] Preserve the AITER expert mask across torch_memory_saver pause/resume - #34220
Merged
HaiShaw merged 1 commit intoAug 11, 2026
Merged
Conversation
JessicaJiang-123
requested review from
BBuf,
Edwardf0t1,
Fridge003,
HaiShaw,
Ying1123,
ch-wan,
ispobock and
merrymercy
as code owners
August 10, 2026 05:36
HaiShaw
reviewed
Aug 10, 2026
HaiShaw
left a comment
Collaborator
There was a problem hiding this comment.
@JessicaJiang-123 can you make sure it works on NV with DeepEP too?
Contributor
Author
Confirmed. Both inner dispatchers (deepep.py & moriep.py) initialise the attribute to # deepep.py:914-922
self.expert_mask_gpu = None
if _use_aiter and num_local_experts is not None:
expert_mask = torch.zeros(num_local_experts + 1, ...)
expert_mask[:-1] = 1
self.expert_mask_gpu = expert_mask# moriep.py:1074-1084 (ROCm)
self.expert_mask_gpu = None
if _use_aiter and num_experts is not None and num_local_experts is not None:
...
self.expert_mask_gpu = expert_maskOn CUDA the attribute value is |
HaiShaw
approved these changes
Aug 11, 2026
Collaborator
|
AITER gated. |
vstone-w
pushed a commit
to ClownBin/sglang
that referenced
this pull request
Aug 12, 2026
saturn-acc
pushed a commit
to saturn-acc/sglang
that referenced
this pull request
Aug 16, 2026
Atituiset
pushed a commit
to Atituiset/sglang
that referenced
this pull request
Sep 10, 2026
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.
Motivation
On ROCm with AITER,
MoriEPDispatcherandDeepEPDispatchercreate anexpert_mask_gpuat construction time to mark which experts are local to the current EP rank.The mask is allocated while the model is inside the memory-saver
WEIGHTSregion, so its GPU pages are managed bytorch_memory_saver. However, the dispatcher is not annn.Module, andexpert_mask_gpuis only a plain attribute, so it is not included inmodel.named_buffers().SGLang preserves init-time GPU state across
release_memory_occupation()/resume_memory_occupation()through_export_static_state()/_import_static_state(), which only operate on registered buffers. As a result, the expert mask is not restored after resume and becomes all zeros.AITER's
fused_moeuses this mask to filter local experts. An all-zero mask makes the rank appear to own no experts, so the expert GEMM output becomes zero and the model silently produces invalid outputs.On a failing Qwen3-30B-A3B-FP8 run with EP4:
The model weights themselves remain correct, so normal weight validation does not catch this corruption.
Modifications
Register the dispatcher's expert mask as a non-persistent buffer on
FusedMoE. This puts the tensor intonamed_buffers(), so the existing static-state save/restore mechanism preserves it across memory-saver pause/resume.persistent=Falsekeeps it out ofstate_dict()._import_static_state()restores buffers in place, so the dispatcher continues to reference the same tensor.Also add
expert_mask_gputo_NON_PERSISTENT_BUFFER_PATTERNSin the RL weight checker, since this rollout-only buffer has no training-side counterpart.This change only affects ROCm/AITER. The dispatcher only creates the expert mask when:
On CUDA/NVIDIA, or on ROCm without AITER,
expert_mask_gpuremainsNone, so no buffer is registered and no forward path changes.The fix covers the constructor-created masks in
MoriEPDispatcherandDeepEPDispatcher, which are the paths where the issue was reproduced.Accuracy Tests
Validated with colocated RL in Miles, using SGLang for rollout and Megatron for training on the same 4×MI355X GPUs.
Configuration:
--sglang-moe-a2a-backend mori--sglang-mem-fraction-static 0.7expert_masknonzeroraw_rewardlog_probsrollout_log_probstotal_lengthsBefore the fix, the rollout engine produces invalid generations and responses consistently hit the 8192-token limit. After the fix, the offload path matches the no-offload reference within normal run-to-run variation, and the Miles RL weight check passes.
Speed Tests and Profiling
N/A
Checklist
Review and Merge Process
/tag-and-rerun-ci,/tag-run-ci-label,/rerun-failed-ciCI States
Latest PR Test (Base): ❌ Run #31359156884
Latest PR Test (Extra): ❌ Run #31359156799