Nodes/ComfyUI-Inference-Core-Nodes/Inference_Core_ModelMergeSDXL
ComfyUI Node

Inference_Core_ModelMergeSDXL

Block-weighted checkpoint merging for SDXL

By LykosAI·Created 2 years ago·Updated about a year ago· 33
Inference_Core_ModelMergeSDXL
  • model1
  • model2
  • MODEL
time_embed.1.00
label_emb.1.00
input_blocks.01.00
input_blocks.11.00
input_blocks.21.00
input_blocks.31.00
input_blocks.41.00
input_blocks.51.00
input_blocks.61.00
input_blocks.71.00
input_blocks.81.00
middle_block.01.00
middle_block.11.00
middle_block.21.00
output_blocks.01.00
output_blocks.11.00
output_blocks.21.00
output_blocks.31.00
output_blocks.41.00
output_blocks.51.00
output_blocks.61.00
output_blocks.71.00
output_blocks.81.00
out.1.00

This is the SDXL counterpart to Inference_Core_ModelMergeBlockNumber, and the reason they're separate nodes rather than one universal merger: SDXL's UNet is built differently from SD1.5's. It trades block count for block width - fewer, chunkier blocks doing more work each - so the two architectures don't share a block-naming scheme, and a merge node built for one can't just be pointed at the other. Model Merge SDXL gives you the same per-block ratio control as the SD1.5 node, sized to match SDXL's actual layout.

What it gives you over a plain global merge

ComfyUI's built-in checkpoint merger has one dial: how much of model B to blend into model A, applied uniformly across the whole network. That's fine for a quick blend, but it can't express "keep model1's composition but pull in model2's style" - for that you need control over which part of the network gets which model's influence, and that's what per-block merging is for. This node exposes SDXL's blocks individually - the time and label embeddings, input_blocks.0 through input_blocks.8, middle_block.0 through middle_block.2, output_blocks.0 through output_blocks.8, and the final out. layer - each as its own FLOAT ratio (0 to 1, step 0.01, default 1).

Each slider means "how much of model2 to mix in at that block." All sliders at 0 gives you model1 back unchanged; all at 1 gives you model2 back unchanged. The output is a single merged MODEL, ready to drop into a KSampler exactly like any normal checkpoint.

If you find yourself needing to go finer than block-level - controlling individual attention layers inside a specific transformer block rather than a whole block at once - this pack also ships Inference_Core_ModelMergeSDXLDetailedTransformers for that more surgical level of control. Start here; escalate to that one only if block-level granularity genuinely isn't precise enough for what you're trying to do.

Setting expectations

Checkpoint merging has a well-known ceiling, and it's worth knowing before you spend an afternoon tuning ratios: blending two models with genuinely different training distributions - a photorealistic SDXL checkpoint and an anime-focused one, for instance - tends to produce something weaker at both rather than the best of each. That's exactly the problem the community ran into at scale once Pony-based merges exploded on CivitAI, and per-block control like this node offers is a real mitigation (keep the blocks that matter from your preferred model, dilute the rest less), not a way to sidestep the underlying tension entirely.

Installing it

Bundled with the pack. ComfyUI Manager: search "ComfyUI-Inference-Core-Nodes". Manually:

cd ComfyUI/custom_nodes
git clone https://github.com/LykosAI/ComfyUI-Inference-Core-Nodes

then install.py, or pip install -e . and restart - no acceleration extras needed, this node does tensor arithmetic on already-loaded checkpoints, not model inference.

Troubleshooting

Feed this node an SD1.5 checkpoint by mistake and you'll hit a tensor-shape crash immediately rather than a subtle bad merge - the block dimensions genuinely don't match. Assuming both models are actually SDXL, the more common issue is a merge that's technically valid but disappointing: mushy, weaker-at-both results are the quality-dilution problem, not a sign the node malfunctioned. Try leaning ratios more heavily toward whichever model should dominate a given block rather than splitting evenly, and expect a few rounds of iteration before you land on a merge you're happy with.

Categoryadvanced/model_merging

Inputs (26)

NameTypeDefaultDescription
model1MODEL
model2MODEL
time_embed.FLOAT1.000–1
label_emb.FLOAT1.000–1
input_blocks.0FLOAT1.000–1
input_blocks.1FLOAT1.000–1
input_blocks.2FLOAT1.000–1
input_blocks.3FLOAT1.000–1
input_blocks.4FLOAT1.000–1
input_blocks.5FLOAT1.000–1
input_blocks.6FLOAT1.000–1
input_blocks.7FLOAT1.000–1
input_blocks.8FLOAT1.000–1
middle_block.0FLOAT1.000–1
middle_block.1FLOAT1.000–1
middle_block.2FLOAT1.000–1
output_blocks.0FLOAT1.000–1
output_blocks.1FLOAT1.000–1
output_blocks.2FLOAT1.000–1
output_blocks.3FLOAT1.000–1
output_blocks.4FLOAT1.000–1
output_blocks.5FLOAT1.000–1
output_blocks.6FLOAT1.000–1
output_blocks.7FLOAT1.000–1
output_blocks.8FLOAT1.000–1
out.FLOAT1.000–1

Outputs (1)

NameTypeDescription
MODELMODEL