Skip to content

[mxfp8 training] fused gated-activation (SwiGLU) + MXFP8 quantization kernel override - #2

Closed
wolfcomos wants to merge 4 commits into
mainfrom
swiglu-mxfp8-fusion
Closed

[mxfp8 training] fused gated-activation (SwiGLU) + MXFP8 quantization kernel override #2
wolfcomos wants to merge 4 commits into
mainfrom
swiglu-mxfp8-fusion

Conversation

@wolfcomos

@wolfcomos wolfcomos commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Summary

Adds an opt-in override module, torchtitan/overrides/mxfp8_fused_swiglu.py, that runs a
FeedForward / routed-experts MLP entirely in MXFP8 with a fused SwiGLU boundary: one composite
autograd function computes w13 GEMM -> fused SwiGLU + dual MXFP8 quantization -> w2 GEMM
(dense and grouped variants), using torchao's fused gated-activation kernel
(pytorch/ao#4743) for the activation boundary and torchao's MXFP8 grouped/scaled-mm internals
for the GEMMs. Compared to the unfused MXFP8 path, the fused boundary eliminates the standalone
activation-quantization casts (fused mode launches 1 fwd + 1 bwd fused op instead of 6 + 6
standalone cast kernels per MLP) and never materializes the BF16 post-activation tensor.

The integration contained:

  • MXFP8FusedSwiGLU(FusedSwiGLU) and MXFP8FusedGroupedExperts(FusedGroupedExperts) subclass
    the existing fused modules (inheriting the w13 parameter, stock-layout checkpoint hooks, and
    init/sharding remaps) and override only forward.
  • Two @override factories: mxfp8_fused_swiglu (targets FeedForward.Config) and
    mxfp8_fused_grouped_experts (targets RoutedExperts.Config, which owns both the token
    dispatcher and the inner experts — the factory swaps the dispatcher to the padded variant its
    kernels require, pad_multiple=128).
  • Zero changes to existing files' behavior: overrides/fused_swiglu.py,
    components/quantization/mx.py, and the quantization converters are untouched. Enabling the
    override is the only opt-in; no converter or job-config plumbing is added.

Fail-loud contract

There is no silent fallback anywhere in this path. Unsupported configurations raise actionable
errors naming the offending value (unsupported SM at override-application time; non-%128 dims,
non-BF16 dtypes, DTensor activations, and misaligned token counts at call time — data-dependent
token counts use torch._check deferred asserts so routing-dependent shapes work under
torch.compile). The user changes the config; the code never substitutes a different numerics
path than the one configured.

Usage

# dense (llama3 debugmodel example flavor)
--override.imports torchtitan.overrides.mxfp8_fused_swiglu.mxfp8_fused_swiglu

# routed experts (deepseek_v3 debugmodel example flavor; needs EP>=2 so the token
# dispatcher produces the padded expert-major layout the kernels consume)
--override.imports torchtitan.overrides.mxfp8_fused_swiglu.mxfp8_fused_grouped_experts

Example flavors: llama3_debugmodel_mxfp8_fused_swiglu, deepseek_v3_debugmodel_mxfp8_fused_swiglu
(both enable compile; attention/lm_head stay BF16 — composable with MXFP8LinearConverter on
those modules independently).

Numerics and tests

  • Shipped: tests/unit_tests/test_mxfp8_swiglu_override.py — CPU-runnable wiring suite
    (config-tree transform, apply_overrides, meta-device build, dispatcher pad_multiple,
    factory fail-loud), validated both with GPUs visible and with CUDA_VISIBLE_DEVICES="".
  • GPU numerics are validated in NVIDIA-internal Blackwell CI and will be maintained there
    (upstream CI has no SM100): 25-test suite on GB200 covering bitwise forward parity between the
    fused kernel and standalone-cast quantization, SQNR tracking against the per-GEMM MXFP8 and
    BF16 references, torch.compile with unbacked routing-dependent token counts, dispatcher
    pad-row/tail inertness, and profiler op-count contracts.
  • Kernel-level numerics (bitwise forward, one-code-bounded backward at ~6e-7 of elements, root-
    caused to the kernel's correctly-rounded sigmoid + FMA contraction) are documented in
    [mxfp8 training] Add a fused gated-activation (SwiGLU) + MXFP8 quantization kernel pytorch/ao#4743.

Your Name and others added 4 commits August 9, 2026 00:49
…sedSwiGLU

Integrates the TorchAO unified SwiGLU+MXFP8 CuTe DSL composite
(mxfp8_swiglu_mlp_w13 / mxfp8_swiglu_grouped_mlp_w13) behind a new
fuse_swiglu_mxfp8 config flag, with A/B debug configs for Llama3
(llama3_debugmodel_mxfp8[_fused_swiglu]) and DeepSeek-V3
(deepseek_v3_debugmodel_mxfp8[_fused_swiglu]). Both arms share the
composite autograd boundary; only fuse_activation differs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mirrors the JET regular-MXFP8 workload (MXFP8Linear over attention, dense FFN
and shared-expert linears, plus MXFP8 routed-expert grouped GEMMs) so the
SwiGLU fusion can be measured end to end rather than only in a microbenchmark.

Three arms, because the fused-w13 override and the unified SwiGLU+MXFP8 kernel
are independent changes and move in opposite directions:

  deepseek_v3_16b_mxfp8_exp               no override (the JET control)
  deepseek_v3_16b_mxfp8_w13_exp           fused w13 GEMM, standalone casts
  deepseek_v3_16b_mxfp8_fused_swiglu_exp  fused w13 + unified kernel

Measured on 4x GB200 (EP=4, bs=4, seq=4096, 50 steps), averaged over steps
11-50: the w13 override alone is -0.51% TFLOPs and +3.3GiB, the unified kernel
adds +2.51% on top of it, for +1.98% against the control. Loss at step 50
agrees to within 1.5e-3 across all three.

Uses the in-repo test tokenizer and c4_test so the configs run without
downloaded assets; token content affects neither FLOPs nor kernel shapes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Moved from torchao (which now offers only the fused gated-activation
kernels): the autograd composite, its tests, and the FusedSwiGLU import
sites. No functional change; 34 composite + 18 override tests pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
torchao moved the fused gated-activation custom ops out of quant.py into
the kernel module and renamed them with the cutedsl infix
(gated_act_mxfp8_cutedsl_{forward,backward}). The composite now imports
the wrappers lazily at the two fused-path call sites -- the kernel module
imports the CuTe DSL runtime at module scope, and the unfused fallback
must keep working without it. Trace-count assertions updated to the new
op names.

52/52 swiglu unit tests green against torchao 39db5297.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dgrad activation casts, while the BF16 activation values needed by the two
weight-gradient GEMMs are recomputed from the saved gated projection. Shapes
the CuTeDSL kernels cannot handle still fall back to the existing per-GEMM
``mx_mm`` path (or plain BF16 as a last resort) instead of asserting.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

i'd advocate against falling back to bf16 based on shape, IMO better to honor the user config and let the user change the config if it cannot be executed

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Thanks a lot for the review @vkuzo ! I addressed this and it's now updated at pytorch#4257.

@wolfcomos wolfcomos changed the title Swiglu mxfp8 fusion Add a fused gated-activation (SwiGLU) + MXFP8 quantization kernel override Aug 20, 2026
@wolfcomos wolfcomos changed the title Add a fused gated-activation (SwiGLU) + MXFP8 quantization kernel override Add fused gated-activation (SwiGLU) + MXFP8 quantization kernel override Aug 20, 2026
@wolfcomos wolfcomos changed the title Add fused gated-activation (SwiGLU) + MXFP8 quantization kernel override [mxfp8 training] fused gated-activation (SwiGLU) + MXFP8 quantization kernel override Aug 20, 2026
@wolfcomos wolfcomos closed this Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants