SeedVR2 PostProcess (Compact)
SeedVR2 Decode and Post-Process in One Node, With Your VRAM Not Growing by the Frame
- samples
- vae
- image
- plan
- images
Two things kill long SeedVR2 runs, and they're both in the back half of the chain. ComfyUI's VAE Decode (Tiled) decodes the whole clip in one call and keeps every decoded frame on the GPU until the end, so VRAM climbs with the frame count - a 32 GB card tops out somewhere around 190 frames at 1080p regardless of tile size. Then Post-Process SeedVR2 Output builds five full-size float32 copies of the clip on its way through, which is how a 30-second 1080p clip exhausts system RAM. This node is both stages in one, and it does neither of those.
What it does differently
The decode writes only the frames, rows and columns that the output keeps - the 4n+1 padding and the pad-to-16 are decoded and thrown away, never stored. Each frame is then colour-corrected in place in that same buffer, against a reference rebuilt a few frames at a time from the original images. It's the same maths in the same order as the two stock nodes (the range conversion, the colour transfer from ComfyUI's own color_fix, the clamp, alpha from the reference, the even crop), just without the temporaries and without ever holding the clip twice.
The result is bit-for-bit identical to the stock chain - the pack tests it across every colour-correction method, several downscale and upscale factors, padded frame counts and both tiled and untiled paths, and against ComfyUI's own colour transfers.
Practically, that means the run is bounded by system RAM rather than VRAM. The author's measurement on a 5090 at 720p → 1080p with the 7B int8 DiT: 901 frames, 30 seconds of video, one piece, 18 minutes end to end, flat VRAM over the length - where the native tiled decode topped out near 190 frames. The decode is the expensive part, about 63% of the upscale's time, which is why the tile choice below is worth understanding.
Inputs
samples- the sampler's latent.vae- the SeedVR2 VAE.image- the original frames, the same batch you fed SeedVR2 Preprocess (Compact). The colour reference is rebuilt from these, four frames at a time on a worker thread so it costs no measurable wall time. If this isn't the batch the plan was made from, the node stops with an error rather than producing a subtly wrong colour transfer.plan- theSEEDVR2_PLANfrom Preprocess (Compact).color_correction_method-lab(default),wavelet,adain, ornone.nonebuilds no reference at all and measured 11–19% faster; it's the right choice when your source and output are already close in colour.tile_size- default 0, auto. It picks the tiling that computes the fewest pixels with a working set that fits the card, choosing the two sides independently so full-height strips are on the table. The decoder's estimate is 7.95 GB plus about 22,940 bytes per tile pixel, compared against the card's total less 768 MiB the driver never hands out. Typing a value gives you the classic square tile and atile_sizethat covers the frame means no tiling.overlap- default 256.
Output: images, decoded and colour-corrected frames, float16, cut back to the original frame count and the resized size.
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 (the pair is under BCNodes/seedvr2/compact). The requirements install opencv-python, postfx and caption-audit - none of which is used here. Delete a leftover ComfyUI-AutoBypass folder from the pack's old name. You also need ComfyUI's own SeedVR2 sampler and VAE for the middle of the chain.
Gotchas
Keep the original frames around. The whole design depends on image being the untouched source batch; pre-resize it "to save memory" and you've broken the reference, and the node's error is the polite version of that failure.
The auto tile is doing more work than it looks - on a 5090 at 720p → 1080p it picks three full-height strips for the decode, computing about a fifth fewer pixels than the 1024 square tile's six, with a smaller working set (26.7 GiB estimated against 29.8). That's not a small win and it's the default, so don't hand-set tile_size unless you have a reason.
That estimate isn't only for picking tiles: it's what the node checks free VRAM against before it starts, and the pack's VAE nodes free other models when they come up short rather than walking straight into an OOM - the DiT is staged in RAM by ComfyUI and reloads on demand. Which is why a decode that used to die next to a resident DiT now doesn't.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| samples | LATENT | The sampler's latent. | |
| vae | VAE | — | |
| image | IMAGE | The original frames: the batch SeedVR2 Preprocess (Compact) got. The colour reference is rebuilt from them, a few frames at a time. | |
| plan | SEEDVR2_PLAN | SeedVR2 Preprocess (Compact) `plan`. | |
| color_correction_method | COMBO | lab | 4 options: lab, wavelet, adain, none |
| tile_size | INT | 00–4096 | 0 = 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. |
| overlap | INT | 2560–4096 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | Decoded, colour-corrected frames, float16, cut to the original frame count and the resized size. |