Skip to content

[perf]: dispatch wide-M affine H3 MLX linears through dequant plus dense GEMM - #1788

Merged
SolitaryThinker merged 2 commits into
hao-ai-lab:mainfrom
aryan5v:aryan/minimax-h3-mlx-exact-perf
Aug 30, 2026
Merged

[perf]: dispatch wide-M affine H3 MLX linears through dequant plus dense GEMM#1788
SolitaryThinker merged 2 commits into
hao-ai-lab:mainfrom
aryan5v:aryan/minimax-h3-mlx-exact-perf

Conversation

@aryan5v

@aryan5v aryan5v commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Route wide-row affine MiniMax H3 MLX linears through mx.dequantize plus dense BF16 GEMM when the measured crossover applies. Stored INT4/INT6/INT8 weights stay quantized, and dequantized matrices are not cached.
  • Keep shared FastWan and Wan 2.2 linears on mx.quantized_matmul. The H3 path opts into this dispatch explicitly.
  • Use a default H3 floor of M >= 768. Set FASTVIDEO_MLX_DQ_GEMM=0 to disable the H3 dispatch or provide an integer to override the floor.
  • This branch is rebased onto merged [perf] Add MiniMax H3 MLX VSA and SIMD attention #1776. It does not add packed QKV, custom quantized GEMM, spatial batching, or an MLX dependency upgrade.

Measured gates

Existing A/B measurements on an Apple M4 Max with 36 GiB unified memory, MLX 0.31.2, INT6, 832x480x124, four steps, seed 2026, tiled VAE, dense attention, and no temporal fast mode:

  • Four-step DiT: 386.47 s to 348.75 s, 9.8% faster. Video and audio latents were bit-exact. Peak memory changed from 19.31 GiB to 19.46 GiB.
  • Complete MP4: 458.4 s total, including 350.8 s denoise, 106.7 s tiled video decode, 0.61 s audio decode, and 0.31 s mux.
  • Production-shape crossover: INT8 was 11.6% faster and INT4 was 10.7% faster. INT4 at M=256 still favored quantized_matmul, which is why the default floor remains 768.

Validation

  • 63 passed on MLX 0.31.2: affine dispatch, H3 parity, VSA, and fast-mode suites.
  • 63 passed on MLX 0.32.2: the same focused suites.
  • Changed-file pre-commit hooks pass.
  • The disabled H3 path executes and matches quantized_matmul exactly.
  • Shared FastWan/Wan dispatch remains on quantized_matmul at wide M.
  • Both MLX CI lanes now include test_mlx_affine_dq_gemm.py.
  • CI is running on the rebased head.

@mergify mergify Bot added type: perf Performance improvement scope: inference Inference pipeline, serving, CLI scope: infra CI, tests, Docker, build scope: docs Documentation labels Aug 30, 2026
@mergify

mergify Bot commented Aug 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=full-suite-passed
This rule is failing.
  • #approved-reviews-by>=1
  • check-success=full-suite-passed
  • check-success=fastcheck-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 commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

This PR has merge conflicts with the base branch. Please rebase:

git fetch origin main
git rebase origin/main
# Resolve any conflicts, then:
git push --force-with-lease

@mergify mergify Bot added the needs-rebase PR has merge conflicts label Aug 30, 2026

@SolitaryThinker SolitaryThinker left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Request changes — reviewed exact head 77ef31081919e908c4eb274c8036d30dad1c7f4a and replayed its unique commit onto current main (a4d9a75e2, merged #1776).

[P1] Scope the default dequant+dense dispatch to H3, or validate every shared consumer — fastvideo/mlx_runtime/fastwan.py:326-366

affine_dq_gemm_min_m() defaults on and _quantized_linear() is called by the shared linear() helper. That helper is used throughout both FastWan and wan22.py, so this H3-calibrated threshold silently changes every affine-quantized Wan linear with at least 768 leading rows as well. The supplied crossover evidence covers one H3 Q shape on an M4 Max; it does not cover Wan K/N shapes, its memory profile, or end-to-end numerical parity, and the committed microtest itself permits nonzero drift. This can regress performance/memory or alter existing Wan generation by default. Please gate this from the H3 path, keep the shared default off, or provide production-shape Wan performance plus end-to-end parity evidence before enabling it globally.

[P1] Add the new parity suite to the MLX CI commands — fastvideo/tests/mlx/test_mlx_affine_dq_gemm.py:1

Both jobs in current .github/workflows/ci-macos-mlx.yml invoke an explicit list of MLX test files, and neither list includes this new file. The generic Linux fastcheck path skips it at pytest.importorskip("mlx.core"), so no required CI lane executes the only dispatch/parity coverage for this default-on numerical path. This PR does not satisfy the add-model component parity gate until the file is added to both the macOS/Metal and Linux-CPU MLX test lists and produces a non-skip pass.

[P2] Evaluate the disabled-path result — fastvideo/tests/mlx/test_mlx_affine_dq_gemm.py:116-117

MLX is lazy, but this test discards linear(x, quantized) and then evaluates only the already-materialized input x. The qmm result graph therefore never executes, so a runtime failure in the advertised FASTVIDEO_MLX_DQ_GEMM=0 fallback still passes. Keep the result, call mx.eval(got), and compare it with _qmm as the below-threshold test does.

Stack/CI note: the PR still has merge conflicts and is parented on 1559dfd, before the blocker fixes merged with #1776; it needs a rebase onto current main. The fastcheck unit lane is red, but its private Buildkite log is unavailable through the supported triage path, so I am not attributing that failure without evidence.

Reviewed lanes: shared component dispatch, numerical parity/CI coverage, conversion impact, and final evidence. I could not run MLX locally on this Linux host; the author-reported Apple runs were considered, but the required CI integration is still absent.

MLX quantized_matmul is slower than dequantize plus steel GEMM at H3's packed token width. Keep stored INT6 weights and use a measured M=768 floor without caching dequantized matrices.
@aryan5v
aryan5v force-pushed the aryan/minimax-h3-mlx-exact-perf branch from 77ef310 to 78c7c90 Compare August 30, 2026 21:27
@aryan5v

aryan5v commented Aug 30, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the requested changes on head 78c7c90a4.

  • Rebased the PR onto current main at merged [perf] Add MiniMax H3 MLX VSA and SIMD attention #1776. GitHub now reports the branch as mergeable.
  • Scoped dequant plus dense GEMM to MiniMax H3 through an explicit H3 call path. Shared FastWan and Wan 2.2 linears keep quantized_matmul by default, with a regression at wide M.
  • Added test_mlx_affine_dq_gemm.py to both MLX CI commands.
  • Changed the disabled-path test to evaluate the result and compare it exactly with direct quantized_matmul.
  • Ran the focused affine, H3 parity, VSA, and fast-mode suites: 63 passed on MLX 0.31.2 and 63 passed on MLX 0.32.2. Changed-file pre-commit hooks also pass.

@SolitaryThinker, this is ready for re-review.

@mergify mergify Bot removed the needs-rebase PR has merge conflicts label Aug 30, 2026
@SolitaryThinker
SolitaryThinker merged commit 8f9d76a into hao-ai-lab:main Aug 30, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: docs Documentation scope: inference Inference pipeline, serving, CLI scope: infra CI, tests, Docker, build type: perf Performance improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants