Skip to content

[MXFP8] Consume directly blocked activation scales - #5334

Open
sanketpurandare wants to merge 1 commit into
dsv3-mtp-loss-metricsfrom
dsv3-mxfp8-blocked-activation-scales
Open

sanketpurandare wants to merge 1 commit into
dsv3-mtp-loss-metricsfrom
dsv3-mxfp8-blocked-activation-scales

Conversation

@sanketpurandare

@sanketpurandare sanketpurandare commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Performnace of this fused cute-dsl quantizer is better than cuda, a single API for dense and grouped mxfp8 linears, no need for scale rearrangements since swizzled layouts are directly output.

Consume TorchAO's landed fused dense rowwise/columnwise cast and single-axis
CuTeDSL casts directly, with blocked E8M0 scales and offs=None. Activation casts
live with weight quantization in tensor.py and use a shared RCEIL constant;
the existing square weight kernel's fixed RCEIL contract is explicitly enforced.
Select CuTeDSL automatically for 128-aligned BF16 operands, with no Linear/
converter backend option or saved autograd backend state. Use CUDA MXFP8 plus
blocked-scale rearrangement only for unsupported operand geometry, not missing
dependencies. Report missing AO/CuTeDSL dependencies with installation guidance
before that linear's parameter allocation. Preserve input-save formats,
32x32 RCEIL weight-scale policy, FSDP lifecycle, gradient destinations and
non-owned output behavior. Reject
unsupported required providers instead of padding or silently falling back.
Credit Protonu's #4895 kernel and Aleksandar's single-axis metadata work; only
landed AO #4995 is the runtime dependency.

Add complete PP2/VPP8/DP128 and PP4/VPP4/DP64, EP64 671B/MTP1 MLPerf recipes
using indexed aligned input sources, global strided ordering, GBS 15360/T4096
and fixed GBS 1024 validation. Reuse the earlier validation, MTP and dense-SDPA
interfaces. Include MXFP8 on the shared head, opt into its existing coalesced
training projection. Choose casts per actual operand: KV-A's aligned forward
input uses CuTeDSL, while its unsupported 576-wide output gradient uses CUDA.
The redundant recipe-level module-backend selector is removed.
Storage adapters and warmed checkpoint binding stay outside core TorchTitan.
Preserve current main's nested MLA KV-B projection selector, with an explicit
check that all 62 main/MTP projections retain MXFP8 rather than BF16 inputs.

Match NVIDIA's BF16 router GEMMs/logits/backward boundary, FP32 sigmoid and
selection, BF16 selected weights, unbiased top-8 sequence auxiliary coefficient
0.01, scale 2.5 and uncentered expert-bias update 0.001. Generic defaults remain
unchanged. Preserve FP32 persistent/final updates, BF16 gather/accumulation/
reduction/Adam moments, selective decay 0.033, clipping 1 and the zero-start
LR multipliers 0/.25/.5/.75/1 with a 11996-update cosine horizon.

Both optimizer/training and landed validation CUDA graphs are enabled.
Expose the existing graph wrapper's eager warmup count through TrainingConfig
(default2, production1) for both training and optimizer capture. Keep the
shared pool's landed eval-first readiness gate. Persisted map-dataset sharding
uses the explicit map_dataset_dp_sharding policy from the data PR. Forced
recipes select CF1; learned recipe defaults retain their conservative CF32 scratch
and minimum saved-activation policy. A run-specific wrapper may set measured
scratch/slot limits on the returned config. VMM and GraphTrainer are excluded.
Future router/sequence/CE fusion overrides are intentionally not imported at
this boundary; their integration belongs to the next three separate PRs.

Verification

Owning-commit CPU checks: 152 passed, 19 warnings in 34.43s.

Strict relevant Sphinx builds and all non-type repository hooks passed.
Three unchanged main type findings remain attributed, not reported as a clean
full type run. External reviewer and CI acceptance are separate, still pending.

Complete-stack integration (not this PR in isolation): real four-GPU PP2/DP2/
EP2 and PP4/DP1/EP1 ran ten updates with exact model/optimizer tensor parity,
optimizer graphs and sequential validation. A fresh native PP2/PP4 checkpoint
matrix matched resumed state exactly. These are debug-model contract checks,
not 671B throughput or convergence results.

The final 207-case GPU matrix covers in-place gradients, dense attention, PP/FSDP train/eval graphs, shared-stream backward/capture and fused numerical contracts.

@sanketpurandare
sanketpurandare added this pull request to stack #5331 October 12, 2026 19:23
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 12, 2026
@sanketpurandare
sanketpurandare force-pushed the dsv3-mxfp8-blocked-activation-scales branch 2 times, most recently from 389cd35 to 1a1ba79 Compare October 13, 2026 01:58
@@ -0,0 +1,126 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider moving this to torchtitan/quantization/mxfp8/tensor.py where we already have a quantize method

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the helpers into tensor.py, alongside weight quantization, and removed activation.py.

"MXFP8Linear",
]

# Activation and gradient quantization takes a scaling mode; the 32x32 weight

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets not delete this. And lets make sure both weight and activation uses this singleton.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restored a shared RCEIL constant for activation casts and the weight-cast contract. AO's weight kernel is RCEIL-only, so the wrapper checks that invariant.

If empty, all Linear modules are converted.
"""
activation_quantization_backend: Literal["cuda", "cutedsl"] = "cuda"
"""Activation cast backend; CuTeDSL requires 128-aligned BF16 matrices."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why even give an option? Why not always choose "cutedsl" - if its only import related issue, we can give a good error message to guide the user/agent to install the right packages.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the backend knob. CuTe is now automatic for supported shapes; CUDA is only for unsupported ones, such as KV-A's 576-wide gradient. Its forward input uses CuTe. Missing dependencies raise an installation error, not a fallback. Forward/backward and FSDP capture/replay checks passed.

@anijain2305 anijain2305 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider just making cutedsl the default and not give an option for cuda. Users will not know when to choose which.

@sanketpurandare
sanketpurandare force-pushed the dsv3-mxfp8-blocked-activation-scales branch from 1a1ba79 to b14b77b Compare October 14, 2026 22:02
@sanketpurandare
sanketpurandare force-pushed the dsv3-mxfp8-blocked-activation-scales branch from b14b77b to fc932b4 Compare October 19, 2026 23:44
@sanketpurandare
sanketpurandare removed this pull request from stack #5331 October 20, 2026 15:21
@sanketpurandare
sanketpurandare force-pushed the dsv3-mxfp8-blocked-activation-scales branch from fc932b4 to 2efe864 Compare October 20, 2026 15:22
@sanketpurandare
sanketpurandare added this pull request to stack #5567 October 20, 2026 15:22
Performnace of this fused cute-dsl quantizer is better than cuda, a single API for dense and grouped mxfp8 linears, no need for scale rearrangements since swizzled layouts are directly output.

Consume TorchAO's landed fused dense rowwise/columnwise cast and single-axis
CuTeDSL casts directly, with blocked E8M0 scales and offs=None. Activation casts
live with weight quantization in tensor.py and use a shared RCEIL constant;
the existing square weight kernel's fixed RCEIL contract is explicitly enforced.
Select CuTeDSL automatically for 128-aligned BF16 operands, with no Linear/
converter backend option or saved autograd backend state. Use CUDA MXFP8 plus
blocked-scale rearrangement only for unsupported operand geometry, not missing
dependencies. Report missing AO/CuTeDSL dependencies with installation guidance
before that linear's parameter allocation. Preserve input-save formats,
32x32 RCEIL weight-scale policy, FSDP lifecycle, gradient destinations and
non-owned output behavior. Reject
unsupported required providers instead of padding or silently falling back.
Credit Protonu's #4895 kernel and Aleksandar's single-axis metadata work; only
landed AO #4995 is the runtime dependency.

Add complete PP2/VPP8/DP128 and PP4/VPP4/DP64, EP64 671B/MTP1 MLPerf recipes
using indexed aligned input sources, global strided ordering, GBS 15360/T4096
and fixed GBS 1024 validation. Reuse the earlier validation, MTP and dense-SDPA
interfaces. Include MXFP8 on the shared head, opt into its existing coalesced
training projection. Choose casts per actual operand: KV-A's aligned forward
input uses CuTeDSL, while its unsupported 576-wide output gradient uses CUDA.
The redundant recipe-level module-backend selector is removed.
Storage adapters and warmed checkpoint binding stay outside core TorchTitan.
Preserve current main's nested MLA KV-B projection selector, with an explicit
check that all 62 main/MTP projections retain MXFP8 rather than BF16 inputs.

Match NVIDIA's BF16 router GEMMs/logits/backward boundary, FP32 sigmoid and
selection, BF16 selected weights, unbiased top-8 sequence auxiliary coefficient
0.01, scale 2.5 and uncentered expert-bias update 0.001. Generic defaults remain
unchanged. Preserve FP32 persistent/final updates, BF16 gather/accumulation/
reduction/Adam moments, selective decay 0.033, clipping 1 and the zero-start
LR multipliers 0/.25/.5/.75/1 with a 11996-update cosine horizon.

Both optimizer/training and landed validation CUDA graphs are enabled.
Expose the existing graph wrapper's eager warmup count through TrainingConfig
(default2, production1) for both training and optimizer capture. Keep the
shared pool's landed eval-first readiness gate. Persisted map-dataset sharding
uses the explicit map_dataset_dp_sharding policy from the data PR. Forced
recipes select CF1; learned recipe defaults retain their conservative CF32 scratch
and minimum saved-activation policy. A run-specific wrapper may set measured
scratch/slot limits on the returned config. VMM and GraphTrainer are excluded.
Future router/sequence/CE fusion overrides are intentionally not imported at
this boundary; their integration belongs to the next three separate PRs.

python -m pytest tests/unit_tests/cpu/test_trainer.py tests/unit_tests/cpu/components/test_validator.py tests/unit_tests/cpu/config/test_config_validation.py tests/unit_tests/cpu/models/common/test_dist_moe.py -q -k 'not graph_training'
python -m pytest tests/unit_tests/gpu/quantization/test_mxfp8_linear.py tests/unit_tests/gpu/quantization/test_mxfp8_fsdp.py -q
pre-commit run --all-files

Current owning checks passed169 CPU/config/recipe tests and51 actual GPU
consumer/FSDP tests, including CuTe/CUDA operand parity, FakeTensor metadata,
head in-place accumulation, compiled/captured FSDP lifecycle and exact
backward accumulation. Strict current warmup/MXFP8/MTP/API Sphinx rendering
passed. All non-type lint hooks passed; only unchanged baseline type findings
remained. The complete updated real-PP2/PP4 provider matrix is still pending;
no current throughput or full-cluster convergence claim follows from these
owning correctness checks.
@sanketpurandare
sanketpurandare removed this pull request from stack #5567 October 23, 2026 21:49
@sanketpurandare
sanketpurandare force-pushed the dsv3-mxfp8-blocked-activation-scales branch from 2efe864 to 7544cfa Compare October 23, 2026 21:49
@sanketpurandare
sanketpurandare added this pull request to stack #5604 October 23, 2026 21:50
@sanketpurandare
sanketpurandare marked this pull request as ready for review October 23, 2026 21:51
@pytorch-bot pytorch-bot Bot added the ciflow/b200 Trigger B200 CI label Oct 23, 2026
@pytorch-bot pytorch-bot Bot added the ciflow/fake-pg Run 1-GPU Fake PG integration tests label Oct 23, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciflow/b200 Trigger B200 CI ciflow/fake-pg Run 1-GPU Fake PG integration tests ciflow/rl CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants