Repository navigation
[MXFP8] Consume directly blocked activation scales - #5334
sanketpurandare wants to merge 1 commit into
Conversation
389cd35 to
1a1ba79
Compare
| @@ -0,0 +1,126 @@ | |||
| # Copyright (c) Meta Platforms, Inc. and affiliates. | |||
There was a problem hiding this comment.
Consider moving this to torchtitan/quantization/mxfp8/tensor.py where we already have a quantize method
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Lets not delete this. And lets make sure both weight and activation uses this singleton.
There was a problem hiding this comment.
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.""" |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
left a comment
There was a problem hiding this comment.
We should consider just making cutedsl the default and not give an option for cuda. Users will not know when to choose which.
1a1ba79 to
b14b77b
Compare
b14b77b to
fc932b4
Compare
fc932b4 to
2efe864
Compare
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.
2efe864 to
7544cfa
Compare
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.