MMH3 Latent Preview (approx)
Check the Clip Before You Pay for the Full Decode
- latent
- info
MiniMax H3 is a 33B omni-modal video model that generates 4-15 second clips at up to 2K with native stereo audio, and on consumer hardware a single segment is a several-minute wait. The last thing you want is to spend that then discover the seam you just spent ten minutes generating is mushy. This node exists so you can look at the result cheaply, before committing the full VAE decode.
What it actually does
It takes an already-sampled H3 latent, decodes it with a tiny H3 VAE decoder (the taeh3 file you drop in models/vae_approx), encodes the frames into an animated WebP, and pushes that image to the front end over a WebSocket so the companion JS can paint it directly on the node. That's the whole feature: a fast, approximate, on-node video preview.
The word "approx" is doing real work. A tiny VAE decoder is a distillation of the real one - it's fast and it gets the composition and motion right, but it is not color-accurate or detail-accurate. Preview frames are for judging whether the shot moves the way you asked, whether the seam blends, whether the character still looks like themselves. Do not grade your final output on a taeh3 preview.
The node is also a thin wrapper over a reusable API - decode_h3_video_frames() and frames_to_animated_webp() - which is why the wrapper itself is flagged as experimental upstream. H3 latents are nested tensors, video and audio in one object (24-channel video, 32-channel audio), and the decoder has to pick the video member out. It also understands the .h3latent files this pack writes, plus regular ComfyUI latent files.
Inputs you'll actually touch
There is exactly one important decision: where the latent comes from. The latent input takes priority and is what you want - wire it straight off MMH3 Temporal Extend Video. latent_file is the fallback when nothing is wired, and it resolves like Load Latent does: an absolute path, or a filename relative to your ComfyUI input directory. It reads .safetensors, the pack's own .h3latent, and torch-pickled latents.
Then the preview knobs: approx_vae (a combo listing whatever is in models/vae_approx; it auto-picks the first taeh3* entry, so you usually leave it), max_frames (0 = every decoded frame, otherwise a uniform sample - reach for this when previewing a long merged timeline), max_resolution (longest-side cap, shrinks the WebP), and fps (playback rate only, default 12; it does not touch the latent).
device and cpu_threads are for benchmarking more than anything: cpu forces the preview onto CPU so you can compare decode speed, and the comment in the source is worth repeating - ComfyUI leaves PyTorch's thread count low, so a CPU decode otherwise crawls along near single-threaded. cpu_threads: 0 means all cores.
There is one output: info, a STRING like 124 frames @ 768x768 (12 fps) on cuda, 3.42s. That's it.
Where it goes, and what it can't do
Wire merged_latent from the Extend Video node in if you want to check the assembled timeline, or segment_latent if you only want to look at the piece that just ran. Point latent_file at a stored .h3latent when you don't want to re-run anything.
Here's the trap: there is no IMAGE output. The preview is deliberately pushed to the UI instead of returned as a tensor, so you cannot feed this node into Save Image, CreateVideo, or anything else. If you need a real video file, decode the latent with the full H3 video VAE and go through the normal decode path.
Install
ComfyUI Manager → search Comfyui-MMH3-UltimateExtend → install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bbaudio-2025/Comfyui-MMH3-UltimateExtend
No pip step - the pack declares no dependencies and imports only torch, PIL and safetensors out of the ComfyUI environment itself. You do need a ComfyUI recent enough to ship H3 (comfy.ldm.minimax, comfy_extras/nodes_minimax_h3.py) and the new comfy_api.latest node schema. Then get taeh3.safetensors into ComfyUI/models/vae_approx/ - the pack does not ship or download it, and without it there is no preview.
When it misbehaves
The node is unusually well-behaved about failure: it catches decode errors, sends the error text to the UI, and puts preview failed [RuntimeError]: ... in the info string instead of killing your run. So if the preview area stays blank, read the info output and the console warning, which carries the full traceback.
The usual cause is a missing or mis-named tiny VAE - the error spells it out and tells you to put taeh3.safetensors in models/vae_approx. If you fed it a path, FileNotFoundError means the path didn't resolve; latent paths go through the same folder list Load Latent uses. And if you connect something that isn't an H3 latent, you'll get a TypeError naming the type it received.
One related note from wider video modelling: when a model rebuilds its VAE and latent space, preview decoders for the old space stop working - exactly what happened to the LTX TinyVAE preview when LTX-2.3 shipped. If H3 ever revisions its VAE, expect to need a matching taeh3 file.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| latent_file | STRING | Path or filename of a saved H3 latent (.safetensors / .latent). Resolved via folder_paths the same way as Load Latent. Used only when 'latent' is not connected. | |
| approx_vae | COMBO | Tiny H3 VAE decoder from models/vae_approx (e.g. taeh3.safetensors). | |
| device | COMBO | auto | Decode device. 'auto' uses ComfyUI's default VAE device (CUDA if available); 'cuda'/'cpu' force that device for the preview (for benchmarking CPU speed). |
| cpu_threads | INT | 0 | CPU threads when device=cpu. 0 = all cores (8C16T -> 16). Ignored on cuda. Tune to compare CPU decode speed. |
| max_frames | INT | 0 | 0 = every decoded frame; else uniformly sample this many frames for the preview. |
| max_resolution | INT | 0 | Longest-side pixel cap (0 = keep native). Shrinks the preview WebP. |
| fps | INT | 12 | Preview playback frames-per-second for the animated WebP. |
| latentopt | LATENT | In-memory H3 latent (e.g. from a Latent loader / VAE Encode / the Extend Video node). Takes priority over latent_file. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| info | STRING | Text summary of the decoded preview: frame count, dimensions, fps. |