Analyze LoRA Similarity (2 Models)
Two LoRAs, same concept? Check before you merge them
- comparison_report
- cwb_report
- documentation
LoRAs are the most commonly merged thing in this whole pack, and also the fiddliest to compare. A LoRA isn't one tensor per layer - it's a down matrix and an up matrix that multiply together to produce the effective delta. Naively comparing files byte-by-byte tells you nothing, because two LoRAs that produce nearly identical effects can store wildly different raw matrices. This node understands the pair structure, and that's the whole value of it.
How it works
It streams two LoRA files from models/loras in low-memory mode and treats each LoRA's down/up tensors as a single logical layer. The similarity between two layers is computed from the product of the down and up cosine similarities - including the paired-sign equivalence CWB uses, so a flipped-sign pair still reads as similar rather than "opposite." The result is a comparison that's about what the LoRA does, not what its bytes look like.
The standard report covers the usual metrics (MAE, MSE, RMSE, relative L2, cosine, Pearson, exact equality, sign agreement) per logical layer. The CWB report adds pairwise row-cosine statistics and each LoRA's affinity to mean and median consensus - a preview of the math you'd get from CWBLoRATwoMerger or CWBLoRAThreeMerger. One genuinely useful thing the reports surface: which layers the two LoRAs share (e.g. both touch the same cross-attention blocks) versus where they don't overlap at all. That's the info that tells you whether merging them is a friendly union or a trainwreck.
Like the other analysis nodes, it never pads or zero-fills missing keys, and quantized LoRAs carrying ComfyUI quantization metadata are rejected since their stored values aren't comparable.
Inputs that matter
- model_a / model_b - the two files.
- cwb_similarity_alignment (default off) - greedy one-to-one row matching by cosine similarity, rather than index alignment. LoRA down/up rows don't have an inherent order the way checkpoint layers do, so this is often the more meaningful comparison. It's quadratic, so keep it off until you actually need it.
- top_weight_differences (default 20) - largest individual differences to detail; zero disables.
- exclude_patterns / glob_patterns - leave matching tensors out of the metrics; regex by default.
- process_device, force_clear_cache, execution_mode - CUDA with CPU fallback on OOM, cache flushing on by default, and a load-nothing
DOCUMENTATION ONLYmode.
Outputs
comparison_report, cwb_report, and documentation as plain text. Show Text node, done. No file is written, no model is modified.
Why you'd reach for it
The classic scenario: two people trained LoRAs for the same character or style, and you want to know if they overlap enough to merge cleanly - or if one is outright a derivative of the other. It's also the right sanity check before committing to a CWB LoRA merge, because the CWB report tells you how similar each layer is to the consensus the merger will compute.
Install
From Model Utility Toolkit (silveroxides/ComfyUI-ModelUtils). ComfyUI Manager → search "Model Utility Toolkit", or:
cd ComfyUI/custom_nodes
git clone https://github.com/silveroxides/ComfyUI-ModelUtils
Restart ComfyUI. Real dependency: unifiedefficientloader (UEL) for the streaming loads. The other requirements.txt packages belong to the pack's downloader nodes. These nodes use ComfyUI's newer extension API, so update ComfyUI if they don't show up.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| execution_mode | COMBO | ANALYZE streams both files and produces standard and CWB diagnostic reports. DOCUMENTATION ONLY performs no model loading. | |
| model_a | COMBO | First file in the comparison. Reports identify values and keys unique to this input separately from Model B. | |
| model_b | COMBO | Second file in the comparison. Inputs are analyzed only; neither file is modified or merged. | |
| cwb_similarity_alignment | BOOLEAN | false | Run threshold-independent CWB-style greedy one-to-one alignment. This is quadratic and can be slow for large embeddings. |
| top_weight_differences | INT | 200–1000 | Number of largest individual absolute parameter differences retained for the detailed report. Zero disables this list. |
| process_device | COMBO | Device for per-work-unit floating-point analysis. A CUDA OOM retries only the affected unit on CPU. | |
| force_clear_cache | BOOLEAN | true | Run garbage collection and clear the CUDA allocator cache after every analyzed work unit. Saves retained memory but slows analysis. |
| exclude_patterns | STRING | One pattern per line. Matching tensors are excluded from all comparison metrics and topology counts. Uses regex unless Glob Patterns is enabled. | |
| glob_patterns | BOOLEAN | false | Interpret exclusion entries as shell-style glob patterns instead of regular expressions. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| comparison_report | STRING | — |
| cwb_report | STRING | — |
| documentation | STRING | — |