Inference_Core_ModelMergeSDXL
Block-weighted checkpoint merging for SDXL
- model1
- model2
- MODEL
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.
Inputs (26)
| Name | Type | Default | Description |
|---|---|---|---|
| model1 | MODEL | — | |
| model2 | MODEL | — | |
| time_embed. | FLOAT | 1.000–1 | — |
| label_emb. | FLOAT | 1.000–1 | — |
| input_blocks.0 | FLOAT | 1.000–1 | — |
| input_blocks.1 | FLOAT | 1.000–1 | — |
| input_blocks.2 | FLOAT | 1.000–1 | — |
| input_blocks.3 | FLOAT | 1.000–1 | — |
| input_blocks.4 | FLOAT | 1.000–1 | — |
| input_blocks.5 | FLOAT | 1.000–1 | — |
| input_blocks.6 | FLOAT | 1.000–1 | — |
| input_blocks.7 | FLOAT | 1.000–1 | — |
| input_blocks.8 | FLOAT | 1.000–1 | — |
| middle_block.0 | FLOAT | 1.000–1 | — |
| middle_block.1 | FLOAT | 1.000–1 | — |
| middle_block.2 | FLOAT | 1.000–1 | — |
| output_blocks.0 | FLOAT | 1.000–1 | — |
| output_blocks.1 | FLOAT | 1.000–1 | — |
| output_blocks.2 | FLOAT | 1.000–1 | — |
| output_blocks.3 | FLOAT | 1.000–1 | — |
| output_blocks.4 | FLOAT | 1.000–1 | — |
| output_blocks.5 | FLOAT | 1.000–1 | — |
| output_blocks.6 | FLOAT | 1.000–1 | — |
| output_blocks.7 | FLOAT | 1.000–1 | — |
| output_blocks.8 | FLOAT | 1.000–1 | — |
| out. | FLOAT | 1.000–1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | — |