Wild H3 Text to Video
MiniMax H3 on your Mac, without the API meter
- first_frame
- last_frame
- video
If you're on an Apple Silicon Mac, MiniMax H3 has been a frustrating model to watch. It's the first open-weight video model that generates picture and stereo audio together - the thing Veo held over the open ecosystem for a year - and ComfyUI does support it, via a CUDA-shaped PyTorch path that on a Mac means roughly an hour a clip. Technically supported. Practically dead.
This node is the workaround, and it's a strange one: H3 never runs inside ComfyUI. It shells out to the h3 binary from antirez's h3.c - Salvatore Sanfilippo's C/Metal port for Apple Silicon - and hands you back a normal ComfyUI VIDEO.
Why you'd reach for it
Two reasons, both about money and latency rather than quality. The official MiniMax nodes in ComfyUI are partner nodes - metered, prepaid credits, billed per second of video. Nothing wrong with them, but you don't iterate freely when every experiment costs credits, and locally a take is free. The pack's framing has the two as complementary: iterate here, hand the locked prompt to hosted H3 Max for the final. Second reason: privacy - prompts and reference frames never leave the machine.
How it works
It assembles a command line - h3 -d <model_dir> -p <prompt> --width … --steps … --layers … --reuse … -o <tmp>.mp4 - runs it from the binary's own directory (h3 looks for its shader file relative to itself), and reads stderr one character at a time, because h3 prints progress with carriage returns and normal line reading would hang. Those segments feed ComfyUI's progress bar, so you get a real bar during the denoise. Output lands in the temp directory, wrapped as a VIDEO. Interrupting the queue kills the child process.
preset is the one bit of node magic worth knowing: it's not a model, it's two numbers. precise runs 50 DiT layers with reuse 1, balanced 45/2, fast 40/3. Fewer layers, more reuse, faster and rougher. balanced is the default for a reason.
The inputs that matter
prompt is a raw H3 prompt - H3 is chatty about camera and lighting detail, and thin prompts come back mushy. width/height must be multiples of 32 with the area capped at 768×1344. seconds runs 0.25 to 15, snapped to h3's own frame chunks (roughly 6 to 362 frames), so don't expect exact fractions to survive. Then steps (denoising passes, default 20), preset, and a full 64-bit seed with randomize.
The two optional inputs, first_frame and last_frame, are FL2VA anchoring - an image to start from, end on, or both. That makes this node not-quite-text-to-video when you want it to be, and it's why reference conditioning lives on a separate node.
In advanced: token_reduction pairs video tokens in the middle DiT blocks, which the tooltip calls an aggressive speedup. It's a merging trick, so check the output before trusting it on a hero shot. ssd_streaming streams the BF16 weights off disk to trade memory for speed - for when the checkpoint crowds your unified memory, and it wants a fast SSD. binary_path and model_dir override config.json per workflow.
One output: video, wire it into Save Video (or Preview). The node also previews on itself, but the actual mp4 sits in the temp dir - save it if you want it to survive.
Install
ComfyUI Manager, search Wild H3C. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/skaiy/wild-h3c-comfyui.git
Then there's setup the manager can't do: macOS on Apple Silicon, ffmpeg and ffprobe on PATH (brew install ffmpeg), a ComfyUI new enough for the V3 schema - this pack has no NODE_CLASS_MAPPINGS, it registers through comfy_entrypoint(), so anything before 0.18 won't see the nodes - and the engine built from source:
git clone https://github.com/antirez/h3.c.git && cd h3.c && make -j8
Checkpoints are ~268 GB total; FL2VA alone (~134 GB) is enough for this node. Then point the plugin at both:
{ "h3_binary": "~/h3.c/h3", "model_dir": "~/h3.c/MiniMax-H3" }
model_dir is the folder containing FL2VA/, not FL2VA itself. Verify the download before blaming the plugin: ./h3 --info -d <path>/MiniMax-H3 prints the inventory in seconds.
Where people get burned
Editing config.json and nothing happening. It's read once and cached per process - restart ComfyUI. Quick tell: the node description reads binary: (not configured) if your paths never took.
The first run looks hung while that checkpoint loads with zero progress output. The bar starts when denoising does. Don't kill it.
No parallelism. h3 calls are serialized behind one lock - one process already saturates the GPU. Five queued variations run in a row, not at once.
"Node is missing" on an old workflow. Node IDs were renamed to WildH3* at release - re-add the node.
The licence. Code is MIT, weights aren't. The MiniMax H3 Community License excludes the US, EU, UK and South Korea from its Applicable Territory - outputs included - plus a revenue gate on commercial use. Check where you sit before downloading 268 GB.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | Raw H3 prompt. Reference media are cited as <Picture N>/<Audio N>. | |
| width | INT | 86432–1344 | Output width. Multiple of 32, width*height <= 768*1344. |
| height | INT | 48032–1344 | Output height. Multiple of 32. |
| seconds | FLOAT | 2.000.25–15 | Duration at 24 fps; h3 aligns frames up to 5+17n chunks. |
| steps | INT | 202–1000 | Denoising passes. |
| preset | COMBO | balanced | Speed/quality: precise=50 layers/reuse 1, balanced=45/2, fast=40/3. |
| seed | INT | 420–18446744073709550000 | — |
| token_reduction | BOOLEAN | false | Pair video tokens in middle DiT blocks (aggressive speedup). |
| ssd_streaming | BOOLEAN | false | Stream BF16 DiT weights from SSD (VRAM for speed). |
| binary_path | STRING | Override h3 binary path. Empty = config.json. | |
| model_dir | STRING | Override MiniMax-H3 model directory. Empty = config.json. | |
| first_frameopt | IMAGE | FL2VA first-frame conditioning. Mutually exclusive with reference inputs. | |
| last_frameopt | IMAGE | FL2VA last-frame conditioning. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |