Enable native-TE MXFP4 training for Flux on MI355X - #909
Open
amital-amd wants to merge 2 commits into
Open
Conversation
amital-amd
requested review from
Xiaoming-AMD,
limou102 and
wenxie-amd
as code owners
July 22, 2026 10:20
Contributor
There was a problem hiding this comment.
Pull request overview
Enable end-to-end MXFP4 Flux training on MI355X using TransformerEngine’s native autocast path (no dependency on Primus-Turbo autocast), while also ensuring the requested attention backend is honored and quantization contexts are routed correctly.
Changes:
- Add
fp4_use_native_te_autocastplumbing/config to force TE-native FP4 autocast selection inget_fp4_context. - Fix Flux quantization context routing so FP4 runs use FP4 context (and FP8 takes precedence when both are set).
- Coerce YAML
attention_backendstrings toAttnBackend(with robust handling for null/blank/invalid), and add a validated MI355X training recipe plus unit tests.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/unit_tests/backends/megatron/diffusion/training/test_flux_model_creation.py | Adds unit tests for YAML attention_backend coercion and error handling. |
| tests/unit_tests/backends/megatron/diffusion/test_fp4_context.py | Adds unit tests verifying TE-native vs Primus-Turbo FP4 autocast branch selection. |
| tests/unit_tests/backends/megatron/diffusion/test_flux_fp8_context.py | Extends tests to cover Flux FP8/FP4 context routing and precedence behavior. |
| primus/backends/megatron/flux_pretrain_trainer.py | Coerces attention_backend strings to AttnBackend and plumbs fp4_use_native_te_autocast into FluxConfig. |
| primus/backends/megatron/core/models/diffusion/flux/model.py | Updates get_fp8_context() to return FP8, FP4, or nullcontext depending on config and spec. |
| primus/backends/megatron/core/models/diffusion/flux/config.py | Introduces fp4_use_native_te_autocast configuration flag (TE-spec FP4 autocast backend selection). |
| primus/backends/megatron/core/fp4_utils.py | Changes Turbo-vs-TE-native FP4 autocast selection logic to honor fp4_use_native_te_autocast. |
| examples/megatron/configs/MI355X/diffusion/flux_12b_ddp_energon_schnell_resample_te_spec_mxfp4.yaml | Adds MI355X recipe exercising TE-spec + fused attention + MXFP4 via TE-native autocast. |
Comment on lines
146
to
+153
| fp4_recipe, fp4_recipe_none_reason = get_fp4_recipe(config) | ||
| turbo_enabled = _primus_turbo_enabled() | ||
| # fp4_use_native_te_autocast forces the TE-native autocast branch | ||
| # (TE fp8_autocast + MXFP4BlockScaling -> AITER a4w4), bypassing | ||
| # Primus-Turbo entirely -- even if the Turbo autocast is otherwise | ||
| # enabled. This is the pure-TE MXFP4 path (enable_primus_turbo=false). | ||
| turbo_enabled = _primus_turbo_enabled() and not getattr( | ||
| config, "fp4_use_native_te_autocast", False | ||
| ) |
Make MXFP4 Flux training work end to end on the pure TransformerEngine
path, with no dependency on the Primus-Turbo autocast layer. Previously
MXFP4 could only be driven through Primus-Turbo; running the TE spec with
enable_primus_turbo=false either fell back to BF16 GEMMs or ignored the
configured attention backend, so a "TE MXFP4" run was silently neither.
This change adds the switch that selects the native-TE path and fixes the
two quantization/attention gaps that were undermining it, then ships a
validated MI355X recipe that exercises the whole path.
Route FP4 autocast through TransformerEngine
- FluxConfig.fp4_use_native_te_autocast (config.py) opts a run into TE's
own fp8_autocast with the MXFP4BlockScaling recipe (TE -> AITER a4w4).
- get_fp4_context (fp4_utils.py) treats the flag as an override: when set
it takes the TE-native branch even if Primus-Turbo is otherwise enabled,
so enable_primus_turbo=false yields a genuine pure-TE MXFP4 run.
- flux_pretrain_trainer.py plumbs the option from params into FluxConfig.
Serve the right quantization context for FP4 runs
- Flux.get_fp8_context() (model.py) previously always delegated to the FP8
utility, so an FP4-only run received a context that issued no FP4 GEMMs
and silently degraded to BF16. It now returns the FP8 context for FP8,
the FP4 context for FP4, and nullcontext otherwise, with FP8 taking
precedence when both are set (mirroring stock Megatron's transformer
block). The local spec still returns nullcontext, since local handles
quantization per module at init and must stay free of global state for
torch.compile.
Honor the configured attention backend
- _build_flux_config_from_yaml() (flux_pretrain_trainer.py) now coerces
the YAML attention_backend string into the AttnBackend enum before it
reaches FluxConfig. As a plain string it matched no branch in
_set_attention_backend() and silently fell back to FlashAttention, so
a recipe requesting fused CK attention never got it. An omitted or
null/blank value maps to AttnBackend.auto; an unknown value raises a
ValueError listing the valid names.
Ship the MI355X recipe
- Add the Flux 12B Schnell config: Megatron DDP + distributed optimizer,
TE spec, fused CK attention, and MXFP4 via the TE-native autocast, with
Primus-Turbo and torch.compile disabled (TE's FP4 autocast toggles
process-global state that breaks graph capture).
Add unit tests covering get_fp8_context routing (FP8/FP4/precedence/local),
the get_fp4_context native-TE-vs-Turbo branch selection, and attention_backend
coercion (string, default, null, blank, whitespace, invalid, case-sensitivity).
…bled In response to review on PR #909. Fail fast at argument validation instead of silently training in the wrong precision. fp4_use_native_te_autocast routes quantization through TE's own fp8_autocast, which never sets the Primus-Turbo FP4 state that PrimusTurboLinear consults. Combining it with use_turbo_gemm=True therefore produced Turbo GEMM linears running BF16 while the run still reported itself as MXFP4 -- the constraint was noted only in a comment on FluxConfig, so nothing stopped a config from violating it. validate_args_on_rocm now raises ValueError for that combination when FP4 is enabled, with a message naming both escape hatches (use_turbo_gemm=false for native TE MXFP4 linears, or fp4_use_native_te_autocast=false for the Primus-Turbo path). transformer_impl="local" is exempt: local specs quantize per module at init rather than off global autocast state. Extend the FluxConfig comment to say why use_turbo_gemm=false is required and to point at where that is now enforced. Add unit tests for the guard: the rejected combination, each flag alone, both flags with FP4 disabled, and the local-spec exemption. Co-authored-by: Cursor <cursoragent@cursor.com>
amital-amd
force-pushed
the
feat/flux/te-spec-mxfp4
branch
from
July 28, 2026 09:18
741be12 to
915b5b2
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
primus/backends/megatron/core/fp4_utils.py:150
- The comment says this is the "pure-TE MXFP4 path (enable_primus_turbo=false)", but the logic actually bypasses Primus-Turbo whenever fp4_use_native_te_autocast is true, even if Primus-Turbo is enabled. This wording is misleading about when the override takes effect.
# fp4_use_native_te_autocast forces the TE-native autocast branch
# (TE fp8_autocast + MXFP4BlockScaling -> AITER a4w4), bypassing
# Primus-Turbo entirely -- even if the Turbo autocast is otherwise
# enabled. This is the pure-TE MXFP4 path (enable_primus_turbo=false).
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.
Make MXFP4 Flux training work end to end on the pure TransformerEngine path, with no dependency on the Primus-Turbo autocast layer. Previously MXFP4 could only be driven through Primus-Turbo; running the TE spec with enable_primus_turbo=false either fell back to BF16 GEMMs or ignored the configured attention backend, so a "TE MXFP4" run was silently neither.
This change adds the switch that selects the native-TE path and fixes the two quantization/attention gaps that were undermining it, then ships a validated MI355X recipe that exercises the whole path.
Route FP4 autocast through TransformerEngine
Serve the right quantization context for FP4 runs
Honor the configured attention backend
Ship the MI355X recipe
Add unit tests covering get_fp8_context routing (FP8/FP4/precedence/local), the get_fp4_context native-TE-vs-Turbo branch selection, and attention_backend coercion (string, default, null, blank, whitespace, invalid, case-sensitivity).