Nodes/ComfyUI Silver Nodes/Silver H3 Batch (N videos / encode once / sample once / decode once)
ComfyUI Node

Silver H3 Batch (N videos / encode once / sample once / decode once)

A dozen MiniMax-H3 clips without paying the model-reload tax twelve times

By SilverAndJade·Created about a year ago·Updated a day ago· 0
Silver H3 Batch (N videos / encode once / sample once / decode once)
  • model
  • clip
  • video_vae
  • audio_vae
  • prompts
  • start_image
  • char_refs_all
  • char_refs_index
  • char_audio
  • guide_audio
  • audio
  • saved_videos
  • videos_rendered
width768
height1344
frames_per_shot243
seed0
steps20
sampler_nameres_multistep
schedulersimple
overall_prompt
combine_videosfalse
step_guide_audiofalse
seed_per_shottrue
filename_prefixSilverH3Batch
formatmp4
frame_compression23
apply_diffaidfalse
diffaid_strength0.20
double_passfalse
double_pass_denoise0.25
double_pass_steps8
upscale_factor1.00

Render five clips the stock way and you load the text encoder five times, the DiT five times, the VAE five times. Then the clips come back and you notice the generation wasn't the slow part - the shuffling of tens of gigabytes in and out of VRAM was. SilverH3Batch exists to fix exactly that and nothing else.

It renders N independent MiniMax-H3 videos (video plus the model's native audio, 24 fps) from N prompts, and it keeps the discipline the stock queue can't: the text encoder, the DiT and the VAE each load once for the whole batch. A twelve-clip run costs about two model swaps instead of roughly 3 × 12. For a 33B model with a big text encoder, that's not a small win.

How it works

The node is built as three phases, which you don't drive - it just stops interleaving them per clip:

  • Phase A, ENCODE. Every prompt is text-encoded in one text-encoder session. Your keyframe images and character references are VAE-encoded here too, once, and reused.
  • Phase B, SAMPLE. Every video is sampled back to back while the DiT stays resident. No mid-sampling keyframe decodes, which is why the "no mid-phase swaps" claim actually holds here.
  • Phase C, DECODE. Every latent is decoded in one VAE session. Each clip is written straight to disk as it decodes and then freed, so at most one clip's frames are ever in RAM. That's how a twelve-clip batch fits on a consumer box instead of thrashing.

This node deliberately has no cross-clip continuity. Each prompt is its own short film, joined at hard cuts if you stitch them. If you want one continuous take across N shots, that's the sibling node, Silver H3 Staged Multishot.

The inputs that matter

prompts is a STRING_LIST, one prompt per video, and it's the input beginners fumble - it's a list socket, not a text box. Either wire it from one of the pack's two prompt helpers, or turn the widget into an input and feed it a list. overall_prompt is a plain string prepended to every prompt (overall + shot), which is where the scene-wide description belongs so you're not repeating it five times.

Then the usual shape knobs: width, height, frames_per_shot (243 default, about 10.1s, on H3's 17k+5 grid - the author's own note is that the trained range is roughly 124–362 and beyond that is RoPE-extrapolation territory), plus seed, steps, sampler_name and scheduler.

The interesting optional ones:

  • start_image is an IMAGE batch, and image i opens clip i. Feed N+1 images and you get N clips chained frame-to-frame, because with combine_videos ON, clip i's last frame is automatically taken as image i+1's start - there is no separate end-image input.
  • combine_videos (default OFF) affects saved files only. ON stitches everything into one master in a dated subfolder (clip_01.mp4, clip_02.mp4, … plus _master.mp4); OFF gives you one flat file per clip.
  • char_refs_all rides every clip with stable <Picture N> labels; char_refs_index is positional, image i on clip i; char_audio is one voice shared by all.
  • guide_audio is a spine locked per clip, with step_guide_audio deciding whether every clip reuses the head of the track or each advances to its own slice (auto-ON when combining).
  • double_pass with double_pass_denoise (0.25) and double_pass_steps (8) is a Motion-Director-style refine over each full latent, and upscale_factor resamples the latent before decode - the suggested combo is 1.25x plus a refine pass. apply_diffaid applies the DiffAid sparse patch and hard-errors if that pack isn't installed, so leave it off unless you have it.

Outputs are audio (a list of audio dicts, one per rendered video), saved_videos (newline-separated paths) and videos_rendered.

Install

Manager search for "Silver Nodes", or:

cd ComfyUI/custom_nodes
git clone https://github.com/SilverAndJade/comfyui-silver-nodes

Restart ComfyUI. The pack's requirements.txt covers the older loader nodes (beautifulsoup4, moviepy, a pinned opencv-python==4.10.0.82 for NumPy compatibility) - the H3 nodes ride on ComfyUI's own PyAV and comfy_api.latest, so you need a reasonably current ComfyUI. And you need H3 weights: roughly 42.5GB, under the MiniMax H3 Community License, which excludes the US, EU, UK and South Korea from its applicable territory. If you're in one of those, the licence says the local weights aren't yours to run.

The repo ships SilverH3Batch_Turbo_3x10s.json and SilverFolderBatch_ToH3Batch.json - drag one in and read the wiring before building from scratch. Start with two or three prompts, not twelve.

Where people get burned

Keyframes and character refs are mutually exclusive. When refs are set, H3's cond_video_latents is replaced by the ref latents and the keyframes are wiped, so the node drops your refs with a warning if start_image is connected. An I2V clip cannot carry identity refs; a ref-driven clip cannot key its opening frame.

Don't trust a render count that looks short. videos_rendered is your prompts-list length, and blank entries are skipped - a stray empty line gives you fewer clips and no error to explain it.

Categorysilver_nodes/sampling

Inputs (30)

NameTypeDefaultDescription
modelMODEL
clipCLIP
video_vaeVAE
audio_vaeVAE
promptsSTRING_LISTA single LIST of prompt strings - one per video (e.g. the output of the Silver H3 Prompts Builder). Every prompt is text-encoded in ONE text-encoder session before any sampling starts, so the text encoder loads once for the whole batch. Empty entries are skipped.
widthINT76832–4096
heightINT134432–4096
frames_per_shotINT24339–1450Frames at 24fps on H3's 17k+5 grid (243 = ~10.1s per clip). Trained range is ~124-362; beyond is RoPE-extrapolation territory.
seedINT00–18446744073709550000
stepsINT201–50
sampler_nameCOMBOres_multistep44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38
schedulerCOMBOsimple9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3
overall_promptoptSTRINGOptional SCENE-WIDE prompt prepended to EVERY video's prompt before encoding (overall + shot).
start_imageoptIMAGEOptional FIRST FRAME (I2V). IMAGE batch: image i opens clip i, so N+1 images chain N clips frame-to-frame. A single image is reused as every clip's frame-0 keyframe. Encoded ONCE per unique image and applied via H3's native first/last keyframe channel. Requires an fl2v-capable model. When combine_videos is ON, clip i's LAST frame is auto-taken as image i+1 (so the next clip's start frame closes this clip) - no separate end input.
combine_videosoptBOOLEANfalseSAVED FILES only. ON = stitch every clip into ONE master video (full guide audio over the whole stitch when a guide_audio is supplied, else per-clip audio crossfaded at the seams) saved into a DATED subfolder prefix_yyyymmddHHMMSS/ as clip_01.mp4, clip_02...plus _master.mp4 - so the clips are on disk for manual re-combining. OFF (default) = save one flat file per clip, the original behaviour. Streamed: only one clip is ever in RAM, so long batches fit a small system.
char_refs_alloptIMAGEOptional CHARACTER REFERENCE list: EVERY image here rides EVERY clip (<Picture N> labels stay stable across the whole batch). 1..k images, one per reference (character, prop, location...). Each is encoded ONCE - a DiT-side image ref row plus <Picture N> vision tokens: outfit/face carry with no temporal claim, so it never fights the start keyframes. Combined with char_refs_index (deduped) when both ride. Mutually exclusive with start_image (refs are DROPPED, with a warning, if start_image is given).
char_refs_indexoptIMAGEOptional CHARACTER REFERENCE list INDEXED BY CLIP: image i is ridden by CLIP i (a list shorter than the prompts reuses its last image for the remaining clips). When combine_videos is ON with a batch, clip i also receives image i+1 so zoom/pose transitions read as continuous. Each clip references a DIFFERENT <Picture N>, so the labels shift per clip. Leave unconnected to disable indexed refs (see char_refs_all for refs on every clip).
char_audiooptAUDIOOptional CHARACTER VOICE REFERENCE (ref2va). ONE voice, ridden by EVERY clip as a DiT-side audio ref row plus <Audio N> tokens - voice/style identity with no timing claim, so it never fights guide_audio (the driving spine) or the generated speech. Encoded once in the ENCODE phase. Single track only (the first audio is used if a batch is supplied). Any sample rate; mono is upmixed. Dropped with a warning when start_image rides.
guide_audiooptAUDIOOptional AUDIO SPINE for the WHOLE batch: a continuous track (voice, music, ...) encoded ONCE in the ENCODE phase. Each video's audio stream is locked to a slice of it at every sampling step so the clip follows the audio. With step_guide_audio OFF every video uses the track's HEAD (first clip-length); with it ON each video advances to the next clip-length slice.
step_guide_audiooptBOOLEANfalseOnly used when guide_audio is set. OFF = every video locks to the first clip-length of the guide (so all 5 reuse the opening 5s). ON = video i locks to guide audio seconds [i*clip, (i+1)*clip], so each clip gets its own slice. NOTE: stepping is AUTO-ENABLED whenever combine_videos is ON - combining implies a continuous long-form take, so each clip must advance through the spine.
seed_per_shotoptBOOLEANtrueVarying the seed per video gives each clip its own take; off reuses one seed for all rendered videos.
filename_prefixoptSTRINGSilverH3BatchOutput filename prefix for the saved videos.
formatoptCOMBOmp42 options: mp4, auto
frame_compressionoptFLOAT230–32Constant Rate Factor (CRF) - H.264 quality knob for the saved video. 0 = lossless (huge file), 23 = visually clean (default), 32 = smallest file. Lower = higher quality / larger file, higher = lower quality / smaller file. Range 0-32 is the useful span; above ~30 quality drops noticeably.
apply_diffaidoptBOOLEANfalseApplies the ComfyUI-DiffAid-Patches MiniMax H3 sparse patch (the diffaid-patches custom node must be installed) to the model BEFORE sampling. The patch clones the model once and is shared by every video (one clone, applied in Phase A, so the DiT still loads once). Raises a hard error if the diffaid-patches node is missing.
diffaid_strengthoptFLOAT0.20-1–1Diff-Aid strength (the sparse patch's strength parameter). 0.20 is the node/paper default; stronger = harder conditioning focus on the patched blocks.
double_passoptBOOLEANfalseSecond sampling pass over the FULL latent at a reduced denoise (Motion-Director style refine). Re-sampling from the already-sampled latent with only the bottom of the sigma schedule regenerates fine detail and cleans up the image. Costs one extra DiT sample per video (n extra total).
double_pass_denoiseoptFLOAT0.250.01–1How much of the first-pass latent is re-noised for the refine pass. 0.25 = only the bottom 25% of the sigma schedule - a light refine that keeps composition, 0.5+ visibly rewrites it, 1.0 = a full re-roll of that clip.
double_pass_stepsoptINT81–50Sampling steps for the refine pass. 8 is plenty for a 0.25-denoise refine; raise only when denoise is pushed higher or quality demands it.
upscale_factoroptFLOAT1.001–2Spatial latent upscale applied to every video BEFORE decoding: the video latent is trilinearly resampled to this factor BEFORE any double_pass refine (recommended combo: upscale 1.25x + double_pass to fill the new detail). 1.0 = native resolution. The upscaled latent is decoded at the larger size; audio is unaffected. The refine pass's VRAM cost scales with the upscaled area.

Outputs (3)

NameTypeDescription
audioAUDIO_LISTList of audio dicts, one per rendered video: [{video1 audio}, {video2 audio}, ...] (each is {'waveform','sample_rate'}); None for silent clips.
saved_videosSTRINGNewline-separated paths of the saved video files (one per clip). When combine_videos is ON, the clips are saved into a dated subfolder SilverH3Batch_yyyymmddHHMMSS/ alongside a _master.mp4, so you can re-combine them manually if needed.
videos_renderedINTHow many videos actually rendered (one per entry in the prompts list).