Skip to content

[perf] MiniMax H3: decode eight VAE spatial tiles per call by default - #2040

Open
aryan5v wants to merge 2 commits into
mainfrom
aryan/h3-vae-tile-batch-default
Open

aryan5v wants to merge 2 commits into
mainfrom
aryan/h3-vae-tile-batch-default

Conversation

@aryan5v

@aryan5v aryan5v commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • End to end (Pika H3 Flex, 768x1344, 1 GB200, bf16 VAE): VAE decode ~8.1 s -> ~4.0 s at 5 s clips, i.e. roughly 4 s (~16%) off a ~25 s generation; at 15 s clips decode drops ~30% (18.3 s -> 12.8 s in the decode-only bench).
  • Exact: decoded frames are bitwise identical to per-tile decoding at the production shape.
  • Cost: +0.7 GiB peak memory with FA2/FA4 attention; +1.3 GiB (107 frames) to +2.1 GiB (362 frames) with SDPA.

How this was found. These changes came out of an agent-driven kernel optimization run with MotionKernel, a tool we're developing that profiles a real generation, finds where the time goes, and only keeps changes that hold up end to end with the quality checks below.

Problem

FASTVIDEO_H3_VAE_TILE_BATCH already groups the spatial tiles of one temporal chunk into a
single decoder call, but it defaulted to 1, i.e. one small ViT forward per tile: a 768x1344
clip is an 18-tile grid over 7 temporal chunks, so the default issues 126 batch-1 decoder calls
per video. The H3 VAE decoder treats batch entries independently (no cross-tile interaction), and
32 heads x 64 dims is a much better shape for the GEMMs than 1 x 1797 tokens.

Fix

Change the default to 8 and document the interaction with the tile-split parallel decode. The env
override is unchanged (FASTVIDEO_H3_VAE_TILE_BATCH=1 restores per-tile decoding), and the
existing batched path (identical tile shapes only) is used automatically.

FASTVIDEO_H3_VAE_TILE_PARALLEL replays the per-tile serial forwards, so it now documents that
it requires FASTVIDEO_H3_VAE_TILE_BATCH=1; its tests set that explicitly.

Evidence

Decode-only, one loaded VAE, warm, interleaved arms, GB200 (768x1344, fp16 autocast, real latents
encoded by the shipped H3 VAE from assets/videos/robot_pouring.mp4):

frames (latent) arm decode s (runs) median peak alloc
107 (32) tile batch 1 5.419 / 5.380 / 5.435 5.419 15.43 GiB
107 (32) tile batch 8 3.658 / 3.685 / 3.649 3.658 16.13 GiB
107 (32) default (env unset) 3.670 / 3.664 / 3.649 3.664 16.13 GiB
362 (107) tile batch 1 18.203 / 18.294 18.294 15.46 GiB
362 (107) tile batch 8 12.765 / 12.763 12.765 16.16 GiB
  • 107 frames: -32.5% decode, 362 frames: -30.1% decode.
  • Peak memory: +0.70 GiB (the batched tile activations), unchanged reserved pool. With SDPA attention the first-run delta is larger: +1.31 GiB at 107 frames, +2.09 GiB at 362.
  • Bitwise: the uint8 frames are identical between the arms at both shapes (sha1
    0ddbf20b... / ad9a1b09...), and a separate fp32 comparison at the production shape finds
    torch.equal(tb1, tb8) == True with max_abs = 0.0.

Caveat: at other geometries a batched launch can select different attention/GEMM kernels, so the
bitwise property is a measured property of the production shape, not a theorem (the CPU unit test
uses a 1e-6 tolerance for that reason).

Tests

python -m pytest fastvideo/tests/stages/test_minimax_h3_vae_streaming.py \
    fastvideo/tests/vaes/test_minimax_h3_video_vae_streaming.py \
    fastvideo/tests/vaes/test_minimax_h3_parallel_vae.py -q
# 97 passed on GB200 after the review fixes (new: test_tile_batch_defaults_to_eight, test_batched_tile_decode_matches_per_tile;
# the two per-tile-driver tests pin FASTVIDEO_H3_VAE_TILE_BATCH=1)

yapf -d / ruff check / codespell clean on the changed files (models/ and tests/ are
pre-commit-excluded, formatted to match neighbors).


Verification on current main (d9e6c3e): the patch applies cleanly; pre-commit (yapf, ruff, codespell, PyMarkdown, mypy) passes on all changed files; the tests listed above were run on GB200.

Independent GB200 verification (after the review fixes)

An agent rechecked this PR on a separate GB200 with SDPA attention:

  • Decode: 6.25 → 3.73 s at 107 frames (−40%) and 18.35 → 13.02 s at 362 frames (−29%), 3 warm interleaved runs each.
  • Exactness: uint8 frames bitwise identical at both shapes.
  • End to end: base MiniMax-H3, 768x1344x124, 6 forwards: wall 36.51 → 33.91 s (−2.6 s). It's a smaller share there because that generation is longer.
  • Review fix: NVFP4 decoders with dynamic activation scales now always decode one tile per call.

@mergify

mergify Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Merge Protections

🔴 1 of 1 protections blocking · waiting on 👀 reviews and 🤖 CI

Protection Waiting on
🔴 PR merge requirements 👀 reviews and 🤖 CI

🔴 PR merge requirements

Waiting for

  • #approved-reviews-by>=1
  • check-success=fastcheck-passed
  • check-success=full-suite-passed
This rule is failing.
  • #approved-reviews-by>=1
  • check-success=fastcheck-passed
  • check-success=full-suite-passed
  • check-success~=pre-commit
  • title~=(?i)^\[(feat|feature|bugfix|fix|refactor|perf|ci|doc|docs|misc|chore|kernel|new.?model|skill|skills|infra)\]

@mergify mergify Bot added type: perf Performance improvement scope: infra CI, tests, Docker, build scope: model Model architecture (DiTs, encoders, VAEs) labels Oct 30, 2026
@greptile-apps

greptile-apps Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The change affects MiniMax-H3 VAE decoding workflows.

The remaining comment-rule violation must be addressed before merging; no new correctness issue was found.

Findings

  1. P2 Comments violate repository rule ▶
Fix with agent prompt
### Issue 1
fastvideo/tests/vaes/test_minimax_h3_video_vae_streaming.py:undefined-188
This new docstring repeats the test name and assertion. The repository requires removing code comments outside its explicit keep-list; test narration and private helper docs do not qualify. Remove this docstring and the same narration in `test_batched_tile_decode_matches_per_tile` and `_tile_batch_size`. The expanded compile-test docstring has the same issue. This repository requirement must be satisfied before merging.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

MiniMax-H3 now defaults to eight spatial tiles per decoder call.

  • MiniMax-H3 VAE decoding groups equal-shaped tiles into batches of eight.
  • Spatial tile-parallel decoding uses the per-tile path when enabled.

Reviews (2) · Last reviewed commit: "[bugfix]: decode dynamic-scale NVFP4 H3 ..." · Reviewed by Greptile

Comment thread fastvideo/envs.py Resolved


def test_tile_batch_defaults_to_eight(monkeypatch) -> None:
"""The shipped default decodes eight spatial tiles per decoder call."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Comments violate repository rule

This new docstring repeats the test name and assertion. The repository requires removing code comments outside its explicit keep-list; test narration and private helper docs do not qualify. Remove this docstring and the same narration in test_batched_tile_decode_matches_per_tile and _tile_batch_size. The expanded compile-test docstring has the same issue. This repository requirement must be satisfied before merging.

Rule Used: What: Remove all unwanted code comments in the scoped diff except for a small keep-list (license headers, dependency/protocol-required non-obvious behavior, // prettier-ignore, public API doc comments, and issue/RFC constraint links). Why: Comment... (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: fastvideo/tests/vaes/test_minimax_h3_video_vae_streaming.py
Line: 188

Comment:
**Comments violate repository rule**

This new docstring repeats the test name and assertion. The repository requires removing code comments outside its explicit keep-list; test narration and private helper docs do not qualify. Remove this docstring and the same narration in `test_batched_tile_decode_matches_per_tile` and `_tile_batch_size`. The expanded compile-test docstring has the same issue. This repository requirement must be satisfied before merging.

**Rule Used:** What: Remove all unwanted code comments in the scoped diff except for a small keep-list (license headers, dependency/protocol-required non-obvious behavior, `// prettier-ignore`, public API doc comments, and issue/RFC constraint links).  Why: Comment... ([source](https://app.greptile.com/hao-ai-lab/-/custom-context?memory=856788fb-b8e1-47f8-b01b-d83ea205fc6b))

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 78a83c8: removed the added test docstrings and the _tile_batch_size docstring, and reverted the compile-test docstring.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: infra CI, tests, Docker, build scope: model Model architecture (DiTs, encoders, VAEs) type: perf Performance improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant