Sign In

MiniMax-H3 Multishot — Seamless Chain: multi-shot scenes that render as one continuous take (picture + audio)

Download

1 variant available

Archive Other

MiniMax-H3_Seamless_Chain_v2.2.4.zip

3.7 MB

Verified:

Type
Workflows
Stats

239

Reviews
Published

Aug 15, 2026

Base Model

MiniMax H3

Hash
AutoV2
F0452D0AF7
default creator card background decoration
Followers - 128

128

Likes - 410

410

Bronze Base model Badge

MiniMax H3 is licensed by MiniMax under the MiniMax H3 Community License Agreement. That agreement’s Applicable Territory excludes the European Union, the United Kingdom, the Republic of Korea and the United States of America. Your use of H3 and of any H3 derivative is subject to that agreement and its Acceptable Use Policy.

MiniMax H3

Support

Everything here is free and stays free — the format spec, the nodes, the workflows, the cartridges, the LoRAs. If it saved you a night of debugging (it contains several hundred of mine), tips keep the 5090 warm:

What is new in 2.2.3

Long chains finish now. Three separate faults could waste a long render after every expensive stage had already succeeded — sampled, upscaled, normalised, and then nothing written. All three are closed.

  • A host-RAM ceiling. The finished timeline was assembled by allocating a second complete copy of itself. Six shots of 243 frames upscaled needed ~70 GB of system RAM at the final step and died on any 64 GB machine. Now ~21 GB. Twelve shots of 192 frames: ~58 GB down to ~31 GB.

  • An activation reserve that inflated its own estimate. If your chains got slower shot by shot until they crawled, this was why — the measurement counted offloaded weights as free activation space, and each overestimate made the next one worse.

  • Two switches that did nothing. sol_attn and chunk_ffn shipped ON while the nodes they gate ship bypassed. Reported by sdktertiaire2.

Every one of these was found by someone running the pack rather than by me testing it, which is worth saying plainly. 2.2.1 and 2.2.2 — three crashes on long or high-resolution chains, and reference renders forcing glasses onto people — came the same way. The version notes carry the detail.

Which DiT to run

If you are on ComfyUI 0.32 or newer, the comfy-native w4a8 build is the one to use. It is 12.5 GB against Q5_1's 21 GB and measured 27% faster at matched shape and seed — independently, on a 5090 and on a 3090. It also loads through ComfyUI's own path rather than the GGUF loader, and needs no custom node to load. On ComfyUI 0.30 it will not load at all (that format did not exist yet); use a GGUF there, or update.

Write a scene. Get one continuous take back - picture and audio, no visible cuts, no colour shift between shots, and faces that hold without supplying a single reference image.

MiniMax-H3 generates blocks of roughly 10-15 seconds. This pack chains them into a scene of any length and joins them so the result reads as one unedited camera take rather than a cut sequence. One script in, one master video out, with a matching audio file.

Two independent video-understanding models were shown a four-shot chain blind, with no context. Both described it as one continuous unedited take - no cuts, colour consistent, audio unbroken.

What is new in 2.2

Everything since 2.1.2, which is where most people still are. Seven point releases folded into one version: five separate defects that stopped the workflow running, a measured campaign against drift over long chains that changed the shipped defaults, and a whole ComfyUI version this pack could not previously run on.

Five things that stopped it running

  • the Audio Spine produced static on ComfyUI 0.32.0 - that version scales the audio half of the packed latent onto the video schedule, and everything this pack injects was in the stream's native domain, so it landed four times too small and decoded as noise. Three injection sites, not one.

  • naming an mmproj file broke GGUF text encoders - the explicit path skipped the vision key-renaming step, so the tower loaded under names nothing downstream reads. The bitter part: that setting is documented as the escape hatch for when automatic pairing fails.

  • The value 1 for reference_image_size is not available - saved widget values written against an older layout, reading two slots early.

  • the full workflow needed a node from a pack that is not in the zip. A node whose class is missing fails the entire prompt, so without ComfyUI-Custom-Scripts the graph could not be queued at all - for the sake of an on-canvas text box.

  • H3_Seamless_Chain_CORE could not be queued at all, since 2.1.3. Its sampler still carried the widget array from before four dials were removed, so output_scale received false against a minimum of 1.0. The workflow advertised as the one with no third-party dependencies was the one that could not run - and it survived because nobody had ever rendered it. All three bundled workflows are now submit-tested against a running server as part of the release routine, and CORE has rendered: three chained shots, 370 frames, picture and audio.

Drift over long chains, measured

Chained shots accrete detail: each one conditions on the previous shot's own output, so invented texture compounds. Measured over ten shots at 960x544, the memory bank's recency slots turned out to be the carrier, and turning them off is strictly better - texture drift per hop 1.055 to 1.022, chroma 1.086 to 1.039, framing correlation at shot ten 0.976 to 0.995. The important part is that at the old default the drift accelerated, which is what a runaway feedback loop looks like, and at the new one it holds flat. Motion continuity was the obvious worry, since carrying it is what those slots are for; tested on a scene with continuous large-amplitude movement, anchor-only retained motion slightly better. So memory_frames now ships at 0.

Two more defaults changed with it. master_normalize gains a luma+contrast mode, because matching only the mean masks a contrast ratchet compounding underneath it, and pin_renorm holds each pinned latent at shot one's sigma rather than letting the pin's own sigma climb every hop. New dials: pin_frames, pin_noise, pin_renorm. Residual drift is about 1.02 per hop - not zero, and said plainly.

join_anchor_noise and handoff_release now ship at 0 because they are inert under context_pin: one noises keyframes the mode never creates, the other belongs to a different continuity mode. A non-zero value on a dead control reads as a tuned setting.

ComfyUI 0.32.0

Supported, and it needed real work rather than a version bump - see the Audio Spine fix above. 0.30.0 is unchanged and still supported, and 0.33.1 is now in production use on a second machine - a user has confirmed 0.30.0 on Ubuntu as well. Both are now tested before a release goes out, because three of the last four user reports were things that only appear on a runtime that was not being tested.

Bypassed nodes now say what they need

Four nodes ship bypassed because their packs are not in the zip. That is the right default - a bypassed node is dropped from the prompt entirely, so the graph queues without them - but a bypassed node sitting on the canvas invites you to un-bypass it, and doing that without the pack installed breaks the workflow with no explanation. The group title, each node's own title, a note above the cluster and the VRAM / SPEED note now all say which pack each one needs. The part people lose: it takes two steps in order - install the pack, Ctrl+B to un-bypass, then turn its switch on. Neither step works alone.

What is new in 2.0 and 2.1

Seamless joins, by a different mechanism

Earlier versions chained by handing the next shot the previous shot's last frame. That still works and is still here. 2.0 adds context_pin: the previous shot's last 22 frames ride into the next shot as raw latents - bit-identical, never decoded to pixels and re-encoded - placed at interior keyframe coordinates, alongside a timeline-placed audio reference. The regenerated head is trimmed on decode. Colour, motion and voice cross the join as data rather than as a description.

Seam audio that does not clip words

The boundary audio cut used to land blindly at the start of the incoming shot, which shaved the attack off any word the model placed there. It now lands in the quietest gap inside the shot's first 0.75 seconds, then welds with a 40 ms equal-power crossfade. A line that begins early survives.

A VRAM and speed panel

Try a render with every switch off and the reserve at 0 before touching any of this. That is the verified recipe, and in practice the fastest route to a working chain - the activation reserve measures each shape and conditioning payload as it renders and sizes the pool itself, and it holds on 24 GB cards as well as 32 GB. These switches exist to dig out of a spill the console has already named, not for pre-emptive tuning.

One panel with three lazily gated model patches - memory-efficient attention, chunked feed-forward, and a block cache - plus an activation-reserve control. Every switch off reproduces the shipped recipe exactly, and an off gate means the patch node never executes at all.

An activation reserve that understands payload

Memory measurements are now keyed by shape and conditioning payload, so a bare first shot and a reference-laden later shot no longer share one estimate. A measured pool is no longer overridden by a fixed floor, an unseen payload variant estimates from a measured sibling, and - the important part - a spill into system RAM is detected and named in the console instead of presenting as an unexplained five-times slowdown.

Boundary rules the prompt writer applies for you

The LLM prompt writer gained a join_style control. Set it to a chained style and the render-verified join rules are appended to its system prompt automatically, so generated scripts obey them without you memorising anything.

How identity holds with no reference images

This is the part most people do not expect. A 40-second two-character scene held both faces across every shot with zero reference images supplied. Two mechanisms do it, and neither works alone.

  • The frame relay carries the instance. Every shot begins from an actual rendered picture of the character - the previous shot's last frame - so the specific face, the wardrobe weathering, the exact hair propagate as pixels rather than being re-imagined from text. Drift can only accumulate per join, not per frame.

  • Verbatim text carries the category. Repeating each character's appearance description word-for-word in every shot re-asserts everything a picture cannot pin down, and authors anyone who walks into frame partway through. Once they are in a handed-over frame, they join the relay too.

Reference images and the identity bank are still there for long chains, characters who leave frame for a long stretch, or when you need a specific pre-existing face - they are just no longer the price of entry.

Voice identity across the chain

Chained shots used to re-perform the voice from text each time, and it drifted. Two controls end that, and the shipped default turns one of them on:

  • voice_ref - feed a clean solo speech clip and it anchors every shot as <Audio 1>. Mono clips, sample rate and length are all guarded internally.

  • self_anchor_voice - no file at all. Shot 1's own rendered voice becomes the reference for every later shot. Write shot 1 so the character speaks a clean solo line.

Both ride the checkpoint's reference rows, so they need ref2va. On fl2va they do nothing except cost tokens - see the checkpoint note below.

Which workflow

Three, each with one clear reason to exist.

  • H3_Seamless_Chain_v2 - everything. Master controls, the LLM writer, VRAM panel, identity and voice anchors, an episode/batch prompt source, FFLF boundary plates and an audio spine. The optional lanes ship gated off, so the default path stays simple.

  • H3_Seamless_Chain_CORE - the same job with zero third-party packs. Type your shots into the script box and queue. Start here if you want a render before installing anything else.

  • H3_Keyframes - a different job: a hand-built sampling graph for anchoring a single clip at chosen frame positions with per-anchor condition strength. Not multishot, does not chain.

v2 supersedes the older H3_Multishot_AIO and H3_Multishot_MEMORY graphs - every lane they had is in v2. If you have them open from a previous version they still work; there is simply no longer a reason to reach for them.

Keyframes at any position

Anchor images are not limited to the first and last frame. The pack can place them at arbitrary positions, with per-anchor condition strength. Two implementations exist for the underlying layout patch - this pack's own, and the one in ComfyUI-H3-Motion-Context - and they patch the same place, so exactly one owns it at a time. If Motion Context is installed it wins (its version is a superset) and this pack stands down with a line in the log. If it is not installed, this pack fills the gap. Either way, first and last anchors always work and you never have to choose.

Master controls, and the dials that matter

One panel drives resolution, frames per shot and steps for the sampler, and also feeds the writer so it paces dialogue to the real shot length. The dials worth knowing:

  • continuity - context_pin (raw-latent join, needs the Motion Context pack), first_frame (the model's own trained hand-off, no extra pack), cut for episodic work, or flf_chain for boundary plates.

  • seed_per_shot - leave it on. Measured: varying the seed per shot holds the face; one seed for every shot drifted both face and voice. Identity lives in the conditioning, not the seed.

  • chain_gain_control - set to flatten past about five shots. Each shot's tail anchors the next and the model returns roughly 1.3x the anchor's texture energy, so sharpness ratchets across a long chain with a visible step at every seam.

  • output_scale / upscale_model - upscaling happens after decode, per shot, so it works with every continuity mode including context_pin, and a long chain never holds a full upscaled master in memory at once. output_scale is a lanczos resize (measured 1.78x faster than rendering the same output size natively, and visibly softer - resolution, not detail); upscale_model takes ComfyUI's own Load Upscale Model (ESRGAN and friends) for synthesized detail. The old two_pass_upscale is gone - it interpolated the raw latent between passes and produced colour noise in every configuration tested.

  • master_normalize - leave it at luma+contrast. It levels both the brightness AND the contrast of the finished chain against one global target taken from shot 1. Chained shots drift brighter-edged every hop; matching only the mean re-centres that and hands the next shot a higher-contrast start. Measured: texture growth per hop 1.126 -> 1.047 at 960x544 and 1.130 -> 1.055 at 640x352, with contrast spread across shots falling from ~11% to under 0.5%. It runs on decoded frames against per-frame statistics, so there is nothing to tune per resolution.

  • pin_noise - small and scene-dependent, not the anti-ratchet answer it was billed as in 2.1.5. Measured -1.8% per hop at 640x352 and -0.9% at 960x544 on a detail-heavy scene, and it gets worse above 0.10. Leave it at 0.05 or set 0; either way the contrast pass above is what does the work.

  • memory_frames - leave it at 0. The bank's RECENT slots hand each shot's accreted output forward as reference images on top of the pin, so invented detail compounds. Ten shots at 960x544, 2 -> 0: texture 1.055 -> 1.022 per hop, chroma 1.086 -> 1.039, framing at shot 10 0.976 -> 0.995, and the drift stops accelerating. Tested on a moving scene too - motion continuity did not suffer. Raise to 1 only if a busy scene loses continuity between shots.

  • pin_frames - leave it at 22. Longer pins also cut the sharpening, but the head trim scales with them, so 39 frames of audio get cut per join and speech planned under the replay gets clipped.

  • Audio drifts the other way: chained audio gets duller per hop where chained video used to get sharper (measured 8-50% of 4-10 kHz energy lost over 8 shots, seed-dependent). There is no per-shot dial for it - the per-shot correctors were removed in 2.1.3 because they cannot reach the raw-latent pin that carries the drift. For cut-grammar content it can be avoided outright: continuity=cut with bank_pinned=1, memory_frames=0 conditions every shot's audio on shot 1 alone - measured flat.

  • preview_first_shot - writes shot 1 the moment it decodes, so a bad take can be cancelled before the whole chain renders.

Which checkpoint

ref2va ships as the default: it carries the reference rows that voice anchoring and the identity bank need. fl2va is lighter and faster, has no reference rows, and chains just as well - the voice rides the frame relay instead of being pinned. Blind review passed on the fl2va configuration; ref2va ships as default because it makes identity explicit rather than emergent.

Writing a script

One prompt per shot, --- on its own line between them. The mechanics of a join are handled for you; whether the join reads as invisible is decided by the writing. These rules were each written after a specific failure:

  • The airlock. Every shot after the first opens holding the previous shot's exact closing arrangement, with about two quiet seconds before anyone speaks. The head of a chained shot is discarded on decode - anything you put there is thrown away.

  • Give the hold something to do. A held framing with nothing happening renders as a literal freeze. Write in a breath, a weight shift, an eyeline change.

  • Land settled. End each shot back in a stable arrangement, dialogue finished, about two seconds spare.

  • A line never straddles two shots. Budget it: dialogue at natural pace plus four seconds of quiet must fit. At 362 frames (~15.1s) that is roughly 27 words; at 243 frames (~10.1s), roughly 15.

  • Repeat the descriptions word-for-word. Each character's appearance and the room and lighting, identical in every shot. Rewording between shots is the single most common cause of a face changing mid-scene.

Camera cuts inside a shot are free and share one audio bed - so put cuts inside shots, and continuity between them. A worked four-shot two-hander ships as example_script.txt.

Quick fixes

  • A word clips at a join - the script put dialogue too close to a boundary. Move the whole line, do not split it.

  • Sharpening increases every shot - the texture ratchet. Set chain_gain_control to flatten.

  • A render stalls at 0 steps, or runs several times slower than usual - the activation reserve is too small and the driver is paging to system RAM. Raise the VRAM reserve (roughly 20 on a 24 GB card), drop resolution or frames, or remove reference payload. The console now names this when it happens.

  • LLM API error 404, model not found - the writer's model_name is not pulled on the endpoint it is pointed at. See the prompt-writer section above.

  • Red or missing nodes - an optional pack is not installed. The four optional nodes already ship bypassed, so this only bites if you un-bypassed one: re-bypass it with Ctrl+B, delete it, or use the CORE workflow.

  • A render crawls, GPU pinned at 100% but drawing a fraction of its usual power - the weights and the activation pool together do not fit, and the shortfall spills to system RAM rather than raising an error. The console names the clamp when it happens: if the reserve was clamped below the measured pool, that render will not finish in reasonable time. Drop frames or resolution, turn the accelerator switches on, or load a smaller quantisation of the DiT - a 4-bit checkpoint frees several GB for activations, which is usually the whole difference.

  • GGUF architecture error - the pack teaches ComfyUI-GGUF the minimax_h3 architecture at startup, so installing it is normally the whole fix. If the error persists, run python apply_gguf_arch_patch.py from the pack folder once and restart.

  • Audio dulls on a very long chain - expected; restart the chain on a scene cut, where a fresh start costs nothing.

The prompt writer needs a model you actually have

The full workflow ships pointed at a local Ollama with model_name = qwen3:14b. Pull it before the first queue or the run stops immediately with LLM API error 404: model 'qwen3:14b' not found:

ollama pull qwen3:14b

Any OpenAI-compatible endpoint works - put its URL in base_url and the exact tag in model_name; ollama list prints the tags you have and it must match character for character. A remote or hosted endpoint is often the better choice, because a local writer large enough to be good competes with H3 for the same card and on under 32 GB will evict the model mid-render.

Running the writer locally? Turn on unload_model_after on the writer node. It frees that model from Ollama the moment the script is written, so the video model gets the card - otherwise it sits for the server default of five minutes, which is your whole first shot. ComfyUI's own eviction cannot reach it (separate process), and Ollama's OpenAI-compatible endpoint has no keep_alive field to ask with; the switch uses the native endpoint. It is added to the writer at runtime by this pack, and is off by default.

Want no LLM at all? Set the master panel's use_file_prompts to manual entry, delete the writer, and feed your own shot script straight into the sampler's script input - one prompt per shot, separated by --- lines. The CORE workflow already works this way.

Requirements

Always: ComfyUI v0.30.0 through v0.33.1 - tested at three points (0.30.0 on Ubuntu by a user, 0.32.0 here, 0.33.1 in production on a second box) and supported across the range (native MiniMax-H3 support), this node pack, a MiniMax-H3 checkpoint, the H3 text encoder, and the video and audio VAEs. The CORE workflow needs nothing else - it is built from this pack plus stock ComfyUI nodes.

For the FULL workflow. ComfyUI validates every node class in a graph before it will queue, so a missing pack stops the whole workflow - not just its own feature. Each can be removed instead; INSTALL.md gives the one-widget change or node deletion for every entry.

  • ComfyUI_JoyAI_Echo_GGUF_Nodes - the LLM prompt writer (JoyEcho_LLMEnhance). It is inside the release zip - copy it into custom_nodes/ with the main pack. It is RealRebelAI's pack, modified with attribution (the NOTICE inside lists every change); use that copy, not upstream - the workflow drives inputs the upstream release does not have, and with upstream those values are dropped silently. Hand-written scripts can delete the writer instead.

  • ComfyUI-H3-Motion-Context - continuity = context_pin, the shipped default, plus interior keyframe anchors. Removal: continuity = first_frame.

  • RES4LYF - the beta57 scheduler the full workflow ships with. Removal: scheduler = beta (measured cost: lip-sync 8/10 vs 10/10, everything else equal; CORE ships beta already).

  • ComfyUI-sol-attn and comfyui-minimax-h3-blockcache-T8 - the VRAM/SPEED patch switches. The switches ship OFF and the nodes ship bypassed, so the graph queues whether or not you have either pack - a bypassed node is dropped from the prompt entirely. To use one: install its pack, restart, Ctrl+B the node to un-bypass it, then turn its switch on. Both steps, in that order - neither works alone.

  • ComfyUI-Custom-Scripts - the in-canvas script preview, a leaf node; removal: delete it.

  • ComfyUI-GGUF - quantised checkpoints and encoders.

Models

GGUF quants of the H3 checkpoint are at huggingface.co/joeygambino/MiniMax-H3-GGUF - Q8_0 for 32 GB, Q5_1 for 24-32 GB, Q4_0 for 16 GB. The text encoder and both VAEs are at huggingface.co/Comfy-Org/MiniMax-H3. GGUF encoder quants are at huggingface.co/joeygambino/MiniMax-H3-encoder-GGUF; keep the -mmproj vision sidecar, and load it with this pack's H3 CLIP Loader (safetensors + GGUF) rather than the stock GGUF loader - the vision path is what carries frames between shots.

ComfyUI-GGUF pairs that sidecar by filename, looking only in the encoder's own folder. Rename either file or separate them and the match fails; upstream logs an error and then carries on without the vision tower, which looks like the model ignoring your reference image. This pack's loader raises instead of continuing blind, falls back to the only mmproj beside the encoder when there is exactly one, and gives you an mmproj_name widget to name the file outright - with that set, filenames and folders stop mattering.

What is verified, and what is not

Stated plainly, because a release note is a claim.

  • Verified: chained renders reviewed blind by two independent models and reported as one continuous take with consistent colour and unbroken audio; holding on both a static talking head and dynamic moving content; a 40-second two-character scene holding both faces with no reference images.

  • Verified since: all three bundled workflows submit-tested against a running server on ComfyUI 0.30.0 and 0.32.0, with 0.33.1 in production use on a second box; the full workflow rendered end to end from the shipped file on 0.32.0 through both of its script lanes, and read by a blind reviewer as one continuous static take with no cut findable anywhere, correct lip-sync, no drift in framing or colour and clean audio; CORE rendered for the first time at 370 frames.

  • Not verified: the shipped ref2va default is the same chaining mechanism with reference rows added, but blind review ran on the lighter fl2va path. Very long chains dull the audio slightly per hop. flf_chain has not been rendered against a fully colour-matched plate set.

Credits

The context_pin join and interior keyframe anchoring build on ComfyUI-H3-Motion-Context by NikoDemon80. The script preview uses ComfyUI-Custom-Scripts by pythongosssss. GGUF loading builds on ComfyUI-GGUF by city96. Thanks to @viralesveras for contributions to earlier versions.

Free, and it stays free. If it saved you time: Ko-fi · GitHub Sponsors · Liberapay.