mmh3turbo
MiniMax-H3 video + audio generation on Apple Silicon, with hand-written int8 Metal kernels.
uvx mmh3turbo "a rainbow colored skunk leaps over a mossy log in a supermarket"
That is the whole setup. The first run downloads what it needs and starts
generating; later runs begin immediately. Prepared bundles come from
yunfengwang/mmh3turbo-bundles;
set MMH3TURBO_BUNDLE_REPO="" to convert them locally instead (~8 min). Output is an mp4
with a stereo soundtrack, plus the individual frames and a gif preview.
What this is
H3 is not a language model. It is a 33B diffusion transformer that denoises
video and audio latents jointly in one packed sequence, conditioned by a
frozen Qwen3-VL-32B text tower, with separate video and audio VAEs. Attention is
full self-attention over [text | keyframes | audio | video] — no
cross-attention, no per-modality weights.
This is a from-scratch MLX port. Every component is checked against a PyTorch transcription of the reference:
| Component | Agreement with reference |
|---|---|
| GGUF k-quant dequantization | bit-exact vs the gguf package |
| Video VAE decoder | 7.8e-04 relative |
| Audio VAE decoder | 1.1e-05 relative |
| Fused int8 kernels | max int8 unit difference 1, 0 beyond |
Why it is fast, and where it is not
The four fused Metal kernels are the point. flash_i8 is 26% faster than
mx.fast.scaled_dot_product_attention at T=38656 (22.4 vs 16.6 TOPS), and the
block's four GEMMs run at 44-50 TOPS.
Measured on an M5 Pro (51 GB), 12 steps:
| Preset | Canvas | 5 s clip |
|---|---|---|
352p |
608x352 | 3.3 min |
480p |
864x480 | 6 min |
704p |
1216x704 | 21 min |
768p |
1376x768 | 32 min |
A 1376x768 / 5 s / 15-step run takes 43 min here, against ~45 min reported for an M5 Max — a machine with roughly twice the GPU cores.
That is the floor, not a missing optimization. Attention is 74% of the block
at 768p and scales with T². Eight approaches were measured and rejected: tile
sweeps, K/V reuse, removing the score staging buffer, MLX's own SDPA, per-block
eval, schedule reshaping, step caching, and temporal chunking. Each is documented
with its numbers in kernels.py and the relevant module. The binding constraint
is that QK's K is head_dim=128, and int8 GEMM manages 3.3 TOPS at K=128 versus
49.9 at K=5376 — so the peak figure is simply unreachable for this shape.
Want it faster? Use a smaller canvas. 352p is 1.5 min for 2 s.
Downloads: ~33 GB, not ~115 GB
The text tower is consumed as a 7.9 GB GGUF instead of the 66.7 GB unquantized encoder, which required implementing k-quant dequantization directly — and finding a real Q3_K bug along the way (ggml's high-mask bit advances across both half-blocks; resetting it per half-block is silently wrong, and the weight statistics look perfectly healthy either way).
Usage
mmh3turbo "prompt" -r 480p --seconds 5.0 -o out/
mmh3turbo --list-res
mmh3turbo "prompt" --first-frame photo.png # image-to-video
Canvas dimensions must be multiples of 32 (the VAE's 16x times the DiT's 2x patch). 1280x720 is rejected with the nearest valid size, because otherwise the patch grid silently drops the last latent row and quietly returns 1280x704.
--steps defaults to 12; it is visually indistinguishable from the reference
template's 20 (31.0 dB), while 8 gives 23.6 dB and 4 gives 17.6 dB.
Requirements
Apple Silicon, macOS. ffmpeg for the mp4 mux (frames and audio.wav are still
written without it). Peak memory is 22 GiB at 352p and 31 GiB at 768p.
Source
https://github.com/vra/mmh3turbo
Credit
The base int8 GEMM and flash-attention kernels in _metal.py are vendored from
the zimgturbo project. The reference semantics were read from ComfyUI's
MiniMax-H3 implementation.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mmh3turbo-0.1.0.tar.gz.
File metadata
- Download URL: mmh3turbo-0.1.0.tar.gz
- Upload date:
- Size: 60.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b10ba755f8b654cdf65a37daacb38ea8509fe5595d651c597cd405c4cbcfa19a
|
|
| MD5 |
e6de7db3ef14eb1cd9e01a238dab79a4
|
|
| BLAKE2b-256 |
c8129c6cb16b56e1034674390da409893874bbc25af1b7ebc2de679831d39bcd
|
File details
Details for the file mmh3turbo-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mmh3turbo-0.1.0-py3-none-any.whl
- Upload date:
- Size: 69.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38a0e6dc6af43c6e1733cd1cceeff359ffe240789a3d9213c905b25c579d22f3
|
|
| MD5 |
2509d6ada96304a711160fc8630f08f6
|
|
| BLAKE2b-256 |
45a7215ec8071268f072f2c8216c8678abe0803eb8ab18e14627f0362ca87508
|