Repository navigation
Conversation
MiniMax-M2/M3, Step-3.7 and LongCat-Flash store e_score_correction_bias in float32 with large values that differ little between experts; bfloat16 collapses them to a few values and changes the selected experts for almost every token. MiniMax also stores the router weight in float32; keep it in float32 on load and under autocast.
Contributor
|
Thank you for your contribution 🤗! CI Security Gate — waiting for maintainer approvalCI is approved automatically only for authors who already have a contribution merged in this repository. A maintainer will review this PR and approve CI to run on it. |
1 of 6 tasks
Contributor
|
[For maintainers] Suggested jobs to run (before merge) run-slow: longcat_flash, minimax_m2, minimax_m3_vl, step3p7 |
This branch has not been 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.
What does this PR do?
What's wrong
These models route like DeepSeek-V3: they add
e_score_correction_biasto the sigmoid scores, then take the top-k:minimax_m3_vl)More than 20 models with that router already declare
_keep_in_fp32_modules_strict = ["e_score_correction_bias"], including DeepSeek-V3, GLM-4.5/4.6/4.7, dots1 and MiMo-V2. These four don't. Withdtype=torch.bfloat16, the bias is rounded to bf16.For MiniMax and Step that breaks routing. Their checkpoints store the bias in float32, and its values are large but differ little between experts:
router_bias)Near 8, bf16 values are 0.0625 apart, so the rounding error (up to 0.031) is larger than the gap between the sigmoid scores of competing experts. Expert selection then follows the rounding of the bias rather than the router.
MiniMax also stores the router weight (
gate.weight) in float32. Its quantization config keeps it out of FP8 (modules_to_not_convert: ["gate", "e_score_correction_bias", "lm_head"]). The router already casts its input to the weight's dtype (F.linear(hidden_states.to(self.weight.dtype), self.weight)). Undertorch.autocast, which Trainer turns on forbf16=True, that matmul still runs in bf16.Impact
Measured on MiniMax-M2.5's first MoE layer, using the real checkpoint tensors on 16,384 tokens (4 × 4096, prose and code):
dtype=torch.bfloat16MiniMax-M2 gives the same picture:
So on main, almost every token has about half of its 8 expert slots filled by experts the float32 router would not pick. The bias causes almost all of this. The bf16 gate causes the remaining 13–14%, and the effect differs by checkpoint:
The router computes in the weight's dtype, so keeping the weight in float32 covers both cases.
LongCat-Flash's biases are centred near zero, so bf16 costs little there. It is included so the checkpoint's float32 values are kept as for the other models.
Fix
MiniMaxM2PreTrainedModel:_keep_in_fp32_modules_strict = ["e_score_correction_bias", "mlp.gate.weight"].MiniMaxM3VLinherits it through the modular file.Step3p7PreTrainedModelandLongcatFlashPreTrainedModel:_keep_in_fp32_modules_strict = ["e_score_correction_bias"].MiniMaxM2TopKRouterandMiniMaxM3VLTopKRouter: the matmul runs undermaybe_autocast(device_type, enabled=False), so it computes in the gate's dtype even under autocast.Ernie4_5_MoeTopKRouteralready does this. Step-3.7's router is generated from M3-VL and gets the same wrapper; its gate is bf16 there, so it computes in bf16 as before. Without autocast,maybe_autocastis anullcontext, and the outputs are unchanged.The modeling files are regenerated from the modular files, and
utils/check_modular_conversion.pypasses. Step'srouter_biasis renamed toe_score_correction_biasbefore the keep-in-fp32 match, which the test covers throughsave_pretrained/from_pretrained.Tests
One new test per model (
test_router_and_correction_bias_kept_in_float32for both MiniMax models,test_e_score_correction_bias_kept_in_float32for Step-3.7 and LongCat):8.5 + 0.02 * arange(n).save_pretrained, thenfrom_pretrained(..., dtype=torch.bfloat16).torch.autocast("cpu", dtype=torch.bfloat16).Results:
torch.bfloat16 != torch.float32); with the fix, all four pass.utils/check_modular_conversion.pypasses, and ruff 0.14.10 check and format are clean.Related
test_modeling_minimax_m3_vl.py. Both PRs only add code there, so they shouldn't conflict. The keep-in-fp32 match runs on the renamed keys (mlp.gate.weight), which that PR keeps.Code Agent Policy
The Transformers repo is currently being overwhelmed by a large number of PRs and issue comments written by code agents. These often are low-quality, or fix extremely minor issues that occur rarely or never in practice. As a result, we're instituting a rule that first-time contributors should not use code agents to submit PRs or issues. We'd also ask autonomous "OpenClaw"-like agents not to open any PRs or issues.
Issues/PRs from first-time contributors that violate this rule will probably just be closed without review, and we might block you, especially if you open more than one or appear to be deliberately ignoring this. We especially do not want new contributors to jump in on random issues to contribute an agent-written fix. This creates lots of noise for reviewers and other users and will almost certainly get you blocked.
For more information, please read
CONTRIBUTING.md.The code, the tests and this description were drafted with an AI coding agent (Claude Code), so the box above is not checked.
Before submitting
Who can review?
Anyone in the community is free to review the PR once the tests have passed. Feel free to tag members/contributors who may be interested in your PR.