Skip to content

[feat] Add MatrixGame3.0 - #1201

Merged
mergify[bot] merged 30 commits into
hao-ai-lab:mainfrom
H1yori233:feat/kaiqin/add-mg-3
May 27, 2026
Merged

[feat] Add MatrixGame3.0#1201
mergify[bot] merged 30 commits into
hao-ai-lab:mainfrom
H1yori233:feat/kaiqin/add-mg-3

Conversation

@H1yori233

@H1yori233 H1yori233 commented Mar 31, 2026

Copy link
Copy Markdown
Collaborator

Purpose

Add MatrixGame3.0 inference support to FastVideo.
https://huggingface.co/FastVideo/Matrix-Game-3.0-Base-Distilled-Diffusers

Changes

  • Add matrixgame3.0 model and action module fastvideo/models/dits/matrixgame3.
  • Add matrixgame3.0 pipeline fastvideo/pipelines/basic/matrixgame.
  • Add matrixgame3.0 specific denoising stage fastvideo/pipelines/stages/matrixgame_denoising.py.
  • Add matrixgame3.0 specific light vae.
test.1.mp4
ours.mp4

TODO

  • migrate origin matrixgame2.0 model/pipeline name
  • inference for base model (bidirectional multi-step)
  • code cleanup

Test Plan

# Commands you ran

Test Results

Test output
# Paste output here

Checklist

  • I ran pre-commit run --all-files and fixed all issues
  • I added or updated tests for my changes
  • I updated documentation if needed
  • I considered GPU memory impact of my changes

For model/pipeline changes, also check:

  • I verified SSIM regression tests pass
  • I updated the support matrix if adding a new model

@mergify mergify Bot added type: feat New feature or capability scope: training Training pipeline, methods, configs scope: inference Inference pipeline, serving, CLI scope: infra CI, tests, Docker, build scope: model Model architecture (DiTs, encoders, VAEs) labels Mar 31, 2026
@mergify

mergify Bot commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🟢 PR merge requirements

Wonderful, this rule succeeded.
  • #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)\]

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request introduces support for MatrixGame 3.0, adding new DiT architectures, action modules, and I2V pipelines while refactoring existing MatrixGame 2.0 components for clarity. Feedback identifies a critical import mismatch for extrinsic builders and a batching issue where only the first item's actions are used for camera trajectories. Performance concerns were raised regarding inefficient VAE device transfers and redundant timestep embedding computations. Additionally, the review suggests using modulo for angle normalization, warns against silent tensor cropping, and notes potential compatibility regressions in the VAE normalization logic.

Comment thread fastvideo/pipelines/stages/matrixgame_denoising.py Outdated
Comment thread fastvideo/pipelines/stages/matrixgame_denoising.py Outdated
Comment thread fastvideo/pipelines/stages/image_encoding.py Outdated
Comment thread fastvideo/models/dits/matrixgame3/utils.py Outdated
Comment thread fastvideo/pipelines/stages/matrixgame_denoising.py Outdated
Comment on lines +735 to +737
timestep_tokens = timestep_tokens.unsqueeze(1).repeat(
1, post_patch_num_frames * post_patch_height * post_patch_width
)

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.

medium

Repeating the timestep for every spatial token and then passing the flattened tensor to the condition_embedder leads to a massive amount of redundant computation in the TimestepEmbedder. Since the timesteps are identical for all tokens in this fallback case, it is much more efficient to compute the embedding once per batch and then expand it spatially.

Comment thread fastvideo/models/vaes/wanvae.py Outdated
@mergify

This comment was marked as resolved.

@mergify mergify Bot added the needs-rebase PR has merge conflicts label Apr 5, 2026
@mergify mergify Bot added scope: data Data preprocessing, datasets scope: docs Documentation and removed needs-rebase PR has merge conflicts labels May 14, 2026
H1yori233 added 8 commits May 15, 2026 07:34
# Conflicts:
#	examples/train/scenario/worldmodel/dfsft_causal_i2v.yaml
#	examples/train/scenario/worldmodel/finetune_i2v.yaml
#	examples/train/scenario/worldmodel/self_forcing_causal_i2v.yaml
#	fastvideo/configs/pipelines/__init__.py
#	fastvideo/models/dits/matrixgame2/model.py
#	fastvideo/models/registry.py
#	fastvideo/pipelines/basic/matrixgame2/matrixgame2_causal_dmd_pipeline.py
#	fastvideo/pipelines/basic/matrixgame2/matrixgame2_i2v_pipeline.py
#	fastvideo/pipelines/preprocess/matrixgame2/matrixgame2_preprocess_pipeline_ode_trajectory.py
#	fastvideo/pipelines/preprocess/v1_preprocess.py
#	fastvideo/pipelines/stages/__init__.py
#	fastvideo/registry.py
#	fastvideo/tests/api/test_presets.py
@H1yori233

Copy link
Copy Markdown
Collaborator Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request integrates Matrix-Game 3.0 into the FastVideo framework, introducing a new 5B-parameter DiT model, an action module for interactive control, and a dedicated I2V pipeline supporting 720p resolution. The changes include comprehensive model and pipeline configurations, specialized denoising and image encoding stages, and utility functions for camera and action processing. Feedback from the review highlights several critical issues: potential empty tensor returns due to incorrect slicing when padding is zero in the action module, and possible runtime errors in the VAE implementation when comparing tensors directly to strings. Additionally, the reviewer recommended guarding the torch.compile call with the existing DISABLE_COMPILE flag and replacing hardcoded architectural and window size parameters with values derived from the model configuration to improve flexibility and robustness.

Comment thread fastvideo/models/dits/matrixgame3/action_module.py Outdated
Comment thread fastvideo/models/dits/matrixgame3/action_module.py Outdated
Comment thread fastvideo/models/dits/matrixgame3/action_module.py Outdated
Comment thread fastvideo/models/vaes/wanvae.py Outdated
Comment thread fastvideo/models/vaes/wanvae.py
Comment on lines +21 to +23
flex_attention = torch.compile(
flex_attention, dynamic=False, mode="max-autotune-no-cudagraphs"
)

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.

medium

The torch.compile call on flex_attention is not guarded by the DISABLE_COMPILE flag defined just above it. This prevents users from disabling compilation if needed for compatibility or debugging.

Suggested change
flex_attention = torch.compile(
flex_attention, dynamic=False, mode="max-autotune-no-cudagraphs"
)
if not DISABLE_COMPILE:
flex_attention = torch.compile(
flex_attention, dynamic=False, mode="max-autotune-no-cudagraphs"
)

Comment on lines +797 to +804
fc, fs = self.get_rotary_pos_embed(
7500,
self.patch_size[1],
self.patch_size[2],
64,
self.mouse_qk_dim_list,
start_offset=0,
)

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.

medium

The head_dim parameter for get_rotary_pos_embed is hardcoded to 64. This should be derived from the model configuration (e.g., mouse_hidden_dim // heads_num) to ensure RoPE is applied correctly if the architecture dimensions change.

target_h = latent_h * spatial_ratio
target_w = latent_w * spatial_ratio
num_iterations = self._infer_num_iterations(batch)
clip_frame = 56 # hardcode for now

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.

medium

The clip_frame value is hardcoded to 56. This value is tightly coupled with the model's expected window size and should ideally be retrieved from the pipeline or model configuration to support different sequence lengths or future model variants.

@H1yori233
H1yori233 marked this pull request as ready for review May 19, 2026 02:23
@H1yori233
H1yori233 force-pushed the feat/kaiqin/add-mg-3 branch from 0453dd6 to d296ccf Compare May 19, 2026 02:25
@SolitaryThinker

Copy link
Copy Markdown
Collaborator

Hi @H1yori233 — automated review from Gob, one of @SolitaryThinker's AI reviewers. Findings aren't all human-verified; ping @SolitaryThinker if anything looks off.

TL;DR

All four critical gemini-bot concerns from the most recent review are resolved at HEAD 35281410cd. The cross-cutting wanvae.py change is properly gated by use_light_vae=False default, so Wan-2.1 / Matrix-Game 2.0 paths stay untouched. Two non-blocking follow-ups: per-batch camera trajectory uses only [0] (G4 still open), and the PR body's Test Plan / Test Results sections are empty.

Verdict: approve-with-followup

S1: 0 · S2: 2 · S3: 2 · Gemini resolved: 5/9 (+ 2 mitigated, + 2 unchanged-but-non-blocking)

Gemini concerns status at HEAD 35281410cd

ID Concern Status
G1 action_module.py :-padded_length empty-tensor bug ✅ Resolved (padded_length removed entirely)
G2 Same bug at second site ✅ Resolved (same removal)
G3 Import name mismatch in matrixgame3_denoising.py ✅ Resolved (build_extrinsics_from_actions matches def at utils.py:103)
G4 Camera extrinsics use only batch.keyboard_cond[0] for whole batch ❌ Still present at matrixgame3_denoising.py:121 — see S2-1
G5 VAE GPU↔CPU thrash in image_encoding.py:forward() ✅ Acceptable — matches existing vae_cpu_offload pattern (Wan/Hy precedent)
G6 while loops for angle normalization ⏸️ Cosmetic, non-blocking
G7 Silent shape-crop at denoising step ⏸️ Now logs warning(...) at line 296 — no longer silent
G8 Timestep repeated per spatial token (perf) ⏸️ Unchanged; perf-only
G9 wanvae.py RMS scale removal ✅ Resolved — self.scale still at line 230; new path gated by use_light_vae=False default

Findings

S2-1 [persistent] — Camera trajectory uses only batch.keyboard_cond[0] / batch.mouse_cond[0]

File: fastvideo/pipelines/stages/matrixgame3_denoising.py:121

extrinsics_all = build_extrinsics_from_actions(batch.keyboard_cond[0], batch.mouse_cond[0]).to(device)

For batch_size > 1, every batch item silently inherits the trajectory of item 0. Current MG3 presets are single-sample so this never triggers in shipped paths, but anyone batching multi-prompt I2V will get incorrect trajectories with no error.

Suggested fix — either:

  1. Loop per-batch-item and stack into a batched extrinsics_all, propagating the batch dim through subsequent slicing, OR
  2. Assert batch.keyboard_cond.shape[0] == 1 at stage entry with a clear error documenting MG3's current batch-size=1 contract.

Option (2) is the cheap defensive fix and matches the actual user-facing surface.

S2-2 [persistent] — PR body Test Plan + Test Results are empty placeholders

PR checklist is all ✅ but the Test Plan and Test Results sections have no SSIM score, no CI/Modal run link, no example output path. SSIM test file exists and looks correct, but reviewers can't independently verify it has run. Recommend pasting the actual SSIM score (or a Buildkite/Modal link) before merge.

What's good

  • Heavy port shipped end-to-end after Matrix-Game 2.0 ([feat] Add Matrix-Game 2.0 #938) — author has track record on this exact surface.
  • Cross-cutting wanvae.py change is gated by use_light_vae=False default; Wan-2.1 / MG2.0 callers are bit-identical. vision_utils.resize "crop" mode is a new elif (additive). ForwardBatch.num_iterations / use_base_model are optional with safe defaults. This is exactly the right pattern for a shared-file modification.
  • Registry / preset / SSIM test / example / support_matrix.md all use the same HF ID FastVideo/Matrix-Game-3.0-Base-Distilled-Diffusers.
  • All 28 commits authored by @H1yori233, no AI co-author trailers.

— Gob (@SolitaryThinker's AI reviewer). Full review archived locally.

The matrixgame3_denoising stage derives camera/mouse extrinsics from
batch.keyboard_cond[0] / batch.mouse_cond[0], which silently uses item-0's
trajectory for the whole batch when batch_size > 1. Add a loud assertion
documenting MG3's current batch-size=1 contract so future callers fail
fast rather than getting incorrect trajectories.

Addresses S2-1 from PR hao-ai-lab#1201 gob review
(hao-ai-lab#1201 (comment)).
Option 2 (assertion guard) chosen over option 1 (loop+stack) per
maintainer direction; if batched action streams are eventually needed,
build_extrinsics_from_actions can be made per-batch-item then.
SolitaryThinker added a commit to H1yori233/FastVideo that referenced this pull request May 27, 2026
Lowers MATRIXGAME3_PARAMS height/width from 720x1280 to 352x640 in the
SSIM regression test (matches MatrixGame 2.0 convention from the
MatrixGame2SamplingParam defaults). MATRIXGAME3_FULL_QUALITY_PARAMS
remains 720x1280 — it derives from SamplingParam.from_pretrained and
covers the full-quality tier separately.

Compute reduction: ~4x vs 720p (352*640 / 720*1280 ≈ 0.24). Brings the
SSIM test within typical L40S CI runtime budget so a HF reference can be
seeded against this resolution.

Followup to PR hao-ai-lab#1201 review:
hao-ai-lab#1201 (comment)
SolitaryThinker added a commit to H1yori233/FastVideo that referenced this pull request May 27, 2026
Two related changes to fastvideo/tests/ssim/test_matrixgame3_similarity.py:

1. Lower MATRIXGAME3_PARAMS height/width from 720x1280 to 352x640
   (matches MatrixGame 2.0 convention from MatrixGame2SamplingParam
   defaults). MATRIXGAME3_FULL_QUALITY_PARAMS remains 720x1280 — it
   derives from SamplingParam.from_pretrained and covers the
   full-quality tier separately. Compute reduction: ~4x vs 720p
   (352*640 / 720*1280 ≈ 0.24).

2. Add fallback_device_prefix='L40S' to resolve_device_reference_folder
   so non-tabled GPUs (B200, etc) fall back to L40S references with a
   clean warning instead of TypeError-crashing at build_generated_output_dir.
   Matches the precedent in fastvideo/tests/ssim/test_sd35_similarity.py.

Together: brings the SSIM test within L40S CI runtime budget AND makes
it runnable locally on B200 dev boxes before the HF reference is seeded.

Followup to PR hao-ai-lab#1201 review:
hao-ai-lab#1201 (comment)
Two related changes to fastvideo/tests/ssim/test_matrixgame3_similarity.py:

1. Lower MATRIXGAME3_PARAMS height/width from 720x1280 to 352x640
   (matches MatrixGame 2.0 convention from MatrixGame2SamplingParam
   defaults). MATRIXGAME3_FULL_QUALITY_PARAMS remains 720x1280 — it
   derives from SamplingParam.from_pretrained and covers the
   full-quality tier separately. Compute reduction: ~4x vs 720p
   (352*640 / 720*1280 ≈ 0.24).

2. Add fallback_device_prefix='L40S' to resolve_device_reference_folder
   so non-tabled GPUs (B200, etc) fall back to L40S references with a
   clean warning instead of TypeError-crashing at build_generated_output_dir.
   Matches the precedent in fastvideo/tests/ssim/test_sd35_similarity.py.

Together: brings the SSIM test within L40S CI runtime budget AND makes
it runnable locally on B200 dev boxes before the HF reference is seeded.

Followup to PR hao-ai-lab#1201 review:
hao-ai-lab#1201 (comment)
@SolitaryThinker

Copy link
Copy Markdown
Collaborator

/merge

@github-actions github-actions Bot added the ready PR is ready to merge label May 27, 2026
@H1yori233

Copy link
Copy Markdown
Collaborator Author

/test vsa

@mergify
mergify Bot merged commit afdb6fb into hao-ai-lab:main May 27, 2026
24 of 25 checks passed
@H1yori233 H1yori233 mentioned this pull request May 31, 2026
1 task
@H1yori233
H1yori233 deleted the feat/kaiqin/add-mg-3 branch June 2, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready PR is ready to merge scope: data Data preprocessing, datasets scope: docs Documentation scope: inference Inference pipeline, serving, CLI scope: infra CI, tests, Docker, build scope: model Model architecture (DiTs, encoders, VAEs) scope: training Training pipeline, methods, configs type: feat New feature or capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants