[Dev] fix(moe): align MoE router loss scale semantics - #3768
Conversation
1ceb193 to
90fcb53
Compare
|
/ok to test 90fcb53 |
|
/claude review |
|
why use |
It's to keep consistent with the standard aux loss, otherwise the effective scale of global aux loss will be increased. |
I think all aux loss should align with |
@zyeric Thanks for your comments. For the Marked this PR as draft until resolving all aux-loss related issues. |
90fcb53 to
7810a78
Compare
|
/ok to test 7810a78 |
7810a78 to
25642dd
Compare
|
/ok to test 25642dd |
|
🔄 Merge queue validation started! You can track the progress here: https://github.com/NVIDIA/Megatron-LM/actions/runs/26496906565 |
…hment Expand the comments around the dp_size and tp_cp_group.size() corrections in TopKRouter so future readers can recover why each factor is required. - `_apply_global_aux_loss`: spell out that `probs` stays local in `switch_load_balancing_loss_func` while `total_num_tokens` reduces over `tp_dp_cp_group`, which is the source of the dp_size dilution that the external multiplier cancels. Note that the same factor is propagated to `normalize_scale` so logged values remain comparable. - `attach_and_log_load_balancing_loss` docstring: clarify the caller contract for `normalize_scale` (must absorb any external scaling already applied to `aux_loss`). - Per-token branch and `apply_z_loss`: explain how `MoEAuxLossAutoScaler` is seeded with `loss_scale` only and `finalize_model_grads` divides by a `dp_cp_group`-reduced global token count, which is why the attach point has to compensate by `tp_cp_group.size()` for both aux loss and z_loss. No functional change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Closed this in favor of #5047 |
Summary
This PR aligns the effective scale of MoE router auxiliary losses across aux-loss variants,
--calculate-per-token-loss, and TP/CP/DP parallel strategies.The conservative semantic baseline is kept unchanged:
load_balancing_type=aux_losswith--calculate-per-token-loss=false. Other paths are aligned to that baseline.Fixes #3672.
Problem Manifestation
Before this fix, equivalent MoE training configurations could apply different effective router regularization strengths even when using the same
moe_aux_loss_coeff.The most visible symptoms were:
global_aux_lossdid not have the same effective scale as the standardaux_loss. In practice, the active load-balancing loss and router gradient strength could drift when switching only the aux-loss type fromaux_losstoglobal_aux_loss.aux_lossand--calculate-per-token-lossenabled, changing TP/CP sizes changed the effective aux-loss scale. The same model and data could therefore show different router-loss/router-gradient behavior under different TP/CP parallel strategies.seq_aux_loss/z_lossstyle router-loss attachment paths, so aux type, per-token mode, and TP/CP/DP strategy were not cleanly comparable.The expected behavior is that these configurations should preserve the same coefficient semantics: changing aux-loss type or parallel decomposition should not systematically rescale router gradients, except where the loss definition itself intentionally differs.
Root Cause
There were two scale mismatches in the router-loss attachment path:
global_aux_lossbuildstokens_per_expertfrom a DP-aggregatedtp_dp_cp_group, while router probabilities remain local. Since the final gradient is averaged across DP ranks, the attached gradient was diluted bydp_size.finalize_model_gradsnormalizes by the global token count. With TP/CP enabled, this missed thetp_cp_group.size()factor.As a result, otherwise equivalent configurations could show systematic router-loss and router-gradient scale drift when switching aux-loss type, per-token-loss mode, or TP/CP/DP strategy.
Fix
global_aux_lossbydp_size = tp_dp_cp_group.size() // tp_cp_group.size()so its backward strength matchesaux_loss.local_valid_tokens * tp_cp_group.size()to match global-token-count gradient normalization.aux_lossbaseline behavior.Validation
Public W&B report: https://api.wandb.ai/links/megatron-core-moe-dev/xafmkree
Original W&B report: https://wandb.ai/megatron-core-moe-dev/moe-aux-loss-scale-alignment/reports/MoE-Aux-Loss-Scale-Alignment-E2E-Ablation---2026-05-25--VmlldzoxNzAwODkxMw==
E2E validation uses the same model/config family and compares loss ratios against the baseline instead of forcing load balancing. Horizontal aux-type comparisons use a deterministic
mock_repeatdataset so each global batch is identical across aux types. Vertical parallel-strategy comparisons use the real SlimPajama data path and load all compared TP/CP/DP jobs from the same one-iteration checkpoint.Key validation results:
aux_lossverticalseq_aux_lossverticalglobal_aux_lossverticalz_lossverticalAdditional checks:
aux_loss + --calculate-per-token-loss=falseis bitwise identical before/after fix, confirming the baseline is unchanged.aux_lossandseq_aux_lossfixed TP1/CP1 horizontal runs are bitwise identical before/after fix where the scale correction should be neutral.global_aux_losschanges after the first step as expected because the fix intentionally changes its backward scale.global_aux_lossgradient scaling.Local sanity checks: