Skip to content

Add Sparse VideoGen attention for Wan on TPUs - #480

Open
Ravi-VK wants to merge 9 commits into
AI-Hypercomputer:mainfrom
Ravi-VK:svg-head-local-pr-clean
Open

Ravi-VK wants to merge 9 commits into
AI-Hypercomputer:mainfrom
Ravi-VK:svg-head-local-pr-clean

Conversation

@Ravi-VK

@Ravi-VK Ravi-VK commented Sep 15, 2026

Copy link
Copy Markdown

Video diffusion processes long sequences of video tokens across many denoising steps, making self-attention expensive. Sparse attention reduces this cost by skipping interactions that contribute little to the output.

This PR introduces an opt-in sparse attention implementation for MaxDiffusion: Sparse VideoGen (SVG) for Wan on TPUs. SVG samples a few queries to choose a spatial or temporal pattern for each head, then computes only the selected mask. Density and active steps/layers are configurable, and SVG is disabled by default.

See SVG.md for an illustrated explanation, configuration examples, and profiling instructions.

The implementation rounds sparse boundaries to hardware tiles, approximately preserving the attention-pair budget. Selected interior tiles share one mask-free kernel; only tiles touching sequence padding need validity masks.

The feature is organized into six commits:

  1. Kernel primitives: compute attention over selected ranges of tiles.
  2. Tile rounding and dispatch: select boundary tiles and combine main and padding-tail results.
  3. Routing and layouts: choose each head’s pattern and arrange tokens for efficient execution.
  4. Wan integration: connect SVG to inference with configuration controls and unsupported-mode checks.
  5. Tests: cover routing, layouts, configuration, sharding, and kernel correctness.
  6. Documentation: explain the method, usage, profiling, and results with illustrations.

A review follow-up adds configuration and shape guards, a static inactive-step shortcut, and regression tests.

Wan2.2 720p results on TPU v6e-8, using 81 frames and 40 denoising steps:

Policy Estimated transformer FLOPs saved Denoising speedup PSNR (dB)
Conservative ≈27.2% 1.13× 26.47
Moderate ≈32.2% 1.20× 26.14
Aggressive ≈37.3% 1.28× 24.80

Timings are medians of three warm runs against same-node optimized fixed-M dense controls. PSNR uses FFmpeg’s aggregate YUV metric against dense outputs.

In an earlier evaluation using the moderate SVG policy, Wan2.2 at 720p retained 98.1% of the dense baseline’s mean VBench dimension score across a 31-prompt, 16-dimension screening subset.

SVG supports inference through the custom Ulysses/ring backends; training, Animate, external masks, periodic support, chunked Ulysses, CFG cache, and MagCache are unsupported.

@Ravi-VK
Ravi-VK requested a review from entrpn as a code owner September 15, 2026 03:07

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request implements Sparse VideoGen (SVG) attention on TPUs for Wan in MaxDiffusion, introducing modules for routing, token placement, and kernel execution. The review feedback highlights several critical issues to address: potential TypeError and AttributeError crashes in the pipeline and attention configuration logic, possible NaN propagation bugs in the attention kernels when all keys are masked out, a missing divisibility check in the Pallas partial kernel, and opportunities to optimize compilation by statically checking step_index.

Comment thread src/maxdiffusion/models/attention_flax.py
Comment thread src/maxdiffusion/kernels/custom_svg_balanced_rounding_attention.py
Comment thread src/maxdiffusion/kernels/custom_svg_static_range_attention.py
Comment thread src/maxdiffusion/kernels/custom_svg_balanced_rounding_partial.py
Comment thread src/maxdiffusion/models/wan/transformers/svg_attention.py
Comment thread src/maxdiffusion/pipelines/wan/wan_pipeline_2_2.py Outdated
Comment thread src/maxdiffusion/pipelines/wan/wan_pipeline.py Outdated

@Perseus14 Perseus14 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Added some minor comments. PTAL

Comment on lines +140 to +151
def _closest_prefix(items, target):
ordered = sorted(
items,
key=lambda x: (-x.alpha, -x.exact_pairs, x.qi, x.kj),
)
best_k, best_err, running = 0, abs(float(target)), 0
for k, tile in enumerate(ordered, 1):
running += tile.real_pairs
err = abs(float(running) - float(target))
if err < best_err:
best_k, best_err = k, err
return {(x.qi, x.kj) for x in ordered[:best_k]}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

_closest_prefix() minimizes the global pair-budget error without ensuring each query tile retains any support. It can select zero boundary tiles even when there are no full tiles.

When Q = K = 0 and every value equal to one, the kernel returns all zeros. Attention over any nonempty set of these values must return ones.

This also occurs for individual query rows on larger grids at low densities. Preserving the global budget does not guarantee valid attention locally.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in e5298b8. If rounding leaves a query tile without any keys, we now retain one boundary tile for that row and include its cost in the budget report. Added coverage checks and a TPU regression test for the constant-value example.

Comment on lines +196 to +200
low_noise_config = getattr(self.low_noise_transformer, "config", None)
if getattr(self, "use_svg_attention", False) or getattr(low_noise_config, "use_svg_attention", False):
if use_cfg_cache or use_magcache:
raise ValueError("SVG sparse attention cannot be combined with CFG cache or MagCache.")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

use_svg_attention is in attention_config and not transformer.config as per

use_svg_for_expert = bool(getattr(config, "use_svg_attention", False)) and (expert_density < 1.0)
wan_config["attention_config"] = {
"use_base2_exp": config.use_base2_exp,
"use_experimental_scheduler": config.use_experimental_scheduler,
"ulysses_shards": getattr(config, "ulysses_shards", -1),
"ulysses_attention_chunks": getattr(config, "ulysses_attention_chunks", 1),
"use_svg_attention": use_svg_for_expert,
"svg_implementation": getattr(config, "svg_implementation", "official_svg"),
"svg_spatial_density": expert_density,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in e5298b8. The low-noise check now reads use_svg_attention from attention_config. Added a regression test for low-noise SVG with incompatible caches.

with jax.named_scope("svg_route_profile"):
sequence_length = query.shape[2]
sample_pool_size = min(max(int(sample_max_row), 1), sequence_length)
sample_count = min(max(int(query_count), 1), sequence_length)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This might be more accurate sample_count = min(max(int(query_count), 1), sample_pool_size)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in e5298b8. sample_count is now capped by sample_pool_size.

Comment thread src/maxdiffusion/models/wan/transformers/svg_attention.py Outdated
Preserve nonempty rounded support for each real query tile and account for
coverage repair in the pair-budget report. Keep supported selections unchanged.
Read low-noise SVG enablement from attention_config, cap routing samples by
the configured pool, and remove the unused compute_band_width wrapper.

Add coverage, budget, sampling, and nested-configuration regressions, including
a TPU constant-value attention check. CPU source-isolated checks pass;
TPU execution and the full integration suite remain to be run.
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.

3 participants