Skip to content

Commit 2d499c7

Browse files
committed
Merge origin/main
2 parents 000a77d + ed9ac9d commit 2d499c7

47 files changed

Lines changed: 7362 additions & 467 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
[![Unit Tests](https://github.com/AI-Hypercomputer/maxdiffusion/actions/workflows/UnitTests.yml/badge.svg)](https://github.com/AI-Hypercomputer/maxdiffusion/actions/workflows/UnitTests.yml)
1818

1919
# What's new?
20+
- **`2026/07/14`**: Automatic attention tile-size (`block_q`/`block_kv`) search for Wan is now supported.
21+
- **`2026/06/26`**: 2D ring (USP) attention with a custom splash kernel is now supported for Wan (`ulysses_ring_custom`), splitting context parallelism into an intra-chip Ulysses axis and a cross-chip ring axis.
2022
- **`2026/04/16`**: Support for Tokamax Ring Attention kernel is now added.
2123
- **`2026/03/31`**: Wan2.2 SenCache inference is now supported for T2V and I2V (up to 1.4x speedup)
2224
- **`2026/03/25`**: Wan2.1 and Wan2.2 Magcache inference is now supported
@@ -619,6 +621,31 @@ To generate images, run the following command:
619621

620622
In our Wan2.2 I2V benchmarks at 40 inference steps, 81 frames, and `720x1280` resolution, Ulysses improved inference time by roughly `~10%` compared with flash attention, with about `~20s` lower latency on the v6e-8 and v7x-8 TPU setup.
621623

624+
#### Chunked Ulysses Attention (Overlapping Communication and Compute)
625+
626+
If you observe a major `all-to-all` communication bottleneck (especially when communication overhead is more pronounced compared to attention computation), you can enable **Chunked Ulysses Attention**.
627+
628+
By setting `ulysses_attention_chunks` greater than 1, MaxDiffusion splits the Ulysses all-to-all communication and attention computation into head-group passes (chunks). This allows XLA to overlap the all-to-all communication of one chunk with the head-parallel local attention compute of another chunk, significantly mitigating the communication bottleneck.
629+
630+
This chunking technique is supported and works for both plain Ulysses attention (`attention="ulysses"`) and hybrid Ulysses+Ring 2D attention/context parallelism (`attention="ulysses_ring"`).
631+
632+
To enable chunked Ulysses attention, set the corresponding override (e.g. `ulysses_attention_chunks=2` or `ulysses_attention_chunks=5`) in your config YAML or command line:
633+
634+
```bash
635+
python src/maxdiffusion/generate_wan.py \
636+
src/maxdiffusion/configs/base_wan_i2v_27b.yml \
637+
attention="ulysses" \
638+
ici_context_parallelism=4 \
639+
ulysses_attention_chunks=2 \
640+
...
641+
```
642+
643+
> [!IMPORTANT]
644+
> For communication-compute overlap to be effective on TPUs, you must enable the following XLA flags before running:
645+
> ```bash
646+
> export XLA_FLAGS="--xla_tpu_enable_async_all_to_all=true --xla_tpu_overlap_compute_collective_tc=true"
647+
> ```
648+
622649
### Caching Mechanisms
623650
624651
Wan 2.x pipelines support several caching strategies to accelerate inference by skipping redundant transformer forward passes. These are **mutually exclusive**enable only one at a time.
@@ -690,6 +717,10 @@ We added ring attention support for Wan models. Below are the stats for one `720
690717

691718
(* There are some known stability issues for ring attention on 16 TPUs, please use `tokamax_flash` attention instead.)
692719

720+
### Automatic Tile-Size Search
721+
722+
The optimal attention tile sizes (`block_q` / `block_kv`) depend on the sequence length, VMEM, sharding, and accelerator, and the feasibility edge is a VMEM OOM with no clean closed form — so we tune them empirically. Passing `enable_tile_search=true` to `generate_wan.py` runs a fast one-DiT-block grid search before inference and injects the winning block sizes into `flash_block_sizes` (`tile_search_mode=smart` by default; the search is opt-in and off by default). The core is model-agnostic (`utils/tile_size_grid_search.py`) with a per-model plug (`utils/wan_block_benchmark.py`), which also runs standalone via `python -m maxdiffusion.utils.wan_block_benchmark ... --smart-search`.
723+
693724
## Flux
694725

695726
First make sure you have permissions to access the Flux repos in Huggingface.
@@ -723,6 +754,22 @@ We added ring attention support for Wan models. Below are the stats for one `720
723754
```bash
724755
python src/maxdiffusion/generate_flux.py src/maxdiffusion/configs/base_flux_schnell.yml jax_cache_dir=/tmp/cache_dir run_name=flux_test output_dir=/tmp/ prompt="photograph of an electronics chip in the shape of a race car with trillium written on its side" per_device_batch_size=1 ici_data_parallelism=1 ici_fsdp_parallelism=-1 offload_encoders=False
725756
```
757+
758+
### Flux.2-Klein (4B & 9B)
759+
760+
Flux.2-Klein provides ultra-fast 4-step image generation using Qwen3 text embeddings and FLUX.2 transformer blocks.
761+
762+
Flux.2-Klein 4B:
763+
764+
```bash
765+
python src/maxdiffusion/generate_flux2klein.py src/maxdiffusion/configs/base_flux2klein.yml run_name=flux2klein_4b prompt="A detailed vector illustration of a robotic hummingbird"
766+
```
767+
768+
Flux.2-Klein 9B:
769+
770+
```bash
771+
python src/maxdiffusion/generate_flux2klein.py src/maxdiffusion/configs/base_flux2klein_9B.yml run_name=flux2klein_9b prompt="A detailed vector illustration of a robotic hummingbird"
772+
```
726773
## Fused Attention for GPU:
727774
Fused Attention for GPU is supported via TransformerEngine. Installation instructions:
728775

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/bin/bash
2+
# Copyright 2026 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# WAN T2V fast-serving example: AOT executable cache + converted-weights
17+
# cache + zero-exec warmup, with a tuned v7 2D-ring attention recipe.
18+
#
19+
# First run per (model, shape) pays one-time conversion + compile and
20+
# populates the caches; every later process start is ~25s to ready.
21+
#
22+
# Usage:
23+
# ./run_wan_fast_inference.sh [21|22] [steps] ["prompt..."]
24+
# Env overrides:
25+
# WAN_CACHE_ROOT cache root (default ~/.cache/maxdiffusion_wan)
26+
# OUTPUT_DIR video/metrics output (default /tmp/wan_out)
27+
# COMPILE_TE=true torch.compile the text encoder (adds ~30s to load,
28+
# saves ~10s/encode; worth it for long-lived processes)
29+
set -u
30+
MODEL=${1:-22}
31+
STEPS=${2:-40}
32+
PROMPT=${3:-""}
33+
34+
PROJECT_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." &> /dev/null && pwd)"
35+
cd "$PROJECT_ROOT" || exit 1
36+
export PYTHONPATH="$PROJECT_ROOT/src:${PYTHONPATH:-}"
37+
export HF_HUB_ENABLE_HF_TRANSFER=1
38+
export JAX_DEFAULT_MATMUL_PRECISION=bfloat16
39+
export TORCHINDUCTOR_FX_GRAPH_CACHE=1
40+
41+
CACHE_ROOT=${WAN_CACHE_ROOT:-$HOME/.cache/maxdiffusion_wan}
42+
OUTPUT_DIR=${OUTPUT_DIR:-/tmp/wan_out}
43+
mkdir -p "$CACHE_ROOT/jax" "$CACHE_ROOT/aot_wan$MODEL" "$CACHE_ROOT/converted" "$OUTPUT_DIR"
44+
45+
# Tuned collective/scheduler flag set for v7 (from the PR #430 2D-ring
46+
# baseline). One line: libtpu stops parsing at a literal backslash.
47+
export LIBTPU_INIT_ARGS="--xla_tpu_spmd_rng_bit_generator_unsafe=true --xla_tpu_enable_dot_strength_reduction=true --xla_tpu_enable_async_collective_fusion_fuse_all_gather=true --xla_enable_async_collective_permute=true --xla_tpu_enable_data_parallel_all_reduce_opt=true --xla_tpu_data_parallel_opt_different_sized_ops=true --xla_tpu_enable_async_collective_fusion=true --xla_tpu_enable_async_collective_fusion_multiple_steps=true --xla_tpu_overlap_compute_collective_tc=true --xla_enable_async_all_gather=true --xla_tpu_scoped_vmem_limit_kib=65536 --xla_tpu_enable_async_all_to_all=true --xla_tpu_enable_all_experimental_scheduler_features=true --xla_tpu_enable_scheduler_memory_pressure_tracking=true --xla_tpu_host_transfer_overlap_limit=24 --xla_tpu_aggressive_opt_barrier_removal=ENABLED --xla_lhs_prioritize_async_depth_over_stall=ENABLED --xla_should_allow_loop_variant_parameter_in_chain=ENABLED --xla_should_add_loop_invariant_op_in_chain=ENABLED --xla_tpu_enable_ici_ag_pipelining=true --xla_max_concurrent_host_send_recv=100 --xla_tpu_scheduler_percent_shared_memory_limit=100 --xla_latency_hiding_scheduler_rerun=2 --xla_tpu_use_minor_sharding_for_major_trivial_input=true --xla_tpu_relayout_group_size_threshold_for_reduce_scatter=1 --xla_tpu_enable_latency_hiding_scheduler=true --xla_tpu_enable_ag_backward_pipelining=true --xla_tpu_enable_megacore_fusion=true --xla_tpu_megacore_fusion_allow_ags=true --xla_tpu_use_single_sparse_core_for_all_gather_offload=true --xla_tpu_sparse_core_all_gather_latency_multiplier=1 --xla_tpu_sparse_core_reduce_scatter_latency_multiplier=3 --xla_tpu_enable_sparse_core_collective_aggregator=true --xla_tpu_enable_sparse_core_offload_queuing_in_lhs=true --xla_tpu_enable_sparse_core_reduce_scatter_v2=true --xla_tpu_enable_sparse_core_collective_offload_all_gather=true --xla_tpu_enable_sparse_core_collective_offload_2d_all_gather=true --xla_tpu_enable_sparse_core_collective_offload_all_reduce=true --xla_tpu_enable_sparse_core_collective_offload_reduce_scatter=true --xla_tpu_enable_sparse_core_collective_offload_3d_all_gather=true --xla_tpu_enable_concurrent_sparse_core_offloading=true --xla_tpu_assign_all_reduce_scatter_layout=true"
48+
49+
if [ "$MODEL" = "21" ]; then
50+
CONFIG=src/maxdiffusion/configs/base_wan_14b.yml
51+
GUIDANCE_ARGS=""
52+
else
53+
CONFIG=src/maxdiffusion/configs/base_wan_27b.yml
54+
GUIDANCE_ARGS="guidance_scale_low=3.0 guidance_scale_high=4.0"
55+
fi
56+
57+
PROMPT_ARG=()
58+
[ -n "$PROMPT" ] && PROMPT_ARG=("prompt=$PROMPT")
59+
RUN_NAME="wan${MODEL}_fast_$(date +%m%d-%H%M%S)"
60+
61+
# libtpu's XLA:CPU AOT feature-mismatch log is cosmetic and ignores every
62+
# log-level env var; filter just that message from stderr.
63+
python src/maxdiffusion/generate_wan.py "$CONFIG" \
64+
run_name="$RUN_NAME" \
65+
output_dir="$OUTPUT_DIR" \
66+
jax_cache_dir="$CACHE_ROOT/jax" \
67+
aot_cache_dir="$CACHE_ROOT/aot_wan$MODEL" \
68+
converted_weights_dir="$CACHE_ROOT/converted" \
69+
attention=ulysses_ring_custom \
70+
ulysses_shards=2 \
71+
ici_data_parallelism=2 ici_fsdp_parallelism=1 \
72+
ici_context_parallelism=4 ici_tensor_parallelism=1 \
73+
per_device_batch_size=0.125 \
74+
num_inference_steps="$STEPS" num_frames=81 width=1280 height=720 \
75+
weights_dtype=bfloat16 activations_dtype=bfloat16 \
76+
vae_spatial=4 vae_decode_chunk=-1 \
77+
vae_weights_dtype=bfloat16 vae_dtype=bfloat16 \
78+
text_encoder_dtype=bfloat16 compile_text_encoder="${COMPILE_TE:-false}" use_batched_text_encoder=false \
79+
use_base2_exp=true use_experimental_scheduler=true \
80+
fps=16 $GUIDANCE_ARGS \
81+
flash_block_sizes='{"block_q":9472,"block_kv":1024,"block_kv_compute":1024,"block_kv_compute_in":1024,"heads_per_tile":1,"vmem_limit_bytes":67108864,"block_q_dkv":9472,"block_kv_dkv":1024,"block_kv_dkv_compute":1024}' \
82+
"${PROMPT_ARG[@]}" \
83+
2> >(grep -vE --line-buffered 'cpu_aot_loader|machine type for execution' >&2)
84+
85+
mp4=$(ls -t wan_output_*.mp4 2>/dev/null | head -1)
86+
if [ -n "$mp4" ]; then
87+
mv "$mp4" "$OUTPUT_DIR/${RUN_NAME}.mp4"
88+
echo ""
89+
echo "=== video saved: $OUTPUT_DIR/${RUN_NAME}.mp4 ==="
90+
fi

pyproject.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,17 +92,19 @@ packages = ["src/maxdiffusion", "src/install_maxdiffusion_extra_deps"]
9292

9393
[tool.ruff]
9494
# Never enforce `E501` (line length violations).
95+
line-length = 119
96+
97+
[tool.ruff.lint]
9598
ignore = ["C901", "E501", "E741", "F402", "F823", "E402", "I001"]
9699
select = ["C", "E", "F", "I", "W"]
97-
line-length = 119
98100

99101
# Ignore import violations in all `__init__.py` files.
100-
[tool.ruff.per-file-ignores]
102+
[tool.ruff.lint.per-file-ignores]
101103
"__init__.py" = ["E402", "F401", "F403", "F811"]
102104
"src/maxdiffusion/utils/dummy_*.py" = ["F401"]
103105
"src/maxdiffusion/pyconfig.py" = ["E721"]
104106

105-
[tool.ruff.isort]
107+
[tool.ruff.lint.isort]
106108
lines-after-imports = 2
107109
known-first-party = ["maxdiffusion"]
108110

0 commit comments

Comments
 (0)