Nodes/ComfyUI-Safe-Chunked-Image-Blend/Safe Chunked Image Blend
ComfyUI Node

Safe Chunked Image Blend

The blend node that stops silently cooking your CPU

By xmarre·Created 3 months ago·Updated 3 months ago· 3
Safe Chunked Image Blend
  • image1
  • image2
  • IMAGE
blend_factor0.35
blend_modenormal
resize_policyerror_if_mismatch
resize_methodbilinear
chunk_size1
compute_devicecuda
output_cpu_float32true
synchronize_each_chunktrue
empty_cuda_cache_each_chunkfalse
log_progresstrue

You've got a 4K upscale on one branch and the original on the other, you hit that blend node, and suddenly your CPU fan sounds like a jet engine - or worse, ComfyUI just wedges. Safe Chunked Image Blend is a small pack written for that moment: a replacement-style ImageBlend for large, batched tensors that makes the resize-and-device dance explicit instead of letting some hidden path decide it.

The problem it attacks is real. ComfyUI image tensors usually arrive at post-processing nodes as CPU float32. A lot of blend nodes follow the device of the first input, so if image1 is on CPU, the resize and the blend happen on CPU too - and if the two inputs have different spatial sizes, some of them silently resize one to match the other first. For a (2, 5464, 3800, 3) upscaled batch against a half-res original, that's a full-batch CPU resize you never asked for, and on WSL setups it can freeze hard enough to wedge the whole thing. The author hit this in exactly those upscale/video workflows and built the fix (released r/StableDiffusion, May 2026).

How it works

The node takes two IMAGE tensors, validates them, and processes them in chunks instead of one giant operation. Per chunk it moves the frames to your chosen device, resizes the mismatched input explicitly, blends, clamps to [0,1], and copies the finished chunk into a preallocated output buffer. No concatenating big temporary chunks, no surprise full-batch resize. The CUDA path uses torch's F.interpolate; if you force CPU, resize runs through OpenCV.

The inputs that actually matter

  • resize_policy - the star of the show. Default is error_if_mismatch, which just throws if the sizes differ. That's a feature: it catches accidental mismatches instead of papering over them. The other two are resize_image2_to_image1 (upscale the smaller branch to match - the usual case) and resize_image1_to_image2 (when you deliberately want to match the second input).
  • compute_device - cuda, cpu, image1, or image2. Default cuda, and it will raise if CUDA isn't available, which is honest behavior for a node built to escape CPU-bound resizes.
  • chunk_size - frames per chunk, 1 to 16. Default 1. For the big-resize case, leave it at 1.
  • blend_factor - 0.0 keeps image1, 1.0 fully replaces it with the blended result. Default 0.35.
  • blend_mode - normal, multiply, screen, add, subtract, difference, darken, lighten.
  • log_progress - prints per-step logs so you can see exactly where a hang happens.

The single output is a normal IMAGE tensor. By default output_cpu_float32 is on, so you get back the standard CPU float32 tensor every save/preview node expects - turn it off only if the next node genuinely wants CUDA.

The author's recommended starting settings for a big upscale blend:

resize_policy = resize_image2_to_image1
resize_method = bilinear
chunk_size = 1
compute_device = cuda
output_cpu_float32 = true
synchronize_each_chunk = true
empty_cuda_cache_each_chunk = false
log_progress = true

Start with bilinear. bicubic is heavier; only switch once the workflow runs clean.

Installing it

ComfyUI Manager has it - search "Safe Chunked Image Blend". Or clone it yourself:

cd ComfyUI/custom_nodes
git clone https://github.com/xmarre/ComfyUI-Safe-Chunked-Image-Blend

Restart ComfyUI. No model downloads. The only dependencies are numpy and opencv-python-headless (declared in pyproject.toml), and cv2 is only touched on the CPU resize path - the code imports it lazily, so a pure-CUDA workflow runs fine without it. Worth knowing: the README's own install block still has a placeholder YOUR_USERNAME URL, so trust the repo link above.

Where people get burned

  • The default throws. If you wire two mismatched images in and get "Spatial mismatch", that's the node doing its job - read the error, pick a resize policy. It even tells you which policy fixes it.
  • CPU resize needs cv2. If you set compute_device=cpu with mismatched sizes and it errors about OpenCV, pip install opencv-python-headless and restart.
  • Batches must match. It won't repeat, truncate, or align frames for you; a (3, ...) against (2, ...) is an error, not a silent fix.
  • Chunks can still OOM. chunking helps a lot, but a giant frame with bicubic on a tight card can still blow up. That's what synchronize_each_chunk and empty_cuda_cache_each_chunk are for when debugging.

Honest take: for a 1MP normal blend, the stock nodes are fine and this is overkill. Where it earns its keep is 4K+ batches and video frames, where one hidden CPU resize is the difference between finishing and cooking your RAM. Niche, but it fixes a genuinely miserable failure mode.

Categoryimage/postprocessing

Inputs (12)

NameTypeDefaultDescription
image1IMAGE
image2IMAGE
blend_factorFLOAT0.350–1
blend_modeCOMBOnormal8 options: normal, multiply, screen, add, subtract, difference, +2
resize_policyCOMBOerror_if_mismatch3 options: error_if_mismatch, resize_image2_to_image1, resize_image1_to_image2
resize_methodCOMBObilinear4 options: bilinear, bicubic, nearest, area
chunk_sizeINT11–16
compute_deviceCOMBOcuda4 options: cuda, cpu, image1, image2
output_cpu_float32BOOLEANtrue
synchronize_each_chunkBOOLEANtrue
empty_cuda_cache_each_chunkBOOLEANfalse
log_progressBOOLEANtrue

Outputs (1)

NameTypeDescription
IMAGEIMAGE