MiniMax H3 Adaptive Cache (Advanced)
What every knob actually does
- model
- model
The preset node in this pack is the one you'll use on a normal day. This is the one you break out when a preset isn't quite right and you want to know why. Both nodes drive the exact same engine - a content-aware tail-block cache for ComfyUI's native MiniMax H3 - but where the preset version hides its decisions behind safe/balanced/fast, Advanced hands you every parameter the controller actually uses, with nothing to hide behind.
The mechanism is the same, so if you haven't met it yet: H3 runs dozens of DiT blocks per sampling step. This plugin recomputes the front blocks every call, and when consecutive steps look similar enough it replays a saved tail_residual over the audio/video target rows and skips the trailing blocks - all wired through H3's existing double_block hooks, no core patching. It's a lossy, seed-changing acceleration. This node is for tuning how aggressive that trade-off is.
The knobs that shape how much it skips
Three parameters decide how much work gets skipped and when skipping is allowed:
cache_depth(default 0.75) - the fraction of trailing DiT blocks skipped on a cache hit. The tooltip says it plainly: 0.75 recomputes about 12 of 50 blocks. Raise it toward the 0.94 cap for more skipping; lower it when output quality complains.sigma_threshold(0.12) - the maximum normalized change in the noise level (sigma) between steps that a candidate will tolerate. Bigger sigma jumps mean the model is doing real work; don't cache those.window_start/window_end(0.1 / 0.9) - the sampling-progress window where caching is even allowed. Caching at the very start or very end of a schedule is where artifacts live, so by default the first and last ~10% are off-limits.
The knobs that protect quality
This is the part that makes the cache "content-aware" instead of blind. It probes a sample of target audio/video tokens and channels each step and measures how much the content actually changed:
max_consecutive(2) - max cache hits in a row before a forced full refresh. Even if content looks stable, this stops errors from compounding.quality_guard(audio_video) - which content signals to check.audio_videois the default;videoskips the audio check;offdisables content protection entirely (that's roughly what the preset node callssigma_only).content_multiplier(1.25) - how tolerant the check is relative to each lane's moving average. Lower is stricter/safer, higher caches more.content_ceiling(0.75) - a hard upper bound on allowed content change, so the very first candidate isn't trusted just because no moving average exists yet.
If you're debugging visible glitches, the first fixes to try are lowering content_multiplier, dropping max_consecutive to 1, or making sure quality_guard is on audio_video. If instead you're getting too few cache hits, loosen the multiplier or widen the sampling window.
Cache placement
cache_device (auto/gpu/cpu) chooses where the residual lives, and gpu_safety_mb (default 768) is the free-VRAM reserve auto insists on before it'll use the GPU. Leave auto alone on anything with less than ~24GB - residuals at higher resolutions get big, and on CPU they're pinned memory that gets copied back to GPU during the front-block compute, which hides most of the cost.
Output and wiring
Same deal as the preset node: one patched MODEL out, and it must feed both the scheduler and the guider. Take one branch only and you'll get a "logically wrong" workflow that runs fine and looks fine until you look at the output.
Install
Same pack, same install. ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/FFFFFFpy/ComfyUI-MiniMaxH3-AdaptiveCache
Restart. No extra dependencies - the only real requirement is ComfyUI's native MiniMax H3 support and the big model it loads.
Tuning and benchmarking gotchas
The README is refreshingly honest about how easy it is to fool yourself with a stopwatch. If you're comparing configs, do a warm-up run first (Triton compiles and autotunes on new resolutions), then take the median of at least three runs, and log the console stats the node prints - full=, cache=, executed=.../1000 blocks, content rejects. The author's own data shows single runs swinging 25% from cache state and compilation alone. And remember the block-reduction percentage the node reports is not your end-to-end speedup; it's just the DiT work it skipped. If you pair this with Kijai's Sol-Attn, keep Morton off - since v0.1.1 the node detects transformer_options["sol_morton"] and auto-bypasses itself (full block execution) when Morton is on, printing a warning and stats so you know it happened.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| cache_depth | FLOAT | 0.750–0.94 | Fraction of trailing DiT blocks skipped on a cache hit. 0.75 recomputes about 12 of 50 blocks. |
| sigma_threshold | FLOAT | 0.120–1 | Maximum normalized sigma change allowed for a cache candidate. |
| window_start | FLOAT | 0.100–0.49 | — |
| window_end | FLOAT | 0.900.51–1 | — |
| max_consecutive | INT | 20–10 | Maximum consecutive cache hits before a forced full refresh. |
| quality_guard | COMBO | audio_video | 3 options: audio_video, video, off |
| content_multiplier | FLOAT | 1.250.25–4 | A candidate is rejected when its content delta is much larger than the lane's moving average. Lower is safer. |
| content_ceiling | FLOAT | 0.750.05–2 | Hard upper bound for symmetric target-content change. Prevents the first candidate from being trusted blindly. |
| cache_device | COMBO | auto | 3 options: auto, gpu, cpu |
| gpu_safety_mb | INT | 7680–8192 | Free-VRAM reserve used by Auto cache placement. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| model | MODEL | — |