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_00…IN_11, M__00, OUT00…OUT11): 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—