Skip to content

Commit 217ee1c

Browse files
Merge pull request #428 from AI-Hypercomputer:sagarchapara/ulysses-two-phase
PiperOrigin-RevId: 948503646
2 parents e0ba26c + a0cf7f2 commit 217ee1c

19 files changed

Lines changed: 389 additions & 25 deletions

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,31 @@ To generate images, run the following command:
619619

620620
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.
621621

622+
#### Chunked Ulysses Attention (Overlapping Communication and Compute)
623+
624+
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**.
625+
626+
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.
627+
628+
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"`).
629+
630+
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:
631+
632+
```bash
633+
python src/maxdiffusion/generate_wan.py \
634+
src/maxdiffusion/configs/base_wan_i2v_27b.yml \
635+
attention="ulysses" \
636+
ici_context_parallelism=4 \
637+
ulysses_attention_chunks=2 \
638+
...
639+
```
640+
641+
> [!IMPORTANT]
642+
> For communication-compute overlap to be effective on TPUs, you must enable the following XLA flags before running:
643+
> ```bash
644+
> export XLA_FLAGS="--xla_tpu_enable_async_all_to_all=true --xla_tpu_overlap_compute_collective_tc=true"
645+
> ```
646+
622647
### Caching Mechanisms
623648
624649
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.

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

src/maxdiffusion/configs/base_wan_14b.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ use_base2_exp: True
8888
use_experimental_scheduler: True
8989
# For attention=ulysses_ring, hidden Ulysses shard count; ring shards are context / this.
9090
ulysses_shards: -1
91+
# Splits Ulysses all-to-all into head-group chunks. The last chunk carries any remainder.
92+
# For communication-compute overlap to be effective, enable the following XLA flags:
93+
# --xla_tpu_enable_async_all_to_all=true
94+
# --xla_tpu_overlap_compute_collective_tc=true
95+
# (Refer to README.md for the full recommended XLA_FLAGS list)
96+
ulysses_attention_chunks: 1
9197
flash_min_seq_length: 4096
9298
dropout: 0.0
9399

src/maxdiffusion/configs/base_wan_1_3b.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ use_base2_exp: True
8585
use_experimental_scheduler: True
8686
# For attention=ulysses_ring, hidden Ulysses shard count; ring shards are context / this.
8787
ulysses_shards: -1
88+
# Splits Ulysses all-to-all into head-group chunks. The last chunk carries any remainder.
89+
# For communication-compute overlap to be effective, enable the following XLA flags:
90+
# --xla_tpu_enable_async_all_to_all=true
91+
# --xla_tpu_overlap_compute_collective_tc=true
92+
# (Refer to README.md for the full recommended XLA_FLAGS list)
93+
ulysses_attention_chunks: 1
8894
flash_min_seq_length: 0
8995

9096
# If mask_padding_tokens is True, we pass in segment ids to splash attention to avoid attending to padding tokens.

src/maxdiffusion/configs/base_wan_27b.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ use_base2_exp: True
9494
use_experimental_scheduler: True
9595
# For attention=ulysses_ring, hidden Ulysses shard count; ring shards are context / this.
9696
ulysses_shards: -1
97+
# Splits Ulysses all-to-all into head-group chunks. The last chunk carries any remainder.
98+
# For communication-compute overlap to be effective, enable the following XLA flags:
99+
# --xla_tpu_enable_async_all_to_all=true
100+
# --xla_tpu_overlap_compute_collective_tc=true
101+
# (Refer to README.md for the full recommended XLA_FLAGS list)
102+
ulysses_attention_chunks: 1
97103
flash_min_seq_length: 4096
98104
dropout: 0.0
99105

src/maxdiffusion/configs/base_wan_animate.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ use_base2_exp: True
8686
use_experimental_scheduler: True
8787
# For attention=ulysses_ring, hidden Ulysses shard count; ring shards are context / this.
8888
ulysses_shards: -1
89+
# Splits Ulysses all-to-all into head-group chunks. The last chunk carries any remainder.
90+
# For communication-compute overlap to be effective, enable the following XLA flags:
91+
# --xla_tpu_enable_async_all_to_all=true
92+
# --xla_tpu_overlap_compute_collective_tc=true
93+
# (Refer to README.md for the full recommended XLA_FLAGS list)
94+
ulysses_attention_chunks: 1
8995
flash_min_seq_length: 4096
9096
# If mask_padding_tokens is True, we pass in segment ids to splash attention to avoid attending to padding tokens.
9197
# Else we do not pass in segment ids and on vpu bound hardware like trillium this is faster.

src/maxdiffusion/configs/base_wan_i2v_14b.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ use_base2_exp: True
8888
use_experimental_scheduler: True
8989
# For attention=ulysses_ring, hidden Ulysses shard count; ring shards are context / this.
9090
ulysses_shards: -1
91+
# Splits Ulysses all-to-all into head-group chunks. The last chunk carries any remainder.
92+
# For communication-compute overlap to be effective, enable the following XLA flags:
93+
# --xla_tpu_enable_async_all_to_all=true
94+
# --xla_tpu_overlap_compute_collective_tc=true
95+
# (Refer to README.md for the full recommended XLA_FLAGS list)
96+
ulysses_attention_chunks: 1
9197
flash_min_seq_length: 4096
9298
dropout: 0.0
9399

src/maxdiffusion/configs/base_wan_i2v_27b.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ use_base2_exp: True
8888
use_experimental_scheduler: True
8989
# For attention=ulysses_ring, hidden Ulysses shard count; ring shards are context / this.
9090
ulysses_shards: -1
91+
# Splits Ulysses all-to-all into head-group chunks. The last chunk carries any remainder.
92+
# For communication-compute overlap to be effective, enable the following XLA flags:
93+
# --xla_tpu_enable_async_all_to_all=true
94+
# --xla_tpu_overlap_compute_collective_tc=true
95+
# (Refer to README.md for the full recommended XLA_FLAGS list)
96+
ulysses_attention_chunks: 1
9197
flash_min_seq_length: 4096
9298
dropout: 0.0
9399

src/maxdiffusion/generate_wan.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ def inference_generate_video(config, pipeline, filename_prefix=""):
178178
negative_prompt = [config.negative_prompt] * config.global_batch_size_to_train_on
179179

180180
max_logging.log(
181-
f"Num steps: {config.num_inference_steps}, height: {config.height}, width: {config.width}, frames: {config.num_frames}, video: {filename_prefix}"
181+
f"Num steps: {config.num_inference_steps}, height: {config.height}, width: {config.width},"
182+
f" frames: {config.num_frames}, video: {filename_prefix}"
182183
)
183184

184185
videos = call_pipeline(config, pipeline, prompt, negative_prompt)
@@ -314,7 +315,8 @@ def run(config, pipeline=None, filename_prefix="", commit_hash=None):
314315
negative_prompt = [config.negative_prompt] * config.global_batch_size_to_train_on
315316

316317
max_logging.log(
317-
f"Num steps: {config.num_inference_steps}, height: {config.height}, width: {config.width}, frames: {config.num_frames}"
318+
f"Num steps: {config.num_inference_steps}, height: {config.height}, width: {config.width},"
319+
f" frames: {config.num_frames}"
318320
)
319321
# Warmup with 2 denoising steps instead of a full run: step 0 runs the
320322
# high-noise transformer and step 1 crosses the boundary to the low-noise
@@ -331,7 +333,8 @@ def run(config, pipeline=None, filename_prefix="", commit_hash=None):
331333
videos = call_pipeline(config, pipeline, prompt, negative_prompt, num_inference_steps=warmup_steps)
332334
if isinstance(videos, tuple):
333335
videos, warmup_trace = videos
334-
max_logging.log("Warmup breakdown: " + ", ".join(f"{stage}={seconds:.1f}s" for stage, seconds in warmup_trace.items()))
336+
warmup_str = ", ".join(f"{stage}={seconds:.1f}s" for stage, seconds in warmup_trace.items())
337+
max_logging.log(f"Warmup breakdown: {warmup_str}")
335338

336339
# Serialize any newly-compiled shapes synchronously while still inside
337340
# warmup-accounted time; a background save would compete with the first

0 commit comments

Comments
 (0)