JR H3 Streaming Sampler (Experimental)
Refine a long MiniMax H3 clip without restarting the story every five seconds
- model
- positive
- vae
- noise
- sampler
- sigmas
- latent_image
- stream_plan
- output
- status
The node's own one-liner is the most useful warning anyone will give you: "Keep pass 1 full-length. Not the Hard AV Prefix sampler." Both halves matter, and people ignore them in that order.
What it actually is
H3 gives you a few seconds of 24fps video with native stereo audio in one pass. Want a better fifteen seconds - upscaled, re-refined - and the usual move is to chop the timeline and refine window by window. With a chaining node each window is effectively a fresh generation: attention restarts, positions restart, drift shows up at the seam. The windows get stitched; the model still thinks in windows.
This is the other approach. A second-pass sampler refines in bounded micro-phases over one continuous timeline: one noise field, one set of positions from a single full-request layout, and, in the streaming modes, a bounded cache of clean K/V from earlier in the clip that later phases can attend to. Streaming attention, not last-frame chaining. The Hard Prefix sampler and Sequential Audio suite are untouched.
How it works
A stream_plan from the planner supplies the geometry: micro-phases of 2/2/2/1 groups, 17 frames and 5 video latents each. Every phase runs your complete sigma schedule through Euler, then a near-clean extra forward - models already resident, sigma≈0, H3 clamping internally to 1e-6. Its prediction is discarded; the point is capturing target video/audio K/V after Q/K norm and RoPE into owned BF16 storage. Commits are transactional, so a failure rolls back instead of leaving a half-cached timeline.
The streaming_mode dropdown is a ladder: Geometry Only (the default - no streaming patch at all, ordinary full native sampling, so you can baseline on the same node), then Micro Chunk, Clean Commit and Clean KV, which run the phases and the clean forwards but feed nothing back to attention, then Streaming Attention (all layers cached) and Sparse KV (selected layers only - the one mode where layer_policy does anything).
retention (previous_only, sink_plus_recent_1, sink_plus_recent_2 - the default) decides how much history survives. It isn't ordinary bidirectional H3 with a bigger buffer: current media Q sees conditioning plus retained clean AV plus current K/V, while conditioning Q sees conditioning K/V only. Approximate by design - A/B it at a fixed seed.
The inputs worth wiring
Model, positive, noise, sampler, sigmas, latent_image, and stream_plan. The vae input exists only so the node can confirm it's an H3 video VAE capable of final decode - it never encodes anything.
sampler is standard Euler, and custom options are rejected. sigmas come from you - the planner never touches a schedule, and each micro-phase runs the whole thing. The author's tested refinement is BasicScheduler(simple, steps=3, denoise=0.3) at shift_video=12; denoise=0.3 is not an initial sigma of 0.3 (it's about [0.837, 0.75, 0.571, 0]), and swapping in a full-noise schedule because the upstream reference uses one can erase your first-pass anchors.
Then the knobs: streaming_mode, retention, layer_policy, custom_layers, cache_device (default cpu), max_kv_mib (8192, range 64–262144), and audio_reset_interval_requests - reserved metadata, since continuation isn't exposed and every execution starts with empty KV.
Outputs are output (the refined AV LATENT; split it and reuse your decode) and status, which reports your actual sigmas, forward counts, cached layers, retained KV and CUDA peak - the only honest record of what happened.
Installing it
Nothing streaming-specific. ComfyUI Manager → search ComfyUI_JR_MiniMaxH3Node (registry comfyui-jr-minimax-h3-node) → install → restart.
cd ComfyUI/custom_nodes
git clone https://github.com/Goldlionren/ComfyUI_JR_MiniMaxH3Node
<the Python that runs ComfyUI> -m pip install -r ComfyUI_JR_MiniMaxH3Node/requirements.txt
requirements.txt is one line: imageio-ffmpeg>=0.5. Use the same interpreter ComfyUI runs on - portable and desktop builds hide theirs. Update with git pull origin main and the same pip line.
Where people get burned
- Duration mismatch. The preset wants one complete AV latent at exactly its dimensions and fails before sampling with an expected-versus-actual pair. The 5s preset is 124 frames, 37 video latents, 207 audio ticks, and
native_framesgoes into a frame-count input upstream, never a seconds input. - Wrong neighbours. Adaptive Cache, Morton and compiled/block-replacement forwards are excluded on purpose; turn them off. Sage and chunk-FFN stay, but Sol-Attn won't help - rectangular Q against a longer K is ineligible for its sparse kernel and falls back to dense.
- Raising
max_kv_mibfirst. That budget is KV and staging, not total model RAM; full-width dense KV runs to tens of GiB. CPU storage (the default) is the honest trade on a 16GB card, and it is slower.
This pack has essentially no community footprint - searches for it, for TaoMate, and for streaming attention in this context come back empty, so there are no threads to check against. Its docs/H3_STREAMING_SAMPLER.md is more thorough than most community documentation. Start at 512×288, Geometry Only against Streaming Attention, fixed seed.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| positive | CONDITIONING | — | |
| vae | VAE | — | |
| noise | NOISE | — | |
| sampler | SAMPLER | — | |
| sigmas | SIGMAS | — | |
| latent_image | LATENT | — | |
| stream_plan | JR_H3_STREAM_PLAN | — | |
| streaming_mode | COMBO | Geometry Only | 6 options: Geometry Only, Micro Chunk, Clean Commit, Clean KV, Streaming Attention, Sparse KV |
| retention | COMBO | sink_plus_recent_2 | 3 options: previous_only, sink_plus_recent_1, sink_plus_recent_2 |
| layer_policy | COMBO | every_4 | Only active in Sparse KV. Streaming Attention always caches all layers. |
| custom_layers | STRING | — | |
| cache_device | COMBO | cpu | 2 options: cpu, cuda |
| max_kv_mib | INT | 819264–262144 | — |
| audio_reset_interval_requests | INT | 11–1000 | Reserved for future continuation; each current execution starts with empty KV. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| output | LATENT | — |
| status | STRING | — |