Skip to content

Commit 87c36b2

Browse files
committed
feat(wan): fast inference optimizations (fused cross-attention, token patch embed, shard-major A2A, lane padding)
All four switches default off ("xla" / "conv" / "flat" / "off") in the Wan YAMLs and in wan_runtime_options. They are plain config keys, plumbed to FlaxWanAttention / WanModel through `attention_config_entries(config)` (the #488 mechanism) and resolved once at module build; nothing is read from the environment at trace time. The unconditional pyconfig default for `wan_cross_attn_cpu_interpret` was removed (it is an attention_config entry, default False, used only by CPU tests). - Short-KV text cross-attention Pallas kernel (wan_cross_attn_kernel="pallas"): kernels/cross_attention_pallas.py keeps a head block's whole 512-token text KV resident in VMEM and computes an exact single-pass softmax per query tile (full-row max, exp2, one numerator/denominator, normalised after PV; no running max / online rescaling). It replaces only what would otherwise be the unmasked XLA dot-product fallback. FlaxWanAttention falls back to XLA (logging the reason once) when the inputs or sharding don't fit, and now also when the VMEM budget is not validated or too small: 64 MiB is requested only when every mesh TPU is v6e or tpu7x (otherwise Mosaic's default), and `estimate_vmem_bytes` (Q/out/K/V double buffers + one head's FP32 scores) is checked against it (~42 MiB at the Wan shard shape; MAX_KV_LEN KV does not fit and falls back rather than failing to compile). The estimate has only been checked against real compiles at Wan's KV length (512). The kernel itself raises a ValueError for an over-budget working set only when a budget resolves (an explicit vmem_limit_bytes, or the v6e/tpu7x default); under Mosaic's default it does no check of its own, and callers that can fall back use `vmem_unusable_reason`. The two fallback reasons (unusable inputs, VMEM) log under separate warn-once keys. - Token-sharded patch embedding (wan_patch_embed_mode="tokens"): the Conv3d patch embedding becomes a patchify + matmul on the token-sharded layout, avoiding the activation all-gather. - Shard-major Ulysses A2A (wan_ulysses_out_a2a="chunked" / "shard_major"): a single layout-preserving all_to_all over a reshaped (num_shards, chunk) leading axis (not chunked compute/comm overlap), so XLA no longer inserts relayout copies around the collective. With the custom splash kernel (and S_local % block_q == 0, D == 128, heads_per_tile == 1) the forward Q exchange also stays shard-major (4-D q) and the kernel writes the shard-major output directly (out_num_shards), on both the 1D Ulysses path (v6e) and the 2D Ulysses+Ring path (tpu7x). - Lane sequence padding (wan_seq_pad="lane"): pads video tokens at the tail to a per-shard multiple of 128 (75,600 -> 75,776 at 720p/CP=4) so Ulysses reshapes are copy-free; TokenPadding masks the pad keys in the custom ulysses / ulysses_ring_custom kernels, and fixed-m metadata now also excludes pad query rows from the Q-norm bound. Every configuration that disables it logs why, once per cause. Behaviour change: if padding is active, the paths that cannot mask it (flash and non-custom ulysses via _tpu_flash_attention, ulysses_ring, dot_product, cudnn_flash_te, head_local_svg) raise NotImplementedError via `_reject_active_token_padding` instead of silently attending to pads. - run_wan_fast_inference.sh: the v6e and v7 profiles set WAN_CROSS_ATTN_KERNEL=pallas, WAN_PATCH_EMBED_MODE=tokens, WAN_ULYSSES_OUT_A2A=chunked, WAN_SEQ_PAD=lane (all overridable); the generic profile sets tokens only. The fused RMSNorm+RoPE kernel from #488 stays on in the v6e and v7 profiles and off in the generic one. LIBTPU: v6e now disables --xla_tpu_enable_ici_ag_pipelining / --xla_tpu_enable_ag_backward_pipelining, v7 enables them and adds --xla_tpu_enable_offloading_copy_to_sparsecore=false and BQ=4736. These two flags moved out of COMMON_LIBTPU, so the generic (non-v6e/v7) profile no longer sets them at all. Performance, measured at the stack tip (Wan 2.2 T2V-A14B, 720p/81f/40 steps, warm AOT, DVFS unpinned unless noted; CP=4, DP=2, launcher defaults including the fused RoPE kernel): v6e-8: denoise 125.9s, generate 128.05s tpu7x-8: denoise 105.1s, generate 107.6s tpu7x-8, DVFS pinned (PIN_DVFS_P_STATE=true), fused RoPE kernel off: denoise 93.6s, generate 96.1s (pinned with it on was not measured) Per-feature deltas were not measured separately and are omitted. In isolation the cross-attention kernel is 0.51 ms vs 3.94 ms (v6e) and 0.49 ms vs 1.81 ms (tpu7x) per call for the XLA path inside the model. The launcher's reference-benchmark comment now carries these numbers. Tests: - cross_attention_pallas_test.py: golden parity (row/tile max, mxu/vpu sum, ragged tiles, k_prescaled, batch), guards, VMEM budget resolution / working-set estimate / fallback reasons, and FlaxWanAttention dispatch (CPU interpret integration, fallbacks, I2V text-vs-image split). The three tests that expect the kernel to be used skip on TPUs outside the validated kinds (there FlaxWanAttention falls back by design); that fallback is covered by test_falls_back_to_xla_on_unvalidated_tpu_kind. - wan_seq_pad_test.py: padding plan and per-cause disable logging, pad-key masking for ulysses custom (unaligned and aligned real_len, flat and shard-major out A2A, every fixed-m mode) and ulysses_ring_custom (k-centring on/off; and the tpu7x production path scaled down: U=2 x R=2, aligned real_len, chunked out A2A, asserting the shard-major layout was taken; needs >= 4 devices), fixed-m metadata ignoring pad query rows, and the NotImplementedError guards. - wan_patch_embed_test.py, ulysses_out_a2a_test.py: tokens vs conv parity and config-driven mode; flat vs chunked vs shard_major parity. - wan_runtime_options_test.py: the new switches' YAML defaults and enums. - CI: 29 tests skip in GitHub Actions: kernel parity and the Pallas-active dispatch / unaligned-KV fallback tests in cross_attention_pallas_test (19 of 39), the three kernel bit-exact tests in ulysses_out_a2a_test, the two WanModel patch-embed parity tests and the five masking / end-to-end tests in wan_seq_pad_test. Guards, VMEM budget logic, the remaining XLA fallback dispatch tests (including the unvalidated-TPU fallback), padding-plan logic and runtime options run in CI. - end_to_end/tpu/run_wan_stack_tests.sh: adds this PR's four test files. Verified (final tree): - TPU v6e-8 (jax 0.11.2, end_to_end/tpu/run_wan_stack_tests.sh): 350 passed, 1 skipped (off-TPU fallback only), 259 subtests passed. - TPU v6e-8 with GITHUB_ACTIONS=true (all 17 stack test files): 231 passed, 120 skipped, 202 subtests passed. - Emulated unvalidated TPU (device_kind="TPU v4", rope_accum_is_measured=False): 0 failures across all 17 stack test files.
1 parent e4a3859 commit 87c36b2

21 files changed

Lines changed: 3183 additions & 133 deletions

‎end_to_end/tpu/run_wan_fast_inference.sh‎

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
# against the XLA-path video, visually clean); on tpu7x the
6464
# output was bit-identical in that measurement.
6565
# USE_FUSED_ROPE_KERNEL=false restores the XLA producer.
66+
# WAN_CROSS_ATTN_KERNEL / WAN_PATCH_EMBED_MODE / WAN_ULYSSES_OUT_A2A / WAN_SEQ_PAD
67+
# override Wan fast-inference kernel/layout switches
6668
# DP / CP / PER_DEVICE_BATCH / SEED
6769
# override mesh parallelism, per-device batch, or RNG seed (default 12345)
6870
set -euo pipefail
@@ -132,8 +134,10 @@ if [ -z "${TPU_PROFILE:-}" ]; then
132134
fi
133135

134136
# Keep LIBTPU flags single-line (literal backslashes truncate libtpu flag parsing).
135-
COMMON_LIBTPU=${COMMON_LIBTPU:-"--xla_tpu_spmd_rng_bit_generator_unsafe=true --xla_tpu_enable_async_collective_fusion=true --xla_tpu_enable_async_collective_fusion_fuse_all_gather=false --xla_tpu_enable_async_collective_fusion_multiple_steps=true --xla_tpu_memory_bound_loop_optimizer_options=enabled:true --xla_tpu_enable_dot_strength_reduction=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_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_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"}
136-
V6E_LIBTPU=${V6E_LIBTPU:-"--xla_tpu_enable_async_collective_fusion=true --xla_tpu_enable_async_collective_fusion_fuse_all_gather=false"}
137+
# ici_ag_pipelining and ag_backward_pipelining are configured per-profile below
138+
# (disabled on v6e, enabled on v7).
139+
COMMON_LIBTPU=${COMMON_LIBTPU:-"--xla_tpu_spmd_rng_bit_generator_unsafe=true --xla_tpu_enable_async_collective_fusion=true --xla_tpu_enable_async_collective_fusion_fuse_all_gather=false --xla_tpu_enable_async_collective_fusion_multiple_steps=true --xla_tpu_memory_bound_loop_optimizer_options=enabled:true --xla_tpu_enable_dot_strength_reduction=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_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_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_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"}
140+
V6E_LIBTPU=${V6E_LIBTPU:-"--xla_tpu_enable_ici_ag_pipelining=false --xla_tpu_enable_ag_backward_pipelining=false"}
137141
# fuse_all_gather is false in every profile (see COMMON_LIBTPU); it must stay
138142
# false on v7, where libtpu fails backend init with it enabled ("Continuation
139143
# fusion for AllGather ... not supported ... other than Viperlite").
@@ -144,13 +148,14 @@ V7_DVFS_FLAG=""
144148
if [ "$PIN_DVFS_P_STATE" = "true" ]; then
145149
V7_DVFS_FLAG=" --xla_tpu_dvfs_p_state=7"
146150
fi
147-
V7_LIBTPU=${V7_LIBTPU:-"--xla_tpu_enable_async_collective_fusion=true --xla_tpu_enable_async_collective_fusion_fuse_all_gather=false --xla_tpu_enable_megacore_fusion=true --xla_tpu_megacore_fusion_allow_ags=true${V7_DVFS_FLAG}"}
151+
V7_LIBTPU=${V7_LIBTPU:-"--xla_tpu_enable_ici_ag_pipelining=true --xla_tpu_enable_ag_backward_pipelining=true --xla_tpu_enable_megacore_fusion=true --xla_tpu_megacore_fusion_allow_ags=true --xla_tpu_enable_offloading_copy_to_sparsecore=false${V7_DVFS_FLAG}"}
148152

149-
# Reference benchmarks (Wan 2.2 T2V-A14B, 720p/81f/40-step, CP=4, DP=2, warm AOT
150-
# cache, these launcher defaults, measured at this PR without the later PRs):
151-
# tpu7x-8: 115.5s generate (denoise 112.8s) DVFS unpinned;
152-
# 102.0s generate (denoise 99.4s) with PIN_DVFS_P_STATE=true
153-
# v6e-8: not re-measured at this PR
153+
# Reference benchmarks (Wan 2.2 T2V-A14B, 720p/81f/40-step, CP=4, DP=2, full 5-PR
154+
# stack, these launcher defaults, warm AOT cache, DVFS unpinned):
155+
# v6e-8: 128.05s generate (denoise 125.9s)
156+
# tpu7x-8: 107.6s generate (denoise 105.1s)
157+
# tpu7x-8 with PIN_DVFS_P_STATE=true: 96.1s generate (denoise 93.6s), measured
158+
# with the fused RoPE kernel off (pinned with it on was not measured).
154159
case "$TPU_PROFILE" in
155160
v6e)
156161
PLATFORM_LIBTPU="$V6E_LIBTPU"
@@ -167,12 +172,16 @@ case "$TPU_PROFILE" in
167172
DEFAULT_VAE_CHUNK=1
168173
DEFAULT_VAE_SPATIAL=8
169174
DEFAULT_FUSED_ROPE=true
175+
DEFAULT_CROSS_ATTN_KERNEL=pallas
176+
DEFAULT_PATCH_EMBED_MODE=tokens
177+
DEFAULT_ULYSSES_OUT_A2A=chunked
178+
DEFAULT_SEQ_PAD=lane
170179
;;
171180
v7)
172181
PLATFORM_LIBTPU="$V7_LIBTPU"
173182
DEFAULT_ATTENTION="ulysses_ring_custom_fixed_m"
174183
DEFAULT_U=2
175-
DEFAULT_BQ=6400
184+
DEFAULT_BQ=4736
176185
DEFAULT_BKV=2048
177186
DEFAULT_BKV_COMPUTE=2048
178187
DEFAULT_BKV_COMPUTE_IN=2048
@@ -183,6 +192,10 @@ case "$TPU_PROFILE" in
183192
DEFAULT_VAE_CHUNK=1
184193
DEFAULT_VAE_SPATIAL=8
185194
DEFAULT_FUSED_ROPE=true
195+
DEFAULT_CROSS_ATTN_KERNEL=pallas
196+
DEFAULT_PATCH_EMBED_MODE=tokens
197+
DEFAULT_ULYSSES_OUT_A2A=chunked
198+
DEFAULT_SEQ_PAD=lane
186199
;;
187200
*)
188201
echo "== warning: unrecognised or non-v6e/v7 accelerator '${ACCEL_TYPE:-unknown}';" \
@@ -201,6 +214,10 @@ case "$TPU_PROFILE" in
201214
DEFAULT_VAE_CHUNK=1
202215
DEFAULT_VAE_SPATIAL=8
203216
DEFAULT_FUSED_ROPE=false
217+
DEFAULT_CROSS_ATTN_KERNEL=xla
218+
DEFAULT_PATCH_EMBED_MODE=tokens
219+
DEFAULT_ULYSSES_OUT_A2A=flat
220+
DEFAULT_SEQ_PAD=off
204221
;;
205222
esac
206223

@@ -232,6 +249,10 @@ USE_FUSED_ROPE_KERNEL=${USE_FUSED_ROPE_KERNEL:-$DEFAULT_FUSED_ROPE}
232249
FUSED_ROPE_ARGS=()
233250
[ -n "${FUSED_ROPE_BLOCK_S:-}" ] && FUSED_ROPE_ARGS+=("fused_rope_block_s=$FUSED_ROPE_BLOCK_S")
234251
[ -n "${FUSED_ROPE_HEAD_BLOCK:-}" ] && FUSED_ROPE_ARGS+=("fused_rope_head_block=$FUSED_ROPE_HEAD_BLOCK")
252+
WAN_CROSS_ATTN_KERNEL=${WAN_CROSS_ATTN_KERNEL:-$DEFAULT_CROSS_ATTN_KERNEL}
253+
WAN_PATCH_EMBED_MODE=${WAN_PATCH_EMBED_MODE:-$DEFAULT_PATCH_EMBED_MODE}
254+
WAN_ULYSSES_OUT_A2A=${WAN_ULYSSES_OUT_A2A:-$DEFAULT_ULYSSES_OUT_A2A}
255+
WAN_SEQ_PAD=${WAN_SEQ_PAD:-$DEFAULT_SEQ_PAD}
235256

236257
# Mesh: context parallelism carries the Ulysses shards, data parallelism takes
237258
# whatever chips remain. Defaults to CP=4 / DP=2 on an 8-chip slice. On a slice
@@ -294,6 +315,10 @@ python src/maxdiffusion/generate_wan.py "$CONFIG" \
294315
use_kv_cache=true use_base2_exp=true use_experimental_scheduler=true \
295316
use_fused_rope_kernel="$USE_FUSED_ROPE_KERNEL" \
296317
${FUSED_ROPE_ARGS[@]+"${FUSED_ROPE_ARGS[@]}"} \
318+
wan_cross_attn_kernel="$WAN_CROSS_ATTN_KERNEL" \
319+
wan_patch_embed_mode="$WAN_PATCH_EMBED_MODE" \
320+
wan_ulysses_out_a2a="$WAN_ULYSSES_OUT_A2A" \
321+
wan_seq_pad="$WAN_SEQ_PAD" \
297322
fps=16 ${GUIDANCE_ARGS[@]+"${GUIDANCE_ARGS[@]}"} \
298323
seed="${SEED:-12345}" \
299324
flash_block_sizes="$FLASH_BLOCK_SIZES" \

‎end_to_end/tpu/run_wan_stack_tests.sh‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,11 @@ TESTS=(
4242
# Fused RMSNorm+RoPE producer, Wan switches in config (feat/wan-custom-kernels)
4343
"$T/fused_rmsnorm_rope_pallas_test.py"
4444
"$T/wan_runtime_options_test.py"
45+
# Cross-attention kernel, token patch embed, shard-major A2A, lane padding
46+
# (feat/wan-fast-inference-optimizations)
47+
"$T/cross_attention_pallas_test.py"
48+
"$T/ulysses_out_a2a_test.py"
49+
"$T/wan_patch_embed_test.py"
50+
"$T/wan_seq_pad_test.py"
4551
)
4652
PYTHONPATH="src${PYTHONPATH:+:$PYTHONPATH}" exec "${PYTHON:-python3}" -m pytest -q -rs "${TESTS[@]}" "$@"

‎src/maxdiffusion/__init__.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
__version__ = "0.22.0.dev0"
1818

19+
1920
from typing import TYPE_CHECKING
2021

2122
from .utils import (

‎src/maxdiffusion/configs/base_wan_14b.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,27 @@ wan_cfg_before_unpatchify: True
133133
wan_cross_attn_prescale_kv: False
134134
# Fused RoPE accumulation: "auto" (measured per-platform default), "dtype", "f32".
135135
wan_rope_accum: "auto"
136+
# Text cross-attention backend where it would otherwise fall back to XLA dot-product
137+
# (KV shorter than flash_min_seq_length): "xla", or "pallas" for the fused kernel that
138+
# keeps the KV in VMEM (within bf16 rounding of "xla", not bit-identical).
139+
wan_cross_attn_kernel: "xla"
140+
# When wan_cross_attn_kernel is "pallas", allow CPU execution via Pallas interpret mode (tests only).
141+
wan_cross_attn_cpu_interpret: False
142+
# Patch embedding: "conv" (nnx.Conv; its channel-sharded output is resharded by
143+
# token, an all-gather on tpu7x) or "tokens" (token-sharded patches times the
144+
# replicated kernel, no activation collective; equal up to accumulation order).
145+
wan_patch_embed_mode: "conv"
146+
# Inverse Ulysses all-to-all (attention output, head-sharded -> sequence-sharded):
147+
# "flat" splits the sequence axis directly; "chunked" exchanges over an explicit
148+
# leading sequence-chunk axis so XLA does not relayout the output around the
149+
# collective (used by the custom Ulysses / Ulysses-ring kernels only).
150+
wan_ulysses_out_a2a: "flat"
151+
# Self-attention token padding: "off", or "lane" to append pad tokens at the end
152+
# of the video token sequence (or at the end of each ring segment on the ring
153+
# path) so every context shard has a multiple of 128 tokens. Aligned shards make
154+
# the Ulysses all-to-all reshapes free; the custom kernels mask the pad keys.
155+
# Only the custom Ulysses / Ulysses-ring kernels use it.
156+
wan_seq_pad: "off"
136157
# For attention=ulysses_ring, hidden Ulysses shard count; ring shards are context / this.
137158
ulysses_shards: -1
138159
# Splits Ulysses all-to-all into head-group chunks. The last chunk carries any remainder.

‎src/maxdiffusion/configs/base_wan_1_3b.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,27 @@ wan_cfg_before_unpatchify: True
130130
wan_cross_attn_prescale_kv: False
131131
# Fused RoPE accumulation: "auto" (measured per-platform default), "dtype", "f32".
132132
wan_rope_accum: "auto"
133+
# Text cross-attention backend where it would otherwise fall back to XLA dot-product
134+
# (KV shorter than flash_min_seq_length): "xla", or "pallas" for the fused kernel that
135+
# keeps the KV in VMEM (within bf16 rounding of "xla", not bit-identical).
136+
wan_cross_attn_kernel: "xla"
137+
# When wan_cross_attn_kernel is "pallas", allow CPU execution via Pallas interpret mode (tests only).
138+
wan_cross_attn_cpu_interpret: False
139+
# Patch embedding: "conv" (nnx.Conv; its channel-sharded output is resharded by
140+
# token, an all-gather on tpu7x) or "tokens" (token-sharded patches times the
141+
# replicated kernel, no activation collective; equal up to accumulation order).
142+
wan_patch_embed_mode: "conv"
143+
# Inverse Ulysses all-to-all (attention output, head-sharded -> sequence-sharded):
144+
# "flat" splits the sequence axis directly; "chunked" exchanges over an explicit
145+
# leading sequence-chunk axis so XLA does not relayout the output around the
146+
# collective (used by the custom Ulysses / Ulysses-ring kernels only).
147+
wan_ulysses_out_a2a: "flat"
148+
# Self-attention token padding: "off", or "lane" to append pad tokens at the end
149+
# of the video token sequence (or at the end of each ring segment on the ring
150+
# path) so every context shard has a multiple of 128 tokens. Aligned shards make
151+
# the Ulysses all-to-all reshapes free; the custom kernels mask the pad keys.
152+
# Only the custom Ulysses / Ulysses-ring kernels use it.
153+
wan_seq_pad: "off"
133154
# For attention=ulysses_ring, hidden Ulysses shard count; ring shards are context / this.
134155
ulysses_shards: -1
135156
# Splits Ulysses all-to-all into head-group chunks. The last chunk carries any remainder.

‎src/maxdiffusion/configs/base_wan_27b.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,27 @@ wan_cfg_before_unpatchify: True
162162
wan_cross_attn_prescale_kv: False
163163
# Fused RoPE accumulation: "auto" (measured per-platform default), "dtype", "f32".
164164
wan_rope_accum: "auto"
165+
# Text cross-attention backend where it would otherwise fall back to XLA dot-product
166+
# (KV shorter than flash_min_seq_length): "xla", or "pallas" for the fused kernel that
167+
# keeps the KV in VMEM (within bf16 rounding of "xla", not bit-identical).
168+
wan_cross_attn_kernel: "xla"
169+
# When wan_cross_attn_kernel is "pallas", allow CPU execution via Pallas interpret mode (tests only).
170+
wan_cross_attn_cpu_interpret: False
171+
# Patch embedding: "conv" (nnx.Conv; its channel-sharded output is resharded by
172+
# token, an all-gather on tpu7x) or "tokens" (token-sharded patches times the
173+
# replicated kernel, no activation collective; equal up to accumulation order).
174+
wan_patch_embed_mode: "conv"
175+
# Inverse Ulysses all-to-all (attention output, head-sharded -> sequence-sharded):
176+
# "flat" splits the sequence axis directly; "chunked" exchanges over an explicit
177+
# leading sequence-chunk axis so XLA does not relayout the output around the
178+
# collective (used by the custom Ulysses / Ulysses-ring kernels only).
179+
wan_ulysses_out_a2a: "flat"
180+
# Self-attention token padding: "off", or "lane" to append pad tokens at the end
181+
# of the video token sequence (or at the end of each ring segment on the ring
182+
# path) so every context shard has a multiple of 128 tokens. Aligned shards make
183+
# the Ulysses all-to-all reshapes free; the custom kernels mask the pad keys.
184+
# Only the custom Ulysses / Ulysses-ring kernels use it.
185+
wan_seq_pad: "off"
165186
# For attention=ulysses_ring*, hidden Ulysses shard count; ring shards are context / this.
166187
ulysses_shards: -1
167188
# Splits Ulysses all-to-all into head-group chunks. The last chunk carries any remainder.

‎src/maxdiffusion/configs/base_wan_animate.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,27 @@ wan_cfg_before_unpatchify: True
112112
wan_cross_attn_prescale_kv: False
113113
# Fused RoPE accumulation: "auto" (measured per-platform default), "dtype", "f32".
114114
wan_rope_accum: "auto"
115+
# Text cross-attention backend where it would otherwise fall back to XLA dot-product
116+
# (KV shorter than flash_min_seq_length): "xla", or "pallas" for the fused kernel that
117+
# keeps the KV in VMEM (within bf16 rounding of "xla", not bit-identical).
118+
wan_cross_attn_kernel: "xla"
119+
# When wan_cross_attn_kernel is "pallas", allow CPU execution via Pallas interpret mode (tests only).
120+
wan_cross_attn_cpu_interpret: False
121+
# Patch embedding: "conv" (nnx.Conv; its channel-sharded output is resharded by
122+
# token, an all-gather on tpu7x) or "tokens" (token-sharded patches times the
123+
# replicated kernel, no activation collective; equal up to accumulation order).
124+
wan_patch_embed_mode: "conv"
125+
# Inverse Ulysses all-to-all (attention output, head-sharded -> sequence-sharded):
126+
# "flat" splits the sequence axis directly; "chunked" exchanges over an explicit
127+
# leading sequence-chunk axis so XLA does not relayout the output around the
128+
# collective (used by the custom Ulysses / Ulysses-ring kernels only).
129+
wan_ulysses_out_a2a: "flat"
130+
# Self-attention token padding: "off", or "lane" to append pad tokens at the end
131+
# of the video token sequence (or at the end of each ring segment on the ring
132+
# path) so every context shard has a multiple of 128 tokens. Aligned shards make
133+
# the Ulysses all-to-all reshapes free; the custom kernels mask the pad keys.
134+
# Only the custom Ulysses / Ulysses-ring kernels use it.
135+
wan_seq_pad: "off"
115136
# For attention=ulysses_ring, hidden Ulysses shard count; ring shards are context / this.
116137
ulysses_shards: -1
117138
# Splits Ulysses all-to-all into head-group chunks. The last chunk carries any remainder.

‎src/maxdiffusion/configs/base_wan_i2v_14b.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,27 @@ wan_cfg_before_unpatchify: True
114114
wan_cross_attn_prescale_kv: False
115115
# Fused RoPE accumulation: "auto" (measured per-platform default), "dtype", "f32".
116116
wan_rope_accum: "auto"
117+
# Text cross-attention backend where it would otherwise fall back to XLA dot-product
118+
# (KV shorter than flash_min_seq_length): "xla", or "pallas" for the fused kernel that
119+
# keeps the KV in VMEM (within bf16 rounding of "xla", not bit-identical).
120+
wan_cross_attn_kernel: "xla"
121+
# When wan_cross_attn_kernel is "pallas", allow CPU execution via Pallas interpret mode (tests only).
122+
wan_cross_attn_cpu_interpret: False
123+
# Patch embedding: "conv" (nnx.Conv; its channel-sharded output is resharded by
124+
# token, an all-gather on tpu7x) or "tokens" (token-sharded patches times the
125+
# replicated kernel, no activation collective; equal up to accumulation order).
126+
wan_patch_embed_mode: "conv"
127+
# Inverse Ulysses all-to-all (attention output, head-sharded -> sequence-sharded):
128+
# "flat" splits the sequence axis directly; "chunked" exchanges over an explicit
129+
# leading sequence-chunk axis so XLA does not relayout the output around the
130+
# collective (used by the custom Ulysses / Ulysses-ring kernels only).
131+
wan_ulysses_out_a2a: "flat"
132+
# Self-attention token padding: "off", or "lane" to append pad tokens at the end
133+
# of the video token sequence (or at the end of each ring segment on the ring
134+
# path) so every context shard has a multiple of 128 tokens. Aligned shards make
135+
# the Ulysses all-to-all reshapes free; the custom kernels mask the pad keys.
136+
# Only the custom Ulysses / Ulysses-ring kernels use it.
137+
wan_seq_pad: "off"
117138
# For attention=ulysses_ring, hidden Ulysses shard count; ring shards are context / this.
118139
ulysses_shards: -1
119140
# Splits Ulysses all-to-all into head-group chunks. The last chunk carries any remainder.

0 commit comments

Comments
 (0)