MiniMax H3 One-Take Sampler (TJ)
The whole H3 pipeline, and the long-video trick, in one node
- model
- clip
- vae
- audio_vae
- first_frame
- last_frame
- ref_images
- ref_video_1
- ref_video_2
- ref_video_3
- ref_video_audio_1
- ref_video_audio_2
- ref_video_audio_3
- ref_audio_1
- ref_audio_2
- ref_audio_3
- audio_lock_source
- images
- audio
- fps
- total_frame
- report
Normally, generating MiniMax H3 video in ComfyUI means wiring RandomNoise → BasicGuider → KSamplerSelect → BasicScheduler → SamplerCustomAdvanced → VAEDecode → VAEDecodeAudio, plus a separate conditioning node and, if you want long video, a whole continuation rig. That's eight-plus nodes and a pile of fiddly choices per generation. MiniMax H3 One-Take Sampler (TJ) is the "fine, one node then" answer: it wraps the entire pipeline - conditioning, sampling, decoding, and the latent checkpoint save/load that makes multi-clip long video work - behind a single node. Canvas input, canvas output, done.
The sampler chain inside is a faithful reproduction of ComfyUI's official SamplerCustomAdvanced logic - the same Noise_RandomNoise and Guider_Basic from comfy_extras. Nothing exotic, just pre-wired. Anything you'd patch onto the model - SageAttention, the H3 cache, SigmaShift - you apply upstream and hand it in via model; the node doesn't care what you did, it just takes the finished MODEL.
The inputs worth your attention (there are many, and most you can leave alone):
mode- Text / First-Last / Reference, same three as the Sequencer. The matching reference inputs (first_frame,last_frame,ref_images,ref_video_1..3with their audios,ref_audio_1..3) appear in the optional set.duration- seconds, not frames. Internally it converts to 24fps and rounds up to H3's 17k+5 frame grid; the real count comes back ontotal_frame. Default 5.17s = 124 frames.prompt- plain text for the H3 encoder.sampler_name/scheduler- defaulter_sde/normal. These are the full ComfyUI tables, so you can reach for the RES4LYF-era samplers too.steps,denoise,seed- standard.denoisebelow 1 splits steps the usual way.audio_lock- flips on the built-in audio locking (lock/remix/strength/fit +audio_lock_source), same merged-mask logic as the Sequencer.one_take- the long-video switch. With it on, each clip's sampled latent is saved to disk after sampling, and the next clip starts by loading the previous tail back in.index(from the Prompt Queue node) tells it clip 1 from clip 2;checkpoint_nameis the internal filename for the handoff.tile_decode- when VRAM is tight, decode in tiles (tile_size,overlap,temporal_size,temporal_overlap). Video only; audio always decodes whole.
Outputs: images (decoded video frames), audio (decoded audio), fps, total_frame, and report - a STRING that logs exactly what each clip did (checkpoint load/save, masks, decode mode). It's an output node, so it also counts as a render target in the queue.
The "One-Take" mechanism is the reason to pick this over hand-wiring. H3 can't hold tensors between separate queue submissions - a relay workflow unloads the model to free VRAM each clip - so the previous clip's latent has to survive on disk. This node saves it as a .h3lat.safetensors after each clip and loads it at the start of the next, feeding the tail (39 frames of overlap, 1.625s) into the head of the new clip with a noise_mask=0 so the sampler preserves rather than regenerates it. No VAE round-trip, no forced FL2VA switch, no motion loss at the seam. It also means "stop and resume the shoot later" works for free - the checkpoints are on disk.
Install
Part of ComfyUI-TJ_NODE:
cd ComfyUI/custom_nodes
git clone https://github.com/designloves2/ComfyUI-TJ_NODE
or via Manager, then restart. No extra Python deps for this node - but it needs ComfyUI recent enough to ship comfy_extras.nodes_minimax_h3, the H3 weights (~42.5GB), the H3 VAE and audio VAE, and a GPU big enough to breathe. Remember the license: the MiniMax H3 Community License excludes the US, EU, UK and South Korea from the local-weights path.
Troubleshooting
- Resolution mismatch error on clip 2 - One-Take requires identical
width/heightacross the whole sequence. Delete the leftover checkpoint and restart from clip 1. - It re-runs every time even with the same inputs - by design: the checkpoint file changes outside the graph (written by the previous run), so the node forces itself to re-run rather than serve a stale cache. Slower to skip, correct to run.
- First clip silently missing the checkpoint - correct behavior:
index<=1treats a missing file as "start fresh." Missing on clip 2+ is the real error. - OOM on long clips - enable
tile_decodeand shrinktile_size/temporal_size, or lower resolution. This is a heavy model; decode is often where the card gives up.
Inputs (40)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | SageAttention/Cache/SigmaShift/Model Preview Override 등 모델 패치는 전부 이 입력 앞에서 끝내고 들어와야 합니다. | |
| clip | CLIP | — | |
| vae | VAE | — | |
| audio_vae | VAE | — | |
| prompt | STRING | — | |
| mode | COMBO | Text | 3 options: Text, First-Last, Reference |
| width | INT | 134432–8192 | — |
| height | INT | 76832–8192 | — |
| duration | FLOAT | 5.170.21–150 | 초 단위 길이. 내부적으로 24fps 프레임으로 환산 후 H3의 17k+5 프레임 그리드에 맞춰 올림 정렬됩니다 — 실제 정렬된 프레임 수는 total_frame 출력으로 확인하세요. |
| ref_image_size | COMBO | match | 2 options: match, max |
| audio_lock | BOOLEAN | false | — |
| audio_lock_mode | COMBO | lock | 2 options: lock, remix |
| audio_lock_strength | FLOAT | 0.500–1 | — |
| audio_lock_fit | COMBO | pad_silence | 3 options: pad_silence, loop, stretch_none |
| one_take | BOOLEAN | false | — |
| index | INT | 11–100000 | MiniMax H3 Prompt Queue (TJ)의 index 출력을 연결하세요. One-Take가 켜져 있을 때 1번 클립인지 자동 판단하는 데 씁니다. |
| checkpoint_name | STRING | prev_clip | 클립 간 latent 핸드오프용 내부 파일 이름. 한 루프 안에서는 그대로 두면 됩니다(매 클립 덮어쓰기) — 루프를 여러 개 동시에 돌릴 때만 서로 다르게. |
| sampler_name | COMBO | er_sde | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 |
| scheduler | COMBO | normal | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 |
| steps | INT | 201–10000 | — |
| denoise | FLOAT | 1.000–1 | — |
| seed | INT | 00–18446744073709550000 | — |
| tile_decode | BOOLEAN | false | VRAM이 부족할 때 켜세요 — VAEDecodeTiled 방식으로 나눠서 디코드합니다 (비디오만 해당, 오디오 디코드는 항상 그대로). |
| tile_size | INT | 51264–4096 | — |
| overlap | INT | 640–4096 | — |
| temporal_size | INT | 648–4096 | 비디오 VAE 전용 — 한 번에 디코드할 프레임 수. |
| temporal_overlap | INT | 84–4096 | — |
| first_frameopt | IMAGE | — | |
| last_frameopt | IMAGE | — | |
| ref_imagesopt | IMAGE | — | |
| ref_video_1opt | IMAGE | — | |
| ref_video_2opt | IMAGE | — | |
| ref_video_3opt | IMAGE | — | |
| ref_video_audio_1opt | AUDIO | — | |
| ref_video_audio_2opt | AUDIO | — | |
| ref_video_audio_3opt | AUDIO | — | |
| ref_audio_1opt | AUDIO | — | |
| ref_audio_2opt | AUDIO | — | |
| ref_audio_3opt | AUDIO | — | |
| audio_lock_sourceopt | AUDIO | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| audio | AUDIO | — |
| fps | FLOAT | — |
| total_frame | INT | — |
| report | STRING | — |