ComfyUI Node

ANDRO Seam Check

Your tiled VAE decode is leaving a softer frame every 24 frames and nobody notices

By AndreiOrehov·Created about a month ago·Updated 6 days ago· 4
ANDRO Seam Check
  • images
  • sharpness_plot
  • report
dip_threshold0.930
check_spatialtrue
predict_from_temporal_size0
predict_from_temporal_overlap8
temporal_compression8

When a video latent is too big to decode in one shot, ComfyUI tiles the decode - spatially and, for video VAEs, in time. The temporal kind is the sneaky one. A diffusion decoder has no context at a temporal tile edge, so the blend leaves a visibly softer frame on every seam. And it's smooth, not a jump, which is exactly why you never catch it: a frame-to-frame difference check doesn't see it, because there's no sudden change, just one frame that's slightly soft before the next recovers.

Tile Seam Check measures per-frame sharpness, finds the local dips, and only flags them when several sit on one regular grid. That regularity requirement is the whole idea - motion in the shot produces isolated soft frames too, and the node refuses to cry wolf about those. Here's the README's real output from a bad setting, on a 121-frame LTX-2.5 generation:

temporal: 121 frame(s), median sharpness 0.00738
  soft frames at [12, 25, 49, 66, 73, 97]
  PERIODIC: 4 of them every 24 frames ([25, 49, 73, 97]) - that is a temporal tiling seam.
  off-grid, most likely motion in the shot: [12, 66]

Same generation with temporal tiling off: soft frames at [66] - no regular spacing, these look like content. That's the node earning its keep - telling a real artefact from normal video in the same clip.

Inputs

  • images - the decoded video batch (IMAGE). Feed it whatever your decode produced; you want the finished frames, not the latent.
  • dip_threshold (default 0.93) - a frame counts as a dip when its sharpness falls below this fraction of the previous frame's. Lower it to only catch harder drops, raise it to catch gentler softening. 0.93 is a sensible default; the seams the README measures are clear dips.
  • check_spatial (default on) - also checks for spatial (within-frame) seams. It looks for several regularly-spaced sharpness peaks along an axis, not a single strong column - because a hard edge in the content looks identical to one seam. Same regularity principle as the temporal check.

Outputs

  • report - the plain-language verdict above: dips, whether they're periodic, and if spatial, the pixel spacing. Wire it to a text display or read the console.
  • sharpness_plot - an IMAGE of the per-frame sharpness trace with the dips marked. This is the one you actually look at: a regular sawtooth is a seam, a single isolated valley is motion blur or content.

The fix it's pointing you at

If the node finds a temporal seam, the README's measurements are unambiguous: raise temporal_size (or turn temporal tiling off entirely) and cut tile_size instead. The 24-frame period in the example is arithmetic - a temporal_size of 32 with overlap 8 means the tile steps 3 latent frames, which is 24 pixel frames at 8× compression. Meanwhile the spatial tile is where the memory wall actually lives: in the pack's testing, cutting spatial tile size from 768 to 384 took a 912-second, VRAM-thrashing float32 decode down to 60 seconds with no visible seam (spatial tile-boundary excess measured 1.03–1.05× - noise). In bf16 tile size costs nothing; in float32, 768 is a 28× cliff. The short version: temporal tiling buys you a soft frame every N frames, spatial tiling buys you the same memory savings without the artefact. Tile space, never time.

One caveat: the sharpness heuristic is exactly that. Grain or heavy film-look post-processing will lower absolute sharpness and could make everything read as "soft" - if the report floods with dips at dip_threshold 0.93, the node is measuring your grain, not a seam. Raise the threshold a notch before you blame the decode.

Install

ComfyUI Manager (search "comfyui-vae-float32"), or:

cd ComfyUI/custom_nodes
git clone https://github.com/AndreiOrehov/comfyui-vae-float32

Restart. No extra dependencies. It's a diagnostic node - you run it once per tiling setup, read the verdict, set your tiling once, and mostly forget it exists. Which is the right relationship with a tool that exists to catch the bug you can't see.

CategoryANDRO

Inputs (6)

NameTypeDefaultDescription
imagesIMAGEThe decoded sequence to inspect. Needs enough frames for a pattern to show - a handful of frames cannot prove periodicity.
dip_thresholdFLOAT0.9300.5–0.999A frame is called soft when its sharpness drops below this fraction of the previous frame's - 0.93 means a 7% fall. Lower it to catch fainter seams at the cost of flagging ordinary motion blur; raise it if a fast-moving shot reports dips everywhere. Isolated dips are usually content: only REGULARLY spaced ones are a tiling seam, and the report says which it found.
check_spatialBOOLEANtrueAlso look for vertical/horizontal seams left by SPATIAL tiling. Only regular, repeating peaks are reported - a single strong edge is content, not a seam.
predict_from_temporal_sizeoptINT00–4096Set this to the temporal_size the decode used and the node will PREDICT where soft frames must land, instead of only finding them afterwards. The spacing is arithmetic, not luck: tile_t = temporal_size / the VAE's temporal compression, and a seam falls every (tile_t - overlap_t) x compression frames. 0 = predict nothing, just measure what is in the batch.
predict_from_temporal_overlapoptINT80–4096The temporal_overlap that went with it. Only read when predict_from_temporal_size is not 0.
temporal_compressionoptINT81–64How many output frames the VAE packs into one latent frame - 8 for LTX-2.5. Wrong value here shifts the predicted spacing by the same factor, so check it against your VAE rather than assuming.

Outputs (2)

NameTypeDescription
sharpness_plotIMAGEPer-frame sharpness as a plot, with the soft frames marked - a temporal seam shows up as evenly spaced dips.
reportSTRINGWhich frames went soft, whether their spacing is regular enough to be a tiling seam rather than motion, and what to change if it is.