CLI tool
antirez/h3.c avatar
antirez/h3.c

h3.c: MiniMax-H3 video and audio inference on Apple Silicon, in C and Metal

MiniMax H3 inference engine for Mac computers

2,686 stars214 forksCMIT

At a glance

What is it?
A native Metal inference engine for MiniMax-H3 that runs prompt-to-video, first/last-frame conditioning and ordered references on Macs. The README documents its mechanisms, its memory trade-offs and the numbers behind its presets.
Who is it for?
Adopt h3.c if you already have Apple Silicon and a local MiniMax-H3 snapshot and want a single C binary that runs prompt-to-video, first/last-frame conditioning and ordered Ref2VA references without a Python stack. Do not adopt it if you are on CUDA hardware, need a stable documented API, or want a project with releases and a support policy.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 38 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 16, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What h3.c is for, and who it is not for

h3.c is a C and Objective-C inference engine for MiniMax-H3 that targets Apple Silicon through Metal. The README describes it as "Native MiniMax-H3 inference for Apple Silicon" and says the project is built as a sequence of working vertical slices: deterministic host and model metadata first, then portable Metal block parity, prompt encoding, prompt-to-video and audio, first/last-frame conditioning, and ordered references. Prompt-to-video and audio, first/last-frame conditioning, and ordered Ref2VA image/video/audio references work end to end according to that description. The current work is incremental H3-specific Metal performance and memory optimization on M3 Max and M5 Max.

The audience is narrow. You need a Mac with Apple Silicon, a local Hugging Face snapshot of MiniMax-H3 in a directory, and FFmpeg and FFprobe on PATH. There is no server mode, no Python package and no documented HTTP API. If you are on NVIDIA hardware or you want a hosted endpoint, this is the wrong tool and the repository does not pretend otherwise. The value here is that the whole pipeline, text encoder, DiT, video VAE and audio VAE, lives in one C binary compiled against Metal and Accelerate, so there is no interpreter between you and the GPU.

How the pipeline is split across files

The repository layout shows the architecture more clearly than the README does. h3_text_encoder.c handles prompt encoding, h3_tokenizer.m wraps ICU for tokenization, h3_dit.c and h3_dit_schedule.c implement the denoiser and its noise schedule, h3_video_vae.c and h3_audio_vae.c decode latents to media, h3_ffmpeg.c muxes output, and h3_metal.m and h3_shaders.metal hold the GPU layer. h3_safetensors.c and h3_weights.c read the checkpoint. The Makefile links Foundation, Metal, MetalPerformanceShaders, MetalPerformanceShadersGraph and Accelerate, plus libicucore and libm.

That split matters because it tells you where the memory goes. The README states that prompt encoding and the two VAEs run in separate phases rather than adding their full peaks to the DiT's tracked storage. The DiT is the resident cost. With --ssd-streaming the engine keeps two DiT blocks in memory and reads the next block from SSD while the GPU runs the current one. Without it, all 50 blocks stay resident. The schedule is a separate concern: the README says the retained mode uses the released linear base grid with one terminal point, and that tail-heavy schedules were evaluated and rejected because they preserved too few early composition updates and produced woven texture, weak motion or clipped colors.

Building h3.c and running --info

The README assumes the Hugging Face snapshot is in ./MiniMax-H3 and that FFmpeg and FFprobe are on PATH. Build with the Makefile, create an outputs directory, then check the model layout before generating anything. The --info flag prints the selected Metal device without mapping all weights or generating media, which makes it the cheapest way to find out whether your snapshot is laid out the way the loader expects.

bash
make -j8
mkdir -p outputs
./h3 --info -d ./MiniMax-H3

Run ./h3 --help for the complete CLI reference. If --info succeeds, the next step is the balanced preset the README calls validated: 22 frames at 24 fps, roughly 0.92 seconds of video, 512 by 512, 20 denoising passes, 45 of 50 transformer blocks, and --reuse 2 so 11 fresh denoiser velocities are computed and the skipped transitions are extrapolated.

bash
./h3 --profile \
  -d ./MiniMax-H3 \
  -p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur, soft footsteps and wind." \
  --width 512 --height 512 \
  --frames 22 --steps 20 \
  --layers 45 --reuse 2 \
  --show \
  -o outputs/fox-fast.mp4

--profile prints phase timings and does not select a different generation path. --show is optional and only works in graphical terminals that speak the Kitty/Ghostty or iTerm2/WezTerm/Konsole protocols. It keeps a preview VAE resident, which the README estimates at roughly 10 GiB of temporary model residency, so drop it for a low-memory run.

The interactive session and its conditioning commands

Without -p, the same binary starts an Iris-style interactive session and keeps the exact BF16 prompt conditioning, the prepared DiT and the video decoder in memory. Repeating a prompt with another seed therefore skips loading and encoding them again. The README lists !status, !seed random, !seconds 2, !show, !save output.mp4 and !cache as useful commands, with !help for the full list.

text
./h3 -d ./MiniMax-H3 --width 512 --height 512 --steps 6
h3> !first opening.png
h3> !last ending.png
h3> The camera moves slowly around the subject.

First and last frame anchors persist for the session; !first clear and !last clear remove them. For a general Ref2VA conditioning image, !ref-image PATH appends images in order and the model sees them as <Picture 1>, <Picture 2> and so on. Filenames carry no meaning to the model, so the prompt has to refer to the picture by index. !refs lists the order, !ref-remove N removes one entry and !refs clear removes them all. One constraint is stated plainly: Ref2VA references cannot be mixed with !first or !last anchors. In a session, SSD streaming is toggled with !ssd-streaming on.

SSD streaming is a real memory and speed trade-off

The low-memory path uses the original BF16 checkpoint without conversion or quantization and streams DiT blocks from SSD. The README reports tracked DiT storage falling from about 36.5 GiB to 2.0 GiB at 512 square and 2.1 GiB at 864x480 on M5 Max. That figure is the DiT's tracked tensor storage, not total system RAM. The OS, media buffers and output resolution still need headroom, and --show adds its roughly 10 GiB on top, so it should be omitted for the lowest-memory run.

bash
./h3 --profile \
  -d ./MiniMax-H3 \
  -p "A red fox walks through fresh snow in a pine forest." \
  --width 512 --height 512 --frames 22 --steps 20 \
  --layers 50 --reuse 1 --ssd-streaming \
  -o outputs/fox-ssd.mp4

The cost is documented: a warm 50-block forward measured 1.35 versus 2.49 seconds at 512 square, which the README calls 84% slower, and 2.14 versus 2.68 seconds at 864x480, 26% slower. Those comparisons are against the same full-residency BF16 path and the results were byte-identical in both checks. Two constraints are worth noting. SSD streaming cannot be combined with --use-int8-row-fc2, and it is not the default. If your Mac has enough unified memory for full residency, streaming buys you nothing and costs you time.

Low-step generation and what the README admits about quality

The README is unusually candid about the quality floor. On the 512-square, 22-frame fox test, the selected four-pass result had 0.556 full-video SSIM against a 29-pass reference, and an independent surfer test measured 0.547. The four-pass denoise took about 3.5 seconds on M5 Max against 26.4 seconds for the reference. Four through seven passes use the same schedule that won the low-budget comparison, and increasing from 4 to 7 progressively improves detail and motion. The README advises keeping --reuse 1 at such small budgets so every requested pass actually runs the model.

bash
./h3 --profile \
  -d ./MiniMax-H3 \
  -p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur." \
  --width 512 --height 512 --frames 22 \
  --steps 4 --layers 50 --reuse 1 \
  --show \
  -o outputs/fox-four-step.mp4

Read those numbers as a description of a draft mode, not a replacement for the reference. An SSIM around 0.55 means the low-step output is structurally related to the reference but visibly different, which matches the README's own framing that 4 to 7 passes trade detail and motion for speed. If you need the reference quality, you are back to 50 passes and full residency.

Where h3.c sits next to diffusers and ComfyUI

The obvious alternative for MiniMax-H3 is a Python stack, either the diffusers pipeline or a ComfyUI graph, both of which run on Apple Silicon through PyTorch's MPS backend. The difference in approach is not the model, it is the runtime. A Python stack gives you a large ecosystem of nodes, schedulers and community checkpoints, and it is portable to CUDA machines. h3.c gives you a single C binary, explicit control over how many transformer blocks are resident, and a documented SSD streaming mode that keeps two DiT blocks in memory. It also gives you an interactive session that holds the BF16 prompt conditioning and prepared DiT across prompts.

What you give up is flexibility. There is no plugin surface, no scheduler zoo and no documented way to swap components. The README does not document rollback, versioned checkpoints or a compatibility matrix for MiniMax-H3 releases, and no releases were retrieved for this repository. If your work depends on tracking upstream model changes quickly, a Python stack will absorb them sooner. If your work depends on fitting a fixed model into a fixed Mac and knowing exactly what each flag costs, the C binary is the more predictable tool.

Maintenance, licensing and what to verify before you commit

The repository is not archived and the last push was on 2026-08-11. That is recent, but it is the only maintenance signal available here: no releases were retrieved, and the README describes the project as being built as a sequence of working vertical slices with incremental optimization still in progress. Treat the CLI as moving. Flags such as --reuse, --layers and --ssd-streaming are documented in the README but there is no stated stability guarantee, and the README does not document rollback or a changelog.

h3.c itself is MIT licensed, which is permissive and imposes few obligations beyond keeping the notice. That covers the engine, not the weights. The MiniMax-H3 checkpoint you download has its own licence, and the repository ships a THIRD_PARTY_NOTICES.md file that you should read before redistributing anything. Linking against MetalPerformanceShadersGraph and Accelerate does not change the MIT terms of the source, but it does tie the build to Apple platforms. None of this is legal advice; check the model licence yourself if you plan to ship generated media or a product built on this binary.

Editorial conclusion

Adopt h3.c if you already have Apple Silicon and a local MiniMax-H3 snapshot and want a single C binary that runs prompt-to-video, first/last-frame conditioning and ordered Ref2VA references without a Python stack. Do not adopt it if you are on CUDA hardware, need a stable documented API, or want a project with releases and a support policy. Before committing, run ./h3 --info against your snapshot to confirm the model layout, measure your own timings with --profile on repeated runs, and decide whether --ssd-streaming is worth its documented slowdown.

Frequently asked questions

What hardware does h3.c require?

The README targets Apple Silicon and the current optimization work is described on M3 Max and M5 Max. The build links Foundation, Metal, MetalPerformanceShaders, MetalPerformanceShadersGraph and Accelerate, so it is a macOS build.

How do I install h3.c?

There is no package or installer. The README gives a Makefile build: run make -j8, create an outputs directory, and point the binary at a local MiniMax-H3 snapshot with -d. FFmpeg and FFprobe must be on PATH.

Can h3.c run on a Mac with limited unified memory?

The README documents --ssd-streaming, which keeps two DiT blocks in memory and reads the next block from SSD, reporting tracked DiT storage of about 2.0 GiB at 512 square. It cannot be combined with --use-int8-row-fc2, and the README notes the 2.0 to 2.1 GiB figure is DiT tensor storage, not total system RAM.

Can I mix first/last frame anchors with Ref2VA references in h3.c?

No. The README states that Ref2VA references cannot be mixed with !first or !last anchors. Use !ref-image for ordered references or !first and !last for anchors, but not both in the same session.

Official sources

  1. antirez/h3.c on GitHub
  2. Issues
  3. License: MIT
  4. README
Community notes

Community notes