ComfyUI Node

ANDRO Compare

Did that setting actually change anything? Stop eyeballing, get the PSNR

By AndreiOrehov·Created about a month ago·Updated 6 days ago· 4
ANDRO Compare
  • image_a
  • image_b
  • difference
  • report
  • worst_zones
amplify20

"Did that setting change anything, and is the change real?" is the question behind half of all ComfyUI experiments, and the usual answer is to eyeball two previews and guess. Image Compare (numeric) replaces the guess with numbers: two image batches in, and out come the max and mean absolute difference, the percentage of differing samples, the PSNR, which frame deviates most, and an amplified difference image you can actually look at.

It's the same pack's sanity tool as Image Range Stats - the thing you use to confirm a claim instead of trusting it. The README's own workflow is the perfect demo: decode one latent twice, once stock and once float32, and this node gives you "max |diff| = 0.151855, PSNR 58.14 dB". Those two decodes look identical to the eye. The difference map doesn't lie.

How it works

Simple and honest. It subtracts batch B from batch A over the shared frame count, reports the aggregate stats, and builds a visualisation by taking the absolute difference and multiplying it by the amplify gain, clipped to [0,1]. That last step is the trick: the real per-pixel differences in a good float32-vs-stock comparison are tiny - a fraction of a percent - so the raw difference image is near-black. Amplified ×20, the structure shows up: fine grain over smooth gradients (that's the bf16 quantisation grid) and bright specks on light sources (that's the clamp cutting highlights). The README's plates show the same grain at ×200 on a graded frame.

Inputs

  • image_a and image_b - the two IMAGE batches. Order matters only for the sign of the difference, which the report doesn't even print; what you care about is magnitude. Batch counts can differ - it compares the first min frames.
  • amplify (default 20, range 1–200) - the gain on the difference image. Start at 20; crank it if the result is still too dark to read. 200 is the "I need to prove something is different at all" setting.

If the two inputs have different spatial shapes, the node says so and passes image_a through rather than crashing - a "cannot compare" report instead of a mysterious failure.

Outputs

  • report - max/mean |diff|, percent differing, PSNR, the worst frame number, and both images' value ranges. Read it in the console.
  • difference - the amplified difference image, which you can drop straight into a SaveImage or PreviewImage. When someone on a forum says "I can't see any difference", this is the receipt.

A couple of honest notes on reading the numbers. PSNR in the 50s+ dB means "visually identical, numerically different" - which is exactly what you want to see when confirming a faithful float32 decode. Below ~30 dB and you're looking at a real visible change. Also, this is a per-pixel metric: it will not tell you that content changed, only that pixels did. For that, you compare against a rerun of the same seed - and here's a genuinely useful habit: two identical graphs run at the same seed on the same hardware should give you PSNR well into the hundreds. If you're at 40 dB, something nondeterministic is in your graph.

Install

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

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

Restart. Zero extra dependencies - it's pure numpy/torch arithmetic.

You'll get the most out of it as the pack intends: on one side a stock VAEDecode output, on the other a VAEDecodeFloat32 output from the same latent, so "did removing the clamp change anything" stops being an argument and becomes a report.

CategoryANDRO

Inputs (3)

NameTypeDefaultDescription
image_aIMAGEFirst batch. Frame counts may differ - the shorter one decides how many frames are compared - but the frame SIZE must match.
image_bIMAGESecond batch, compared against A. The usual pairing is one decode with keep_out_of_range ON and one with it OFF, or float32 against 'vae default' - same seed, one setting changed, so whatever the report shows can only have come from that setting.
amplifyFLOAT201–200Gain on the difference image, because the raw difference is almost always too dark to see. Be warned what this is worth: the clamp/precision differences this pack is about stayed BLACK at 25x, and only became visible around 100-200x - and there they sit on sky, haze and smooth gradients, i.e. exactly where banding shows up first. Trust the numbers in the report over this picture.

Outputs (3)

NameTypeDescription
differenceIMAGE|A-B| multiplied by amplify - black means identical, and it stays black for differences too small to see even at high gain.
reportSTRINGmax/mean deviation, PSNR and SSIM, where in the frame the difference actually sits, the five worst frames, and a verdict on whether float32 is worth it for THIS shot.
worst_zonesMASKThe tiles where the difference is concentrated. A high global PSNR with a small bright patch here means the damage is real but local - usually sky or haze, which is exactly where banding starts.