Repository navigation
Conversation
torch.autocast runs F.linear in bf16 and undoes the explicit float32 casts of the DeepSeek-style routers. Run the router matmul with autocast disabled, as Ernie4_5_MoeTopKRouter does.
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. |
Draft
1 of 6 tasks
Contributor
|
[For maintainers] Suggested jobs to run (before merge) run-slow: axk1, axk2, bailing_hybrid, beam, deepseek_ocr2, deepseek_v2, deepseek_v3, deepseek_v32, dots1, exaone_moe, glm4_moe, glm4_moe_lite, glm4v_moe, glm5_next, glm_moe_dsa, hy_v3 |
1 of 6 tasks
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
The DeepSeek-V2/V3-style routers compute their logits as
F.linear(hidden_states.type(torch.float32), self.weight.type(torch.float32)), and 23 other models copy or inherit these routers. Undertorch.autocast(dtype=torch.bfloat16), autocast runsF.linearin bf16 and undoes the casts. The logits come back in bf16, so the sigmoid/softmax, bias addition and top-k all run on bf16 scores. Trainer and Accelerate turn on autocast forbf16=True(outside DeepSpeed). As a result, a bf16 fine-tune of these models picks different experts than inference does with the same weights.Reproduction
On main (50e35cc):
With this change:
torch.float32and0.0%.Impact
The bug affects any bf16-autocast training or evaluation of axk1, axk2, bailing_hybrid, beam, deepseek_ocr2, deepseek_v2, deepseek_v3, deepseek_v32, dots1, exaone_moe, glm4_moe, glm4_moe_lite, glm4v_moe, glm5_next, glm_moe_dsa, hy_v3, hy_v4, kimi_linear, kolibri1, longcat_flash, mimo_v2_flash, muse_spark, nemotron_h, solar_open and unlimited_ocr. Ernie 4.5 MoE (text and VL) and Flint already disable autocast around their router matmul, and they behave correctly.
I measured this on
zai-org/GLM-4.7-Flash(glm4_moe_lite, 64 experts, top-4, sigmoid router) with these settings:Each cell is the share of tokens whose top-4 expert set changes under
torch.autocast("cuda", dtype=torch.bfloat16):Fix
The router matmul now runs under
maybe_autocast(device_type=device_type, enabled=False), the same wayErnie4_5_MoeTopKRouterandFlintTopKRouteralready do it. The explicit casts stay, because bf16 weights still need them when autocast is off.modeling_*.pyfiles were regenerated from them.sigmoid,topkorgather, and it already runssoftmaxin float32.maybe_autocastreturns anullcontextwhen autocast is off. Without autocast, outputs are unchanged and torch.compile gets no extra nodes. Afullgraph=Truecompile of the router works both with and without autocast.F.linearbranch is wrapped. Itstorch.mm(..., out_dtype=torch.float32)fast path already returns float32 under CUDA autocast (checked).Not changed here: routers that compute in the activations' dtype (Qwen3-MoE, Mixtral) don't ask for float32.
MiniMaxM2TopKRouter,MiniMaxM3VLTopKRouterandStep3p7TopKRouter(step3p7 is generated from minimax_m3_vl) computeF.linear(hidden_states.to(self.weight.dtype), self.weight), so they run in the gate's dtype.MiniMaxM2TopKRouter, but it has its own float32 forward, which is fixed here.Tests
test_router_ignores_autocasttotests/models/deepseek_v3andtests/models/deepseek_v2. The test checks that the router output (logits, weights, indices) undertorch.autocast(torch_device, dtype=torch.bfloat16)equals the output without autocast, and that the logits are float32.AssertionError: torch.bfloat16 != torch.float32.-k "not slow", CPU, macOS): 3889 passed, 2830 skipped, 52 failed.utils/check_modular_conversion.pyreports the 25 models as consistent.utils/check_copies.pyandruff check/ruff format --check(ruff 0.14.10) pass on the changed files.Note for
run-slow: the unlimited_ocr integration tests wrapgeneratein bf16 autocast to match the reference implementation. The referenceMoEGatehas the sameF.linear(... float32 ...)pattern, so under that autocast it actually routes in bf16. Those expected outputs may need an update. Suggested:run-slow: deepseek_v2, deepseek_v3, glm4_moe, glm4_moe_lite, kolibri1, unlimited_ocr.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.