Nodes/Model Utility Toolkit/Merge Text Encoders (3 Models)
ComfyUI Node

Merge Text Encoders (3 Models)

Merging three text encoders you almost certainly don't have to

By silveroxides·Created about a year ago·Updated 7 days ago· 16
Merge Text Encoders (3 Models)
    • output_filename
    • documentation
    execution_mode
    model_a
    model_b
    model_c
    calc_mode
    mismatch_modeskip
    alignment_modepad/crop
    alpha0.50
    beta0.50
    gamma0.990
    delta2.00
    epsilon0.01
    zeta0.00
    seed0
    output_filenamemerged_3_textencoder
    save_dtype
    process_device
    exclude_patterns
    discard_patterns
    glob_patternsfalse
    lazy_loadtrue
    force_clear_cachetrue
    override_dtypefalse

    Nobody is googling "merge text encoders," and the 0 impressions on this page kind of proves it. That's not a bug - it's an honest reflection that almost nobody merges text encoders, because the text encoder isn't where the style usually lives. It's the network that turns your prompt into conditioning vectors, and merges of those are for a genuinely narrow set of people. But if you're one of them, TextEncoderThreeMerger is the most capable place in ComfyUI to do it.

    Merge Text Encoders (3 Models) takes three text encoder files from models/text_encoders/, applies one of four mathematical recipes to their weights, and writes a new .safetensors into the same folder. Where it earns its keep: blending two CLIP-family encoders whose vocabularies you want combined, or carrying a fine-tuned encoder's learned semantics into a base while keeping the base's stability. The diffusion model usually carries style; the encoder carries what words mean.

    How it works

    Model A is the anchor. It sets the metadata, the tensor shapes, and the layer structure of the output - extra layers in B or C that A doesn't have are simply ignored. For every tensor in A, the node loads the matching tensors from B and C, applies the selected recipe, and writes the result. It streams per-tensor by default (lazy_load on, cache cleared between layers), so multi-GB encoders merge without blowing up RAM.

    Four recipes, all borrowed from the old SuperMerger world:

    • Add-Difference - A + (B - C) * α. The classic: add the difference between two models to a base. The canonical use is style transfer - B is the styled model, C is the style's base, A is your target.
    • Train-Difference - a fancier scaling of the same idea based on relative tensor distances.
    • Extract-Features - finds features present in both (B - A) and (C - A) and adds them to A, weighted by cosine similarity.
    • Add-Dissimilarities - the inverse: finds what's dissimilar between B and C relative to A and adds that.

    The inputs that matter

    • execution_mode - start here. DOCUMENTATION ONLY returns the exact formula and what each coefficient does without loading a single file. MERGE actually writes the result. It's the pack's escape hatch from its own complexity.
    • model_a / model_b / model_c - dropdowns from text_encoders. A is the anchor; think about which one that is.
    • calc_mode - the four recipes above.
    • alpha - the one coefficient that means something in every mode. The other six (beta through zeta) are each used by some modes and ignored by others; the documentation output tells you which.
    • mismatch_mode - skip (missing layers use A's values, default), zeros, or error. Leave it on skip.
    • save_dtype and override_dtype - without override, higher-precision tensors stay high-precision even if you pick fp16; flip override to force everything down.
    • output_filename - the new file's name in text_encoders/.

    Outputs are output_filename (a string) and documentation (a string with the recipe reference).

    Installing it

    Same pack as everything else here - the Model Utility Toolkit. ComfyUI Manager, search "Model Utility Toolkit," install, restart. Or:

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

    Its requirements.txt (unifiedefficientloader, plus av, mutagen, requests, Pillow for sibling nodes) is modest, and the merger itself is pure torch. Keep ComfyUI current since these nodes use the newer node API.

    Where people get burned

    • Merging across encoder families produces silent nonsense. A CLIP and a T5 have almost no shared key names, so the output - which always matches A's structure - is basically A with a few padded strangers. Same-family merges only: CLIP-with-CLIP, not CLIP-with-Qwen - encoders are architecture-bound, and a vector from one vocabulary binds to nothing in another.
    • Shape mismatch confusion. pad/crop is the default and usually right; interpolate is there for same-family models with slightly different dimensions. If your output looks structurally wrong, check which one you're on.
    • OOM on big LLM encoders. Keep lazy_load on and don't fight it; process_device set to cuda will retry an OOM tensor on CPU, which is slower but won't crash you.
    • Don't guess the coefficients. Run DOCUMENTATION ONLY once, read the output, then merge. The seven-coefficient interface is this node's worst first impression, and the documentation string is the answer.

    Honest verdict: for most people the 2-model version in the same pack covers every real use case, and this three-way node is for people who genuinely enjoy model surgery. If that's you, it's a genuinely good scalpel.

    CategoryModelUtils/Merging

    Inputs (23)

    NameTypeDefaultDescription
    execution_modeCOMBOMERGE writes the selected result; DOCUMENTATION ONLY returns the operation reference without loading model files.
    model_aCOMBOPrimary text encoder; anchors metadata, tensor shapes, and values preserved by exclusions or skip handling.
    model_bCOMBOSecond text encoder contributing to the selected calculation mode.
    model_cCOMBOThird text encoder contributing to the selected three-model calculation mode.
    calc_modeCOMBOThree-model operation to apply per comparable tensor; DOCUMENTATION ONLY shows its formula and coefficient meanings.
    mismatch_modeCOMBOskipHandle missing or incompatible tensors: preserve Model A, substitute zeros where supported, or abort with an error.
    alignment_modeCOMBOpad/cropResolve compatible shape differences by zero-padding/cropping or by interpolating Model B and Model C to Model A shape.
    alphaFLOAT0.50-10–10Mode-specific coefficient; use DOCUMENTATION ONLY for its exact role in the selected calculation mode.
    betaFLOAT0.50-10–10Mode-specific coefficient; some calculation modes ignore it. See DOCUMENTATION ONLY for the selected formula.
    gammaFLOAT0.990-10–10Mode-specific coefficient; some calculation modes ignore it. See DOCUMENTATION ONLY for the selected formula.
    deltaFLOAT2.00-10–10Mode-specific coefficient; some calculation modes ignore it. See DOCUMENTATION ONLY for the selected formula.
    epsilonFLOAT0.01-10–10Mode-specific coefficient; some calculation modes ignore it. See DOCUMENTATION ONLY for the selected formula.
    zetaFLOAT0.00-10–10Mode-specific coefficient; some calculation modes ignore it. See DOCUMENTATION ONLY for the selected formula.
    seedINT00–18446744073709550000Random seed used only by calculation modes with stochastic behavior.
    output_filenameSTRINGmerged_3_textencoderOutput filename without extension, written under the matching ComfyUI model directory.
    save_dtypeCOMBOOutput tensor dtype; when Override Dtype is disabled, source tensors with higher precision remain at that precision.
    process_deviceCOMBODevice used for per-tensor merge arithmetic; CUDA out-of-memory retries the affected tensor on CPU.
    exclude_patternsSTRINGNewline-separated regex or glob patterns for tensors excluded from merging and preserved from Model A.
    discard_patternsSTRINGNewline-separated regex or glob patterns for tensors omitted entirely from the output.
    glob_patternsBOOLEANfalseWhen True, exclude/discard patterns use glob syntax (* = any sequence, dots are literal). When False (default), patterns are Python regex matched as substrings.
    lazy_loadBOOLEANtrueLow memory mode: load tensors from disk on demand
    force_clear_cacheBOOLEANtrueClear CUDA cache after each layer
    override_dtypeBOOLEANfalseForce the entire model to be saved as the selected save_dtype. If False (default), higher precision dtypes are preserved.

    Outputs (2)

    NameTypeDescription
    output_filename*
    documentationSTRING