Nodes/ComfyUI-BCNodes/SeedVR2 Preprocess (Compact)
ComfyUI Node

SeedVR2 Preprocess (Compact)

The SeedVR2 Input Stage in One Node, With the Clip Never Held Twice

By 0xBeycan·Created about a month ago·Updated 13 days ago· 2
SeedVR2 Preprocess (Compact)
  • image
  • vae
  • latent
  • plan
◄upscale_factor2.00►
◄downscale_factor0.50►
◄max_resolution4096►
◄emulate_bf16true►
◄tile_size0►
◄overlap256►

SeedVR2 has quietly become the default "add real detail" upscaler in this ecosystem, and the catch is always the same: it works beautifully and then runs out of memory on video. The standard chain - Resize → VAE Encode → sampler → VAE Decode → PostProcess - keeps every node's output alive until the prompt ends, so a 900-frame 1080p clip is holding several full copies of itself at once. This node is the first half of the fix. It does the resize and the encode, and hands you a latent plus a small settings note. The clip-sized intermediates never exist as graph outputs.

What it replaces, and why that matters

It's SeedVR2 Resize and SeedVR2 VAE Encode collapsed into one, with the resize's output existing only inside the node while it's being encoded. The colour reference the non-compact pair carries around isn't built here at all - PostProcess (Compact) rebuilds its own from the original frames.

The numbers, per frame at 720p → 1080p with upscale_factor 1.5, are the point: the traditional chain ends the run holding about 62 MB per frame across the graph's outputs (original, resized, reference, decoded, post-processed, plus the latents). The compact pair holds roughly 24.5 MB per frame - original, the corrected output, the latent. On a 902-frame clip that's 56 GB against 22 GB. That's the difference between running and not running on a 64 GB machine.

How the resize works

The same steps as the non-compact node, in this order: a PIL LANCZOS downscale by downscale_factor (8-bit, exactly ComfyUI's own ImageScaleBy(lanczos)), then a shortest-edge resize where the short edge becomes shortest edge of the original × upscale_factor - torchvision's bicubic with antialias - then a second resize if the longest edge exceeds max_resolution, a clamp to [0, 1], zero-padding to a multiple of 16, and frame-count padding to 4n+1 by repeating the last frame.

Those sound like fiddly details and they're why the node exists rather than just three stock nodes: ComfyUI's own bicubic is F.interpolate without antialias - a different kernel - and its Resize Image rounds the long edge. Neither matches what the SeedVR2 reference pipeline does.

emulate_bf16 (on by default) runs the resize in bfloat16 on the GPU when CUDA is available, so the frames match what a bf16 pipeline would produce. Without CUDA it's float32.

The inputs

  • image - the original frames. Connect this same batch to PostProcess (Compact)'s image; the pair is designed around that.
  • vae - the SeedVR2 VAE.
  • upscale_factor - default 2. The short edge of the output is the short edge of the input times this.
  • downscale_factor - default 0.5. The lanczos pre-downscale; 1 means none. This is the same knob SeedVR2 Framing Downscale picks for you.
  • max_resolution - default 4096, cap on the longest edge, 0 for no cap.
  • tile_size - default 0, which is auto. It picks the tiling that computes the fewest pixels while fitting your card: the two tile sides are chosen independently (multiples of 32), so a 1088-high frame can run as full-height strips instead of a grid of squares, and it never cuts the overlap below the value you set. The estimate it compares against free VRAM is 6.36 GB fixed plus about 15,440 bytes per tile pixel. Type a value instead and you get the old square-tile behaviour, so saved workflows keep working.
  • overlap - default 256.

The outputs

latent - what the encode gives, float32, ready for the sampler. And plan (SEEDVR2_PLAN), a few numbers: the resize settings and the output size. Wire it to PostProcess (Compact)'s plan input and don't lose it; that node also wants the original image and will stop with an error if it isn't the batch the plan was made from.

Install

Manager, search ComfyUI-BCNodes, or:

cd ComfyUI/custom_nodes
git clone https://github.com/0xBeycan/ComfyUI-BCNodes
pip install -r ComfyUI-BCNodes/requirements.txt

Restart and search BCNodes in the node library - the compact pair lives under BCNodes/seedvr2/compact. Requirements are opencv-python, postfx and caption-audit, none of which this node uses. Delete a leftover ComfyUI-AutoBypass folder from the pack's old name, and note you still need ComfyUI's own SeedVR2 model, VAE and sampler support for the middle of the chain.

Gotchas

With downscale_factor below 1, the lanczos downscale runs twice per frame - once here, once in PostProcess (Compact), where the reference is rebuilt. The author's figure is about 20 ms per 720p frame of extra CPU work, which is real on a long clip and negligible on a still.

The encoder's memory estimate runs about 1.34 to 1.40× the actual driver peaks with the Process Monitor off, which is deliberate margin, not a bug - the estimate is what stands in for measurement until bigger cards have been characterised the same way. If it refuses a tile that you think would fit, that's the reason.

CategoryBCNodes/seedvr2/compact

Inputs (8)

NameTypeDefaultDescription
imageIMAGEThe original frames. Connect the same batch to SeedVR2 PostProcess (Compact) `image`.
vaeVAE—
upscale_factorFLOAT2.000.01–16Shortest edge of the output = shortest edge of the input × this (the resize resolution, computed from the original image).
downscale_factorFLOAT0.500.01–1Lanczos downscale applied first, like ImageScaleBy(lanczos). 1 = none.
max_resolutionINT40960–16384Cap on the longest edge, 0 = none.
emulate_bf16BOOLEANtrueResize `image` in bfloat16 on the GPU when CUDA is available. Without CUDA the resize runs in float32.
tile_sizeINT00–40960 = auto: the tiling that computes the fewest pixels with a working set that fits this card, tiles of any width and height (full-height strips when they fit; no tiling when the whole frame fits), the overlap kept. Otherwise a square spatial tile in pixels, as VAE Encode/Decode (Tiled); a tile that covers the frame means no tiling.
overlapINT2560–4096—

Outputs (2)

NameTypeDescription
latentLATENTThe latent SeedVR2 VAE Encode gives for SeedVR2 Resize `image`, float32. Wire to the sampler.
planSEEDVR2_PLANThe resize settings and the output size (a few numbers). Wire to SeedVR2 PostProcess (Compact) `plan`.