Merge Embeddings (3 Models)
Merge Embeddings (3 Models) — blend three textual inversions into one
- output_filename
- documentation
This is one of the more niche nodes in the whole pack, and it's worth saying that up front rather than pretending otherwise. Embeddings are already a shrinking part of the ecosystem - locked to whichever text encoder they were trained against, mostly abandoned by every architecture since SD 2.0's CLIP swap, with the surviving new uploads almost entirely SDXL/Illustrious pose and character files rather than anything general-purpose. Merging three of them together is a genuinely specialist move on top of an already-niche technique: think averaging a few seed variants of the same trained concept, or blending three related style embeddings into one you can load with a single trigger word instead of three.
That said, if you're the kind of person who trains or collects a lot of embeddings for one base architecture, this is a real tool doing real work, not filler. It's part of ComfyUI-ModelUtils' Merging category, and it's the same SVD/blend machinery the pack uses elsewhere (LoRA extraction, checkpoint merging) applied to the smallest file type in the ecosystem.
Inputs that matter. model_a, model_b, and model_c are the three embeddings you're merging - dropdowns of your local embeddings folder. alpha, beta, and gamma (each default 0.5, range −10 to 10) read as the per-model blend weights for A, B, and C respectively, one Greek letter per input. execution_mode and calc_mode are mode selectors the schema doesn't document further - treat them as "pick a value, see what changes" rather than something with an obvious right answer from the field name alone. mismatch_mode (default "skip") governs what happens when the three embeddings don't line up cleanly - different shapes or missing keys between them - and alignment_mode (default "pad/crop") decides how it reconciles vectors of different lengths, by padding the shorter one or cropping the longer one.
There are three more numeric knobs - delta (default 2), epsilon (default 0.01), zeta (default 0) - that feed whatever formula calc_mode is running. The README doesn't spell out the math behind them, so the honest advice is to leave them at default until you have a reason not to, then sweep them by eye rather than by intuition.
The rest is plumbing shared with the pack's other merge and extraction nodes: seed for anything with a stochastic component, save_dtype and process_device for output precision and where the work runs, exclude_patterns/discard_patterns (regex by default, or glob syntax if you flip glob_patterns to true) for keeping specific tensor keys out of the merge, lazy_load (on by default) to stream tensors from disk instead of loading everything into memory at once, force_clear_cache (on by default) to free CUDA memory after each layer, and override_dtype (off by default) to force the whole output to save_dtype instead of preserving whatever higher precision the inputs carried.
Outputs. output_filename (STRING) tells you where the merged embedding landed; output_filename for the node input sets what it's called, defaulting to merged_3_embedding. documentation (STRING) is a second output that appears to return a human-readable summary of what the merge actually did - worth piping into a text-preview node, since with this many undocumented knobs, a plain-language readout of what ran is more useful here than on almost any other node in the pack.
Installing it. ComfyUI Manager, search "Model Utility Toolkit," or:
cd ComfyUI/custom_nodes
git clone https://github.com/silveroxides/ComfyUI-ModelUtils
Restart ComfyUI afterward.
Troubleshooting. Given how many parameters here are genuinely undocumented, the most useful troubleshooting step is also the simplest: read the documentation output before you assume anything went wrong. Beyond that, remember embeddings are text-encoder-locked - merging three SDXL-era embeddings gives you a usable SDXL-era embedding, but it won't magically produce something that works on a model with an entirely different text encoder, no matter how the merge math shakes out.
Inputs (23)
| Name | Type | Default | Description |
|---|---|---|---|
| execution_mode | COMBO | 2 options: MERGE, DOCUMENTATION ONLY | |
| model_a | COMBO | 1 options: None | |
| model_b | COMBO | 1 options: None | |
| model_c | COMBO | 1 options: None | |
| calc_mode | COMBO | 4 options: Add-Difference, Train-Difference, Extract-Features, Add-Dissimilarities | |
| mismatch_mode | COMBO | skip | 3 options: skip, zeros, error |
| alignment_mode | COMBO | pad/crop | 2 options: pad/crop, interpolate |
| alpha | FLOAT | 0.50-10–10 | — |
| beta | FLOAT | 0.50-10–10 | — |
| gamma | FLOAT | 0.50-10–10 | — |
| delta | FLOAT | 2.00-10–10 | — |
| epsilon | FLOAT | 0.01-10–10 | — |
| zeta | FLOAT | 0.00-10–10 | — |
| seed | INT | 00–18446744073709550000 | — |
| output_filename | STRING | merged_3_embedding | — |
| save_dtype | COMBO | 3 options: fp32, fp16, bf16 | |
| process_device | COMBO | 2 options: cuda, cpu | |
| exclude_patterns | STRING | — | |
| discard_patterns | STRING | — | |
| glob_patterns | BOOLEAN | false | When True, exclude/discard patterns use glob syntax (* = any sequence, dots are literal). When False (default), patterns are Python regex matched as substrings. |
| lazy_load | BOOLEAN | true | Low memory mode: load tensors from disk on demand |
| force_clear_cache | BOOLEAN | true | Clear CUDA cache after each layer |
| override_dtype | BOOLEAN | false | Force the entire model to be saved as the selected save_dtype. If False (default), higher precision dtypes are preserved. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| output_filename | STRING | — |
| documentation | STRING | — |