Nodes/ComfyUI-NynxzNodes/Model Merge by Depth
ComfyUI Node

Model Merge by Depth

One model's composition, another model's textures

By Nynxz·Created 12 months ago·Updated 9 days ago· 4
Model Merge by Depth
  • model_a
  • model_b
  • model
◄early1.00►
◄late0.00►
◄crossover21►
◄softness8►

In a diffusion transformer, depth does different jobs. The early blocks settle what's in the picture and where - layout, composition, the big shapes. The late blocks handle what it looks like - texture, skin, fine detail. Merge two fine-tunes of the same base block by block, and you can take one model's sense of composition and another's sense of surface.

Model Merge by Depth does exactly that graft, with a smooth crossover instead of a hard cut. The author's own example is the one to copy: MOSS-Image, with the SFT checkpoint as model A for composition and Base as model B for realism. SFT follows instructions but looks SFT-ish; Base looks real but wanders off the prompt. Run the blend and you get prompt compliance with a photograph's surface.

The four numbers

model_a and model_b in, model out. Nothing else. The work is in the numbers, and there are four of them.

early is model A's share in the first blocks - 1 means all A at the top of the stack. late is A's share at the bottom; 0 means all B. The defaults (1 and 0) describe a clean graft: A owns the start, B owns the end.

crossover is the block where the blend sits halfway, and it's a block number, not a percentage. MOSS-Image has 42 blocks (0–41), so the default of 21 is dead centre. Because it's a block index you need to know your model's depth - Krea 2, MOSS, Flux 3 and the rest don't agree on this.

softness is how many blocks either side of the crossover the transition takes, default 8. Set it to 0 for a hard cut. A hard cut is a legitimate experiment, and it's also how you'll hear the seam in an image: fine detail snapping on mid-picture looks like a rendering artefact, not a merge.

The curve is a logistic sigmoid, so the change is gradual at both ends and steepest at the crossover - which is what you want, since blocks nearest the middle are the least load-bearing for either job.

What happens to the weights that aren't in a block

This is the part that separates a working merge from a mess, and it's usually invisible in other merge nodes. Not every weight lives in the block stack. The output head - its final norm, projection and modulation together - goes with the last block, so it takes the late share. The input embedder goes with the first, so it takes early.

Everything a block reads rather than contains - shared modulations, the time embedder, the text embedder - takes the stack's average share, not one end's. That's a deliberate choice: hand a shared weight to model B and every block in the merge suddenly reads its conditioning through B, which quietly undoes the whole point of the graft.

It also means the node works out block depth from the weight names themselves (layers, blocks, single_blocks, double_blocks, transformer_blocks), so it isn't guessing from a fixed architecture.

Install

Same pack as the rest:

comfy node install comfyui-nynxz-nodes

Or search Nynxz in ComfyUI Manager, or:

cd ComfyUI/custom_nodes
git clone https://github.com/Nynxz/ComfyUI-NynxzNodes
cd ComfyUI-NynxzNodes
pnpm install && pnpm build

Restart. No Python dependencies - the blend is pure weight maths over what ComfyUI already loaded. ZenKit is optional.

Practical notes

Have the VRAM conversation with yourself before you start. Both checkpoints are loaded to merge them, so a 12B pair is a 12B-and-a-bit problem, and then you sample the result. On a tight card, merge once, save the result as a checkpoint if your pack allows it, and reload it for generation.

Keep a fixed seed and a fixed prompt while you sweep crossover. The differences between crossover 14, 21 and 28 are real but subtle, and with a random seed you'll be looking at noise, not at your merge.

Don't expect this to fix a mismatched pair. Both inputs must be fine-tunes of the same base architecture - same block count, same weight names. Merging two different architectures isn't a tough blend, it's a shape error, and you'll know.

And if the result looks like neither model, check early and late before anything else. It's easy to nudge late up to 0.3 while chasing detail and end up with two models arguing over the last third of the stack.

CategoryNynxz/Model Merging

Inputs (6)

NameTypeDefaultDescription
model_aMODELThe early blocks' model, e.g. MOSS SFT.
model_bMODELThe late blocks' model, e.g. MOSS Base.
earlyFLOAT1.000–1Model A's share in the first blocks (1 = all A).
lateFLOAT0.000–1Model A's share in the last blocks (0 = all B).
crossoverINT210–200The block where the blend is halfway. MOSS has 42 blocks (0-41).
softnessINT80–100How many blocks either side the crossover takes. 0 = a hard cut.

Outputs (1)

NameTypeDescription
modelMODEL—