feat(peft): support multi-LoRA on grouped MoE expert linears - #5155
Conversation
Signed-off-by: Mathew Han <mathewjhan@gmail.com>
Signed-off-by: Mathew Han <mathewjhan@gmail.com>
Signed-off-by: Mathew Han <mathewjhan@gmail.com>
Signed-off-by: Mathew Han <mathewjhan@gmail.com>
Signed-off-by: Mathew Han <mathewjhan@gmail.com>
Signed-off-by: Mathew Han <mathewjhan@gmail.com>
Signed-off-by: Mathew Han <mathewjhan@gmail.com>
MultiLoRA previously skipped every MoE expert linear, so on an MoE model the
experts — most of the trainable capacity — silently received no adapter.
Add MultiLoRAGroupedExpertLinear for grouped expert linears
(mlp.experts.linear_fc{1,2} of a TEGroupedMLP). Each slot is a
GroupedExpertLinearAdapter, so the packed [num_local_experts, ...] weight layout
that peft_bridge's grouped-expert export and distributed checkpointing already
understand is reused unchanged. It subclasses MultiLoRALinear so isinstance-based
multi-LoRA discovery (slot lifecycle here, per-slot optimizers and adapter-state
zeroing downstream) picks expert layers up with no changes.
The hard part is that inside the experts the row order is the dispatcher's
expert-major permutation of tokens from every EP rank, so tokens_per_adapter no
longer segments it. install_moe_slot_routing registers a forward pre-hook on each
MoE layer's experts module — the only point with both the dispatcher's
permutation metadata and the final row order — which co-permutes an int32
slot-id vector through the same stages the dispatcher applied and stable-sorts by
(slot, local expert) so one grouped GEMM covers every pair. The companion
all-to-all carries one int32 per dispatched token.
Every slot's weights stay in the autograd graph (via the stacked weights, and an
explicit zero term on the empty-batch path) because Megatron's grad buffers
expect one grad hook per trainable parameter; a slot missing from the graph would
leave its bucket incomplete.
Unsupported configurations are rejected at layer construction, not in the hook:
a hook that raised on only some ranks would leave its peers waiting in the
companion all-to-all. Rejected: expert TP > 1, fp8/fp4 experts, permute fusion
(the fused permute records TE's row_id_map rather than a token gather index),
capacity padding, and non-alltoall dispatchers. Sequential (SequentialMLP)
expert linears are still skipped, with the warning rewritten to say so.
reset_adapter now forks the expert RNG tracker instead of the dense one: the
dense seed varies with the dense TP rank, and expert-data-parallel peers differ
in exactly that rank whenever tensor and expert tensor parallel sizes differ, so
replicas of a reused slot would diverge.
Signed-off-by: Ethan (Yusheng) Su <yushengsu.thu@gmail.com>
|
Hi @yushengsu-thu — this needs a rebase before it can be reviewed/merged. Why it conflicts: #4218 was squash-merged into Fix: drop the #4218 base and keep only your one new commit on top of current git fetch upstream main
git checkout yusheng/multilora-moe-experts
git reset --hard upstream/main
git cherry-pick 5fde419eae1cd7f67136f283ac6965dbdf6a69dc
git push --force-with-leaseI also confirmed on the rebased result that every symbol this PR imports still exists after main's peft refactor ( I would have pushed the rebase for you, but the fork is owned by the Note #5156 is stacked on this branch and will need rebasing after this one lands — see my comment there. |
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com> # Conflicts: # src/megatron/bridge/peft/multi_lora.py # src/megatron/bridge/peft/multi_lora_layers.py # tests/unit_tests/peft/test_multi_lora.py # tests/unit_tests/peft/test_multi_lora_layers.py
What does this PR do ?
Extends multi-LoRA (#4218) to grouped MoE expert linears, bringing the multi-adapter path to parity with single-adapter
LoRAfor grouped experts.Why
MultiLoRAskips every MoE expert linear, so on MoE models the experts — most of the trainable capacity — silently get no adapter.What
MultiLoRAGroupedExpertLinearwrapsmlp.experts.linear_fc{1,2}of aTEGroupedMLPwith one low-rank pair per (slot, local expert). Each slot is an existingGroupedExpertLinearAdapter, so the packed[num_local_experts, ...]export and checkpoint layout is reused unchanged; subclassingMultiLoRALinearkeepsisinstance-based multi-LoRA discovery working with no downstream changes.tokens_per_adapterno longer segments them.install_moe_slot_routingputs a forward pre-hook on each MoE layer'sexpertsmodule that co-permutes an int32 slot-id vector through the dispatcher's own stages (local permute, EP all-to-all, local-expert sort), then stable-sorts by (slot, expert) so one grouped GEMM covers every pair.Rejected configurations
Raised at layer construction, not in the hook (a hook raising on some ranks would strand peers in the companion all-to-all): expert TP > 1,
moe_permute_fusion(records TE'srow_id_map, not a token gather index), fp8/fp4 experts (input padding desyncs the row order), capacity padding, non-alltoall dispatchers.SequentialMLPexperts stay skipped with a clearer warning;normalize_moe_lora/share_expert_adapters/experts_shared_outer_lorasraiseNotImplementedError.Bug fix
reset_adapterforked the dense RNG tracker, whose seed varies with the dense TP rank — expert-DP peers differ in exactly that rank whenever TP != ETP, so replicas of a reused slot diverged. It now forks the expert tracker.Testing
On 8x H200 (radixark fork, same file contents as this PR):
test_multi_lora_moe.py17 passed; all multi-LoRA tests 70 passed. Real-model EP=2 integration (Qwen3-MoE-shaped, realMoEAlltoAllTokenDispatcher): all expert adapter params get grads, and routing tokens to different slots gives different losses. Export throughAutoBridge.export_adapter_weightsis byte-identical (names and shapes) to single-adapterLoRA.Changelog
MultiLoRAGroupedExpertLinearand MoE slot routing (install_moe_slot_routing) tomegatron.bridge.peft.multi_lora_layersMultiLoRAnow wraps grouped expert linears; sequential (SequentialMLP) experts are still skipped with a clearer warningMultiLoRAGroupedExpertLinear.reset_adapterforks the expert RNG tracker (EDP-consistent slot reuse)tests/unit_tests/peft/test_multi_lora_moe.py(CPU routing math + single-GPU integration)GitHub Actions CI
See the CI section in the Contributing doc. A Nvidia developer will need to approve and trigger the CI for external contributors.
Before your PR is "Ready for review"
Pre checks:
Additional Information