Skip to content

[Attn] Remove SDPA and use Varlen attention in Flux - #5296

Merged
acisseJZhong merged 12 commits into
mainfrom
refactor_attn
Oct 12, 2026
Merged

acisseJZhong merged 12 commits into
mainfrom
refactor_attn

Conversation

@acisseJZhong

@acisseJZhong acisseJZhong commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

This PR removes the core SDPA backend and moves Flux and GraphTrainer recipes to shared Varlen attention, reducing the number of attention implementations to maintain.

Flux keeps its existing [B, L, D] activations and packs Q/K/V only at attention calls. Per-sample document boundaries are built once per forward, preserving bidirectional attention within each sample and isolation between samples. Under CP, K/V are gathered before packing.

Tests

Full Flux-dev and Flux-schnell (11.89B parameters), 8 H100s, BF16, FSDP=8, CP=1, full activation checkpointing, 256x256 images. Each backend ran 20 training steps using randomly initialized weights, the CC12M test shard, and offline tokenizers.

Original SDPA (3210be8297) vs Varlen (d2ddc8d2d5), both cuDNN. PyTorch 2.14.0+cu130 / cuDNN 9.24; seed 42, TF32 off, deterministic=False, CUDA graphs off.

Numerics

Maximum differences across 20 steps:

Model Max absolute loss difference Max relative grad_norm difference
Flux-dev 3.06e-05 0.0341%
Flux-schnell 1.80e-04 0.1305%

Both loss traces pass rtol=1e-3, atol=1e-5; Schnell's grad_norm exceeds this tolerance. These runs are not bitwise identical.

Separate 10-step flux-debug regression, seed 42 and strict determinism, CP=1/2: outputs, loss, grad_norm, gradients, and final weights match the previous Varlen implementation (0b34e4ea36) bitwise.

Performance

Median of steps 11-20, including data loading, encoders, forward/backward, optimizer, and communication; CUDA-synchronized wall time, slowest rank.

Model Per-GPU batch x sequence SDPA/cuDNN (s/step) Varlen/cuDNN (s/step) Slowdown
Flux-dev 32 x 768 4.5748 4.5895 +0.32%
Flux-schnell 64 x 512 5.6795 5.6832 +0.07%

Schnell's 0.07% difference is within the observed step-to-step variation (5-6 ms standard deviation).

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 11, 2026
@acisseJZhong
acisseJZhong added this pull request to stack #5297 October 11, 2026 23:13
@acisseJZhong acisseJZhong changed the title Remove shared SDPA and use Varlen attention in Flux [Attn] Remove SDPA and use Varlen attention in Flux Oct 11, 2026
@acisseJZhong
acisseJZhong removed this pull request from stack #5297 October 12, 2026 05:31
@acisseJZhong
acisseJZhong added this pull request to stack #5308 October 12, 2026 05:32
@acisseJZhong
acisseJZhong marked this pull request as ready for review October 12, 2026 06:41
@pytorch-bot pytorch-bot Bot added the ciflow/fake-pg Run 1-GPU Fake PG integration tests label Oct 12, 2026

@tianyu-l tianyu-l 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.

inlined comments

Comment thread torchtitan/models/flux/sharding.py Outdated
)


def create_flux_attention_metadata(

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.

do we need this as public API?
also I feel it doesn't belong to "sharding"

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 to model.py and changed the name to **_get_attention_metadata** to align with main decoder.

Comment thread torchtitan/models/flux/layers.py Outdated
return out_THV.unflatten(0, (batch_size, -1))


def varlen_attention(

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.

should this be private function

Comment thread torchtitan/models/flux/layers.py Outdated
return q_BLHK.flatten(0, 1), k_BLHK.flatten(0, 1), v_BLHV.flatten(0, 1)


def prepare_flux_attention_inputs(

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.

similar

cp_group = spmd_mesh_group(CP)
if cp_group is not None:
k_BLHK, v_BLHV = (
spmd.redistribute(

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.

flux cp is not via transform -- seems fine

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.

yes we are explicitly doing cp preprocess here as right now flux only have kv all gather and varlen. cc @fegin

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.

For consistency, we should do transform. But we can do this only if we have more CP supports for Flex.

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.

left a todo comment

@fegin fegin 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.

Thanks for removing SDPA.

cp_group = spmd_mesh_group(CP)
if cp_group is not None:
k_BLHK, v_BLHV = (
spmd.redistribute(

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.

For consistency, we should do transform. But we can do this only if we have more CP supports for Flex.

Delete the experimental SDPA backend and its flat-input adapter. Use the
shared Varlen backend in graph test recipes and pass its metadata into
bitwise tests. Update the CP codegen check for Flash Attention operators.
Use a math-only attention reference for CPU infrastructure tests; keep
checkpoint-comparison SDPA isolated under scripts.

Validation:
- 7 targeted tests and 4 subtests passed (1 recipe case deselected).
- Real Llama3 debug model: 10 synthetic AdamW steps, seed 42 and
  deterministic algorithms; eager and minimal_fx_tracer replay have
  bitwise equal losses, grad_norms, and all parameter gradients.
- Serialized Varlen graphs replay changed document boundaries exactly.
- Checkpoint reference matches the removed backend in FP32/BF16 forward
  and backward.
- Non-Pyrefly all-file pre-commit checks pass; new helpers/tests typecheck.

Full recipe/FSDP validation is blocked by missing local PyTorch APIs
(analyze_pipeline_activation_liveness and param_dtype_override_fn).
Global Pyrefly fails on existing environment import/path errors.
Already-disabled AutoParallel tests still need Varlen metadata input
sharding before they can be enabled.
@acisseJZhong
acisseJZhong merged commit 90c7fa4 into main Oct 12, 2026
29 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

3 participants