Nodes/Model Utility Toolkit/CWB Embedding Multi-Merge
ComfyUI Node

CWB Embedding Multi-Merge

Merge 2 to 8 embeddings into one file without a training run

By silveroxides·Created 2 years ago·Updated 10 days ago· 16
CWB Embedding Multi-Merge
  • cwb_config
  • output_filename
  • documentation
  • cwb_report
embedding_count2
embedding_1
embedding_2
embedding_3None
embedding_4None
embedding_5None
embedding_6None
embedding_7None
embedding_8None
execution_modeMERGE
cwb_presetbalanced_sim_mean
target_vector_count0
coalesce_similarity_threshold0.95
coalesce_position_window0.10
vision_boundary_embeddingsfalse
legacy_boundary_searchfalse
boundary_reference_embeddingNone
boundary_similarity_threshold0.95
output_filenamecwb_merged_coalesced_embedding
save_dtypefp32
process_devicecuda
lazy_loadtrue
force_clear_cachetrue
override_dtypefalse

Ask the old-timers how to combine two embeddings and they'll tell you not to. "You don't merge embeddings, just use both in the prompt." That's been the correct answer for years, and it's still the correct answer for 99% of cases. The CWB Embedding Multi-Merge is the experimental corner case that finally does the thing nobody built: it actually blends 2 to 8 embedding files into one new .pt, then cleans up the redundant rows that blending creates.

What it is

Embeddings (textual inversions, if you remember that term) are just a handful of learned token vectors plus a trigger word - 10 to 80 KB, no model weights involved. This node takes up to eight of them, aligns them row by row, and blends each aligned group into one vector using Consensus-Weighted Blending (CWB, the algorithm this whole pack is built around). Then, because a merge tends to leave near-duplicate rows behind, it runs a "coalesce" pass that folds similar vectors together. The result is one embedding file you can drop into ComfyUI/models/embeddings and trigger with a single token, instead of maintaining a prompt stack.

Why bother? Mostly portability and cleanliness: one file to share, one file to ship in a workflow, and one file that keeps the useful concept signal from several embeddings without you babysitting prompt weights. This is a deep-end tool, and it shows - the node is marked experimental and has essentially zero community footprint yet. Treat it as "nice, it exists" rather than a daily driver.

How the merge works

For every aligned group of token vectors across your inputs, CWB does the same thing:

  1. Compute an element-wise mean or median of the group (the "consensus").
  2. Measure each source vector's cosine similarity to that consensus.
  3. Weight each contributor by that similarity, so vectors that agree with the consensus dominate the blend.

That's the whole trick - it's a weighted average where the weights come from how well each source matches the group's shared direction, not from a manual strength slider. The default balanced_sim_mean preset uses similarity-based row alignment, mean consensus, and a touch of position weighting, which is a sane starting point.

The coalesce stage is separate and purely local: it repeatedly finds pairs of rows that are mutual nearest neighbors (each is the other's closest match), requires that pair to be both similar enough and close enough in row position, and merges it into one row. Rinse and repeat until you hit your target row count.

Inputs that matter

  • embedding_count - how many of the eight input slots to use. If it's set to 4 but one slot is "None", it errors rather than silently merging garbage.
  • embedding_1 … embedding_8 - the contributors. Embedding 1 is the anchor: it supplies the output metadata and the reference for shared shape and naming.
  • cwb_preset - the blend recipe. balanced_sim_mean (default) is the safe one; the focused_* variants get stricter about which rows match.
  • target_vector_count - the row count you want after coalescing. 0 means "coalesce every eligible pair"; otherwise it stops at this count.
  • coalesce_similarity_threshold (0.95) and coalesce_position_window (0.1) - how similar two rows must be, and how close in position, before they're merged. Lower the threshold to shrink harder.
  • vision_boundary_embeddings - leave this off for ordinary textual inversions. Turn it on only if your embedding is a complete encoded visual block where the start/end rows are structural and must be preserved.
  • output_filename - no extension; the file lands in the embeddings folder.

The node outputs output_filename (the file it wrote), documentation (the full CWB manual, handy), and cwb_report (a text summary of what got merged and coalesced).

Installing it

Grab the whole toolkit, since these nodes ship inside it:

cd ComfyUI/custom_nodes
git clone https://github.com/silveroxides/ComfyUI-ModelUtils
# restart ComfyUI

Or use ComfyUI Manager and search "Model Utility Toolkit" - that's the pack's display name. Installer-wise it pulls requests, Pillow, mutagen, unifiedefficientloader (the streaming library behind lazy_load), and av. No model files to download; everything it touches is already in your embeddings folder.

Where people get burned

  • Embeddings are encoder-locked. SD 1.5, SDXL, and Pony each have their own CLIP variant, and blending across them produces a vector that means nothing in either space. Only merge embeddings trained for the same encoder - the KB's embedding research is blunt about this.
  • Merging into a bigger mess. The coalesce pass is what makes a multi-merge usable; skip it (or set a huge target count) and you'll just get a longer, bloatier embedding.
  • It writes files. Set execution_mode to DOCUMENTATION ONLY first if you just want to read the docs without generating anything.

If the merge silently produces nonsense, your inputs are almost certainly from different encoders. Check that before you suspect the node.

CategoryModelUtils/Embeddings/Merge

Inputs (25)

NameTypeDefaultDescription
embedding_countCOMBO2Number of consecutive embedding inputs to merge.
embedding_1COMBOPrimary embedding and normal visual-boundary anchor.
embedding_2COMBOSecond equal-prior embedding contributor.
embedding_3COMBONoneOptional embedding contributor.
embedding_4COMBONoneOptional embedding contributor.
embedding_5COMBONoneOptional embedding contributor.
embedding_6COMBONoneOptional embedding contributor.
embedding_7COMBONoneOptional embedding contributor.
embedding_8COMBONoneOptional embedding contributor.
execution_modeCOMBOMERGEMERGE writes a new embedding. DOCUMENTATION ONLY opens no files.
cwb_presetCOMBObalanced_sim_meanEmbedding CWB preset used for multi-input alignment and coalesced row pairs.
target_vector_countINT00–100000Target body-row count. Zero coalesces every eligible pair; otherwise stops at this count or when no eligible pair remains.
coalesce_similarity_thresholdFLOAT0.950–1Minimum cosine similarity for a mutual-nearest body-row pair to coalesce.
coalesce_position_windowFLOAT0.100–1Maximum normalized row-position distance for an eligible pair.
vision_boundary_embeddingsBOOLEANfalseEnable for complete encoded visual blocks. Start/end rows are validated and preserved; False treats the full tensor as open textual inversion.
legacy_boundary_searchBOOLEANfalseSearch and trim legacy template rows using Boundary Reference Embedding. Requires vision boundary mode and a selected reference.
boundary_reference_embeddingCOMBONoneKnown-clean visual block used by legacy boundary search. Its first and last encoded rows define vision start/end.
boundary_similarity_thresholdFLOAT0.95-1–1Minimum encoded cosine similarity required independently for visual start and end validation.
output_filenameSTRINGcwb_merged_coalesced_embeddingFilename without extension under ComfyUI's embeddings category.
save_dtypeCOMBOfp32Requested dtype for generated floating embedding tensors.
process_deviceCOMBOcudaPer-tensor FP32 CWB arithmetic device; CUDA OOM retries that tensor on CPU.
lazy_loadBOOLEANtrueUse bounded UEL streaming and release each tensor after its work unit.
force_clear_cacheBOOLEANtrueClear Python and CUDA caches before each tensor at a possible speed cost.
override_dtypeBOOLEANfalseForce generated floating tensors to Save Dtype.
cwb_configoptCWB_CONFIGOptional complete CWB configuration override.

Outputs (3)

NameTypeDescription
output_filename*
documentationSTRING
cwb_reportSTRING