Muse Color Match (Batched)
Color-matching 2,000 frames without eating all your RAM
- images
- reference
- images
If you've ever tried to fix color drift on a long video - say, stitching Wan clips together with start-end frames and then color-matching everything to a still reference - you know the drill: drag in KJNodes' ColorMatchV2, set method to mkl, strength to 1.0, and pray. It works beautifully for a few hundred frames. Then you throw a couple thousand 1080p frames at it and your machine starts swapping, the queue freezes, and the run dies.
That's the exact pain Muse Color Match (Batched) exists for. It's a drop-in replacement for ColorMatchV2 that processes the video a few frames at a time instead of holding the whole thing in RAM at once. Same color_matcher library, same methods, same inputs - just memory-bounded.
Why ColorMatchV2 crashes and this doesn't
The mechanism is right there in the node's source, and it's a genuinely interesting bug. ColorMatchV2 runs every frame through a thread pool, keeps every result alive in a Python list, then torch.stack()s the entire list at the end. Separately, the color_matcher library's internal Normalizer unconditionally upcasts every frame to float64 - regardless of what dtype you fed it. So right before the final downcast back to float32, that stack briefly holds your entire video at float64. For a few thousand 1080p+ frames that's tens of extra GB stacked on top of what the output actually needs. That peak is what kills long runs.
This node fixes it three ways: it processes a handful of frames at a time, forces each result back to float32 immediately per-frame (not once at the end), and writes straight into a single preallocated output tensor instead of ever building a second full-length list. Everything between "input" and "final output" stays bounded to a few frames.
The inputs that matter
- method -
mkl,hm,reinhard,mvgd,hm-mvgd-hm,hm-mkl-hm. These are the real methodscolor_matchersupports.mklis the community default for video work; experiment if you're unhappy with it. - strength - how hard to push toward the reference.
1.0is a full match; drop it toward 0 to blend back toward the original frame when the match is too aggressive. - batch_size - frames processed and held at once. The README recommends 2–4 for 1080p+; 4 is the default, and it's the main knob for the memory/speed tradeoff.
- output_precision -
float16,float32, ormatch_input. The default isfloat16, and for long videos that's the right call: half the final tensor's size. - workers - thread pool size, default 1. Each extra worker holds its own float32 source frame plus color_matcher's internal float64 intermediates at the same time, so more workers trades RAM for speed.
cleanup_between_batches just runs gc.collect() after each batch; leave it on.
Reference handling matches the original: one still gets reused for every frame, a batch the same length as your video matches 1:1, and a shorter reference batch clamps to its last frame. The single output is images (an IMAGE tensor) - wire it wherever you would've wired ColorMatchV2.
Installing it
Easiest route is ComfyUI Manager: search for "muse-collective-batched-colour-match" (or "Muse Color Match") and hit install. Or clone it manually:
cd ComfyUI/custom_nodes
git clone https://github.com/muse-collective-26/muse-collective-batched-colour-match
# restart ComfyUI
The only dependency is the color-matcher PyPI library - that's the entire requirements.txt. Manager handles it; if you installed manually and see an ImportError about color_matcher, pip install color-matcher into ComfyUI's embedded Python. No models to download, no API keys, nothing GPU-specific.
The honest caveat
The name isn't magic. The final IMAGE tensor this node returns is still one contiguous batch of every frame - roughly 51GB at float32 or 25.5GB at float16 for 2040 frames at 1088x1920. Batching kills the temporary overhead stacked on top of that, not the output itself. If your video genuinely can't fit in RAM at float16, no amount of batching saves you - that's what the float16 default is for.
For the classic long-video color-drift workflow, this is the one I'd reach for: same results as ColorMatchV2, minus the mystery OOM.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| reference | IMAGE | — | |
| method | COMBO | mkl | 6 options: mkl, hm, reinhard, mvgd, hm-mvgd-hm, hm-mkl-hm |
| strength | FLOAT | 1.000–10 | — |
| batch_size | INT | 41–64 | — |
| workers | INT | 11–16 | — |
| output_precision | COMBO | float16 | 3 options: match_input, float16, float32 |
| cleanup_between_batches | BOOLEAN | true | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |