Repository navigation
Conversation
DeepGemmMegaMoEExperts writes every checkpoint shard straight into its kernel layout and has no post-load processing, yet layerwise reload put its parameters on meta, buffered every loaded expert tensor, dry-ran each loader under a dispatch-mode copy counter, materialized a fresh layer and copied it back. For RL weight sync of a 384-expert model that per-tensor overhead dominates the receiver. Add a `reload_in_place` layer opt-in: initialize_layerwise_reload leaves such layers live, so their loaders write the live (CUDA-graph-captured) storage directly. Bytes are unchanged: the same loaders write the same destinations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: aoshen02 <aoshen@inferact.ai>
load_weights scanned every (expert, shard) mapping entry with a substring test for each expert tensor: 1152 entries at 384 experts, ~40 us per tensor, ~1 s per RL weight sync per rank. Look up only the entries keyed by the `experts.<id>.w<k>.` occurrences in the name; fall back to the full scan when the mapping has other weight-name forms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: aoshen02 <aoshen@inferact.ai>
aoshen02
requested review from
AndreasKaratzas,
DarkLight1337,
Harry-Chen,
bnellnm,
khluu,
mgoin,
pavanimajety,
wzhao18,
ywang96 and
zyongye
as code owners
October 23, 2026 23:26
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.
Purpose
Speed up the receiver side of RL weight sync for DeepSeek-V4.1 (MegaMoE, 384 routed experts):
[Model Loader]Reload MegaMoE experts in place during layerwise reload.DeepGemmMegaMoEExpertsloaders already write the final kernel layout and the layer has no post-load processing, but layerwise reload still put its params on meta, buffered every expert tensor, dry-ran each loader under a copy counter, materialized a new layer and copied it back. Areload_in_placelayer opt-in leaves such layers live, so loaders write the live (CUDA-graph-captured) storage directly. Same loaders, same destinations, same bytes.[DSV41]Index the routed-expert mapping inload_weights. Each expert tensor scanned all 1152(expert, shard)mapping entries with a substring test (~40 µs/tensor, ~1 s per sync per rank at 384 experts). Look up only the entries keyed by theexperts.<id>.w<k>.occurrences in the name; fall back to the full scan for other name forms.[DSV41]Load runs of consecutive routed experts with one batched copy. Each routed-expert shard went through its own loader call (name mapping, ownership scan, scale packing, layout views, copy), ~0.2 ms per tensor, ~5 s of every sync per rank at full scale (96 local experts × 40 layers × 6 shards).load_weightsnow groups consecutive experts of one MegaMoE parameter and hands each run toDeepGemmMegaMoEExperts.load_routed_experts, which stacks the local ones and writes them with one batched copy using the same layout transforms. Bytes are unchanged; NVFP4 global scales and EPLB replica layouts keep the per-expert loader.[DSV41]Collapse Engram huge pages only after loading the Engram tables.load_weightsdropped the checkpoint page cache andMADV_COLLAPSEd every Engram table on every call. RL weight sync calls it once per IPC bucket and never sends the frozen tables, so each call paid ~5 ms for nothing. Do both only when the call loaded an Engram table: ~0.9 s per sync on a 1-node proxy.[DSV41]Keep one expert run open per parameter shard. The weight-sync sender emits w1, w2, w3 of one expert before the next, so a single open run was closed by every tensor and (3) never batched (480 calls of 1 expert on the proxy). Keep one run per (parameter, shard) and flush them at the end of the call. This is what makes (3) actually batch.With (1)–(2) the per-expert-tensor receive cost drops from ~0.6 ms to ~0.115 ms; (3)–(5) remove most of the remaining per-tensor overhead. Together with trainer-side changes (separate repo) a full DeepSeek-V4.1 weight update in colocated verl RL went from ~106 s to ~9 s.
Not a duplicate
Searched open PRs for
reload_in_place, "layerwise reload MegaMoE", "deepseek_v41 load_weights expert mapping". Related but different: #57678 / #57733 (model-level post-load finalization on reload), #63119 / #60895 (MegaMoE for other models). None skip the layerwise reload buffering for layers without post-load processing or index the DSV41 expert mapping.Test Plan
tests/model_executor/model_loader/test_reload.py::test_reload_in_place_layer_writes_live_storage,tests/models/test_deepseek_v41_expert_mapping.py::test_expert_mapping_index_matches_linear_scanand::test_routed_expert_shards_load_as_one_run_per_parameter_shard(wired into Basic Models (Other)),tests/kernels/moe/test_deep_gemm_mega_moe.py::test_deep_gemm_mega_moe_batched_load_matches_per_expert_loads(batched run writes the same bytes as per-expert loads, MXFP4 and NVFP4; already in the MegaMoE kernel step).pre-commit runon the changed files: passed.Test Result
On the original base (vLLM nightly image + these files as an overlay, GB200): both new tests pass;
test_reload.py89 passed, 2 failed (Qwen3-0.6B engine start, Llama FP8-KV reload perplexity) — neither uses MegaMoE orreload_in_place, so the new code is a no-op there; treated as image-environment failures, not re-run on a clean baseline. The commits were then cherry-picked onto currentmainwithout conflicts in the source files; the unit tests have not been re-run on this exact rebase yet (CI will). Commits (3)–(5) were developed on a downstream DSV41 branch; cherry-picking them here only conflicted in tests (the batched-load test was taken without the unrelated tests next to it, and the run-grouping test moved intotest_deepseek_v41_expert_mapping.py). Their two new tests have not been run on this rebase (CI will).pre-commit runon the changed files passed.End-to-end (DeepSeek-V4.1, colocated verl + Megatron, sleep level 2, 16×GB200):
rollout_probs_diff_max= 0 with batch invariance across steps; AIME eval unchanged.update_weightsper step: ~106 s → 8.8–9.5 s (with the trainer-side changes). All five commits were in the overlay used for those 16-node runs; full-scaleupdate_weightsstays ~9 s total with all of them.AI assistance
This PR was prepared with AI assistance (Claude Code). The human submitter is reviewing every changed line.
🤖 Generated with Claude Code