Nodes/ComfyUI-BridgeLab/SD1.5 To SDXL Embedding Converter
ComfyUI Node

SD1.5 To SDXL Embedding Converter

Your favorite SD1.5 embedding isn't dead — this node ports it to SDXL

By Kentskooking·Created 5 months ago·Updated a day ago· 1
SD1.5 To SDXL Embedding Converter
    • embedding_name
    • embedding_path
    • fit_token_cosine
    • validation_hidden_cosine
    • validation_pooled_cosine
    • report
    sd15_embedding
    sdxl_checkpoint
    output_name
    overwritefalse
    run_ci_validationtrue
    validation_phrase_count128
    validation_batch_size32

    The standard advice when someone asks how to use an SD1.5 embedding on SDXL is a shrug. Ask on r/StableDiffusion and the top answer is blunt: "You don't. At best they will have added a little noise." That's not laziness, it's physics. SD1.5's text encoder is CLIP-L, and a textual inversion is just a small vector parked in that encoder's embedding space. SDXL runs two encoders - CLIP-L plus the much bigger OpenCLIP-G - and merges their outputs. Your old embedding only has the CLIP-L half, so on SDXL it either gets ignored or quietly degrades into noise. This node, from the small ComfyUI-BridgeLab pack, is the honest attempt to build the missing half.

    What it actually does: keeps your SD1.5 CLIP-L vectors untouched and synthesizes the CLIP-G vectors from scratch, then writes a proper SDXL .safetensors embedding into your models/embeddings folder. And it doesn't guess. It loads the SDXL checkpoint you pick, reads both of that checkpoint's token-embedding tables (CLIP-L and CLIP-G), and fits a transform between the two spaces - a scaled orthogonal Procrustes solve over the cross-covariance matrix. Your vectors get pushed through that transform into CLIP-G's space. It's a projection, not a retrain, so a converted embedding won't behave identically to one trained natively on SDXL. But it's a principled projection, and it's the same family of idea as the "convert your 1.5 LoRA to SDXL" tools people passed around in 2024.

    The fit is cached per checkpoint in cache/alignments/, keyed on the checkpoint file's size and mtime. Convert ten embeddings against the same checkpoint and the expensive part runs exactly once.

    The inputs you'll actually touch: sd15_embedding (dropdown of your embeddings - must be a real SD1.5 textual inversion, 768-wide CLIP-L; anything already-SDXL is rejected rather than mangled), sdxl_checkpoint (the checkpoint whose CLIP-G space you're converting into - switch checkpoints and it refits), and output_name if you don't like the automatic _sdxl suffix. overwrite decides whether an existing output gets replaced. run_ci_validation defaults on: it samples phrases from the bundled CLIP Interrogator word lists, encodes them both ways, and reports cosine scores so you can tell a good conversion from a bad one.

    The outputs are strings and floats you mostly read, not wire: embedding_name, embedding_path, fit_token_cosine, validation_hidden_cosine, validation_pooled_cosine, and a report. The real product is the file - the node clears ComfyUI's embedding list cache after saving, so you can drop it in the positive prompt as embedding:name without restarting. It's an output node; you can literally drop it into any workflow, hit run, and get a file.

    Install is ComfyUI Manager (search "ComfyUI-BridgeLab") or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/Kentskooking/ComfyUI-BridgeLab
    

    then restart. No pip step, no model downloads - it runs on the torch and safetensors ComfyUI already ships. The node lives under the "embed_converter" menu.

    Two gotchas worth knowing. First, validation fails up front if it can't find the phrase files - they're bundled in data/clip_interrogator (with an ATTRIBUTION.md), with a fallback to eden_comfy_pipelines, so this only bites on a stripped-down install; flip run_ci_validation off and the conversion still works. Second, the cache is tied to the exact checkpoint file. Update or re-download the checkpoint and you'll eat one fresh fit.

    Honest take: embeddings are a dying format - about one new textual inversion published for every ~970 LoRAs in the first half of 2026, per our knowledge base - so you're doing this for a handful of favorites, not your whole library. But it's free, it's local, and it beats the shrug.

    Categoryembed_converter

    Inputs (7)

    NameTypeDefaultDescription
    sd15_embeddingCOMBO0 options:
    sdxl_checkpointCOMBO0 options:
    output_nameSTRING
    overwriteBOOLEANfalse
    run_ci_validationBOOLEANtrue
    validation_phrase_countINT12816–4096
    validation_batch_sizeINT321–256

    Outputs (6)

    NameTypeDescription
    embedding_nameSTRING
    embedding_pathSTRING
    fit_token_cosineFLOAT
    validation_hidden_cosineFLOAT
    validation_pooled_cosineFLOAT
    reportSTRING