ComfyUI Node

MergeBlockWeighted

25 sliders, two checkpoints, one merged SD1.5 model

By YinBailiang·Created 3 years ago·Updated 2 years ago· 15
MergeBlockWeighted
  • model0
  • model1
  • MODEL
base_alpha0.00
IN_000.00
IN_010.00
IN_020.00
IN_030.00
IN_040.00
IN_050.00
IN_060.00
IN_070.00
IN_080.00
IN_090.00
IN_100.00
IN_110.00
M__000.00
OUT000.00
OUT010.00
OUT020.00
OUT030.00
OUT040.00
OUT050.00
OUT060.00
OUT070.00
OUT080.00
OUT090.00
OUT100.00
OUT110.00

This is the ComfyUI port of the old A1111 "merge block weighted" (MBW) method, and it's a time capsule. Instead of one global ratio when you combine two checkpoints, it hands you a slider for every block of the U-Net - 12 input, 1 middle, 12 output - so you can take one model's early layers and the other model's fine detail, then eyeball the result without re-exporting a checkpoint. Block-merging talk was everywhere in 2023, the SD1.5 merge era that built half of CivitAI; by 2025 it had mostly died out as LoRA and full training took over. If you still have two 1.5 checkpoints you want to breed, this node does the job with a granularity the built-in tooling never gave you.

How it works

The code is refreshingly transparent. It deep-copies model0, walks every tensor in its state dict, and blends it with model1's version using

theta_0[key] = (1 - alpha) * theta_0[key] + alpha * theta_1[key]

where alpha comes from the block your tensor belongs to: time_embed rides IN_00, input_blocks.X maps to IN_XX, the middle block maps to M__00, output_blocks.X maps to OUTXX, and the final conv out layer is folded into OUT11. Anything outside the U-Net - the CLIP text encoder and VAE - uses base_alpha instead. When it's done, it copies over any model1 layers that model0 doesn't have and loads the blended weights back into the copy.

The one wrinkle to internalize: base_alpha does not touch the U-Net. It only governs the non-diffusion parts. The 25 block sliders are the whole show.

The inputs that matter

Only three things need explaining to a beginner:

  • model0 / model1 (MODEL): wire in two CheckpointLoaderSimple outputs. model0 is the base that gets copied; model1 is what you're pulling traits from.
  • base_alpha (0–1, default 0): how much of model1's CLIP and VAE to keep. Leave at 0 and you get model0's text encoder and VAE.
  • The 25 sliders (IN_00IN_11, M__00, OUT00OUT11): 0 = fully model0's block, 1 = fully model1's. Early IN blocks control structure and composition; later OUT blocks carry style and fine detail.

The output is a single MODEL. Wire it straight into a sampler - or into a Save Checkpoint node with a CLIP and VAE if you want to keep the result as a file, since this node is runtime-only and never writes a .safetensors itself.

The trap

Every slider defaults to 0. Feed in two models, hit run, and you get model0 back verbatim - that "nothing happened" moment is the #1 way people bounce off this node. Raise the weights before you judge it. Also keep in mind the memory math: it holds both models plus a full deep copy and a blended state dict, so you're juggling a few GB of SD1.5 weights in RAM. That's fine on a modern machine; it's why you don't want to feed it anything bigger.

Install

Here's the awkward part. The original repo was deleted from GitHub - the canonical URL 404s as of this writing, so ComfyUI Manager can't find the pack and git clone of the original fails. The code still lives in forks and mirrors:

cd ComfyUI/custom_nodes
git clone https://github.com/Nezarik-Intmax/MergeBlockWeighted_fo_ComfyUI
# or the GitCode mirror: https://gitcode.com/fengya011/MergeBlockWeighted_fo_ComfyUI

Restart ComfyUI and the node appears under the MergeBlockWeighted category. No requirements.txt, no model downloads, no API keys - it only imports torch, numpy, PIL and tqdm, all already bundled with ComfyUI.

Troubleshooting

  • Output identical to model0 - the defaults are all zeros. Start with base_alpha where you want it, then push a few OUT blocks toward 1 and work backwards.
  • Weird results on non-SD1.5 models - the 12/1/12 block layout is hard-coded. SDXL's blocks don't line up and Flux has no input_blocks at all, so the mapping silently drifts and you'll mostly get base_alpha applied everywhere. This is an SD1.5 node, full stop.
  • OOM on a small card - two loaded checkpoints plus a deep copy is the price of admission. SD1.5 is small enough that it usually just means a slow merge (watch the Stage 1/2 and Stage 2/2 progress bars).

Should you use it?

Honest answer: as of now it's a curiosity. ComfyUI ships a built-in ModelMergeBlocks node that does the same family of thing with three coarse stage ratios, and if you're serious about merge recipes you want something like ljleb/comfy-mecha, which reproduces MBW behavior and then some. This one is for the person who grew up on the A1111 GUI, wants 25 genuine per-block sliders, and doesn't mind an unmaintained relic. It works - just know what you're picking up.

CategoryMergeBlockWeighted

Inputs (28)

NameTypeDefaultDescription
model0MODEL
model1MODEL
base_alphaFLOAT0.000–1
IN_00FLOAT0.000–1
IN_01FLOAT0.000–1
IN_02FLOAT0.000–1
IN_03FLOAT0.000–1
IN_04FLOAT0.000–1
IN_05FLOAT0.000–1
IN_06FLOAT0.000–1
IN_07FLOAT0.000–1
IN_08FLOAT0.000–1
IN_09FLOAT0.000–1
IN_10FLOAT0.000–1
IN_11FLOAT0.000–1
M__00FLOAT0.000–1
OUT00FLOAT0.000–1
OUT01FLOAT0.000–1
OUT02FLOAT0.000–1
OUT03FLOAT0.000–1
OUT04FLOAT0.000–1
OUT05FLOAT0.000–1
OUT06FLOAT0.000–1
OUT07FLOAT0.000–1
OUT08FLOAT0.000–1
OUT09FLOAT0.000–1
OUT10FLOAT0.000–1
OUT11FLOAT0.000–1

Outputs (1)

NameTypeDescription
MODELMODEL