Skip to content

feat(wan): token-sharded patch embedding (wan_patch_embed_mode="tokens") - #510

Open
Perseus14 wants to merge 1 commit into
feat/wan-cross-attn-pallasfrom
feat/wan-token-patch-embed
Open

Perseus14 wants to merge 1 commit into
feat/wan-cross-attn-pallasfrom
feat/wan-token-patch-embed

Conversation

@Perseus14

@Perseus14 Perseus14 commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on feat/wan-cross-attn-pallas. Second of four pieces split out of #491. Adds wan_patch_embed_mode: "tokens" (default "conv"): the Conv3d patch embedding becomes a patchify + matmul on the token-sharded layout (embed_patches_as_tokens) — non-overlapping patches flattened in the kernel's (p_t, p_h, p_w, C) order, sharded by token, multiplied by the replicated kernel. Same result as collapse(conv(x), 1, -1) up to accumulation order, but produced directly in the layout the transformer blocks use, so XLA no longer emits the activation all-gather / collective-permute when collapsing (F, H, W) into the context-sharded token axis (12.8 ms per step on tpu7x, exposed). can_embed_patches_as_tokens guards that the conv is a plain stride-equals-kernel patchify; otherwise the nnx.Conv path is used unchanged (logging the fallback reason once). run_wan_fast_inference.sh sets tokens in every profile.

E2E latency (TPU v6e-8, Wan 2.2 T2V-A14B, 720p / 81 frames / 40 steps, CP=4, DP=2, warm AOT, DVFS unpinned): 130.6 s generate / 128.5 s denoise, 2.2 s warm AOT compile (cold AOT: 130.7 s generate / 128.5 s denoise, 30.3 s compile) — neutral on v6e-8's 1D Ulysses mesh (U=4) vs #509 (130.6 s / 128.4 s), while removing the 12.8 ms/step exposed reshard collective on tpu7x-8's 2D Ulysses+Ring mesh (U=2, R=2).

Tests: wan_patch_embed_test.py (7, new; tokens vs conv parity at function and WanModel level, guard, config-driven mode), wan_runtime_options_test.py (+enum validation).

Stack: #477 → #507 → #478 → #508 → #479 → #488 → #509 → #510 → #511 → #491

@github-actions

Copy link
Copy Markdown

@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 introduces a token-sharded patch embedding mode (wan_patch_embed_mode) for Wan models to optimize performance by avoiding activation collectives on TPU. It implements embed_patches_as_tokens and can_embed_patches_as_tokens in transformer_wan.py to perform patch embedding as a token-sharded matrix multiplication when the "tokens" mode is selected and eligible, falling back to standard convolution otherwise. The new mode is integrated into the configuration files, runtime options, and fast inference scripts, and is verified with new unit tests. There are no review comments to address, and I have no additional feedback to provide.

@Perseus14
Perseus14 added this pull request to stack #512 October 15, 2026 16:00
@Perseus14
Perseus14 force-pushed the feat/wan-token-patch-embed branch from 251437a to 64a7d8a Compare October 15, 2026 16:05
@Perseus14
Perseus14 force-pushed the feat/wan-token-patch-embed branch from 64a7d8a to 24bbfdf Compare October 15, 2026 17:53
Second of four pieces split out of the Wan fast-inference optimizations PR.
The switch defaults off ("conv") in the Wan YAMLs and in wan_runtime_options;
it is a plain config key plumbed to WanModel through
`attention_config_entries(config)` and resolved at build time
(`_wan_opt`) so it lives on the GraphDef.

- With "tokens", the Conv3d patch embedding becomes a patchify + matmul on
  the token-sharded layout (`embed_patches_as_tokens`): the non-overlapping
  patches (stride == kernel) are flattened in the kernel's
  `(p_t, p_h, p_w, C)` order, sharded by token and multiplied by the
  replicated `[p_t*p_h*p_w*C, D]` kernel. Same result as
  `collapse(conv(x), 1, -1)` up to accumulation order, but produced directly
  in the layout the transformer blocks use, so XLA no longer emits the
  activation all-gather / collective-permute when collapsing `(F, H, W)`
  into the context-sharded token axis (12.8 ms per step on tpu7x, exposed).
- `can_embed_patches_as_tokens` checks the conv really is a plain
  stride-equals-kernel 3D patchify (no groups, masks, dilation, and 'SAME'
  pads nothing); otherwise the nnx.Conv path is used unchanged (and a warn-once message logs the fallback reason when wan_patch_embed_mode="tokens" was requested).
- run_wan_fast_inference.sh: every profile sets WAN_PATCH_EMBED_MODE=tokens
  (overridable).

Tests
- wan_patch_embed_test.py (7): tokens vs conv parity (function level and
  through WanModel), the eligibility predicate, and the config-driven mode.
- wan_runtime_options_test.py (12): the new switch's YAML default and enum
  validation; `wan_patch_embed_mode` is excluded from the FlaxWanAttention
  attribute check since WanModel consumes it.
- CI: the two WanModel patch-embed parity tests skip in GitHub Actions.
- end_to_end/tpu/run_wan_stack_tests.sh: adds wan_patch_embed_test.py.
Verified (this head): TPU v6e-8 (jax 0.11.2), every file of
end_to_end/tpu/run_wan_stack_tests.sh at this head run directly with unittest:
329 tests, all OK, 1 skipped (cross_attention_pallas_test: off-TPU fallback only);
wan_patch_embed_test.py 7, wan_runtime_options_test.py 12.
@Perseus14
Perseus14 force-pushed the feat/wan-token-patch-embed branch from 24bbfdf to f26b420 Compare October 15, 2026 19:20
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.

1 participant