VAE Similarity Analyser
How different are they really?
- vae_a
- vae_b
- report_json
- global_cosine
- most_divergent_blocks
There's a classic ComfyUI moment: you download a "new" VAE, drop it in, and the output looks… identical. Or you fine-tune a VAE and want to know how much it actually moved. VAESimilarityAnalyserMEC answers that question with math instead of vibes - it computes cosine similarity between two VAEs, globally and per block, and tells you which blocks diverged most. It's from the ComfyUI-CustomNodePacks pack's VAE Tools corner.
Under the hood this is dead simple - flatten weight tensors, compare directions - but the utility is surprisingly practical. The KB's VAE panel makes the background clear: modern VAEs are usually baked into their checkpoints, and "go find a different VAE" is a habit that mostly breaks things on SDXL/Flux-era workflows. Before you chase a VAE swap, run this node and find out whether your two candidates are even different enough to matter.
How it works
It loads two VAEs (vae_a, vae_b), matches their tensors by name, and computes cosine similarity - how aligned each weight vector is between the two, where 1.0 means identical direction and lower means more divergent. You get a global figure across all common tensors plus a per-block breakdown, and the report flags the ten most divergent blocks.
One structural thing worth knowing: this is a weights comparison, not a behavior comparison. Two VAEs with 0.99 cosine can still decode slightly differently, and two with 0.90 can look similar in practice. But weights-close ⇒ behavior-close is a good first-order rule, which is what makes this a useful screening tool.
Inputs and outputs
vae_a,vae_b(VAE) - the two VAEs to compare.include_per_tensor(BOOLEAN, default false) - add a full per-tensor cosine list to the JSON. The default report is already per-block; flip this on when you want tensor-level forensic detail (verbose).
Outputs:
report_json(STRING) - per-block cosine similarity, missing keys, optional per-tensor detail.global_cosine(FLOAT) - the headline number: similarity across all common tensors.most_divergent_blocks(STRING) - JSON list of the ten lowest-cosine blocks, which is where any real difference actually lives.
Where it fits
Three quick wins. (1) You downloaded a "new" VAE and want proof it's actually new - check cosine against your current one. (2) You're about to merge VAEs with the pack's VAE Merge node, and you want to know which blocks carry the difference so you can weight the merge accordingly. (3) You're cataloguing a model collection and want a fast "is this a duplicate?" check. That last one is where global_cosine shines - it turns a 30-second eyeball job into a number.
Installing it
Standard pack install:
cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks.git
restart ComfyUI or use Manager → "CustomNodePacks". No extra dependencies - it's torch tensor math on already-loaded weights.
The honest limit
It compares weight directions, not sizes, and it only covers tensors both VAEs share - a VAE with a different architecture reports lots of "missing keys" rather than a clean low score. And remember the direction caveat: cosine similarity near 1.0 doesn't mean identical output, just identical weights. For the "is this worth swapping" question it's more than good enough, and it pairs cleanly with VAE Block Inspector for the "is it healthy" question.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| vae_a | VAE | First VAE to compare. | |
| vae_b | VAE | Second VAE to compare. | |
| include_per_tensoropt | BOOLEAN | false | Include per-tensor cosine entries in the JSON report (verbose). |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| report_json | STRING | Full similarity report as JSON (per-block cosine, missing keys, optional per-tensor). |
| global_cosine | FLOAT | Global cosine similarity across all common tensors. |
| most_divergent_blocks | STRING | JSON list of the 10 most divergent blocks (lowest cosine first). |