Nodes/ComfyUI LC Modelbuilder Nodes/LC Krea2 Block Merge Advanced
ComfyUI Node

LC Krea2 Block Merge Advanced

Stop guessing at one ratio — drag a curve across 28 blocks

By lonecatone23·Created 21 days ago·Updated 3 days ago· 3
LC Krea2 Block Merge Advanced
  • model1
  • model2
  • model
◄preset50_50►
◄edit_modesmooth►
◄smooth_radius2►
◄blocks_curve0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5►
◄first0.50►
◄tmlp0.50►
◄txtmlp0.50►
◄tproj0.50►
◄txtfusion_layer00.50►
◄txtfusion_layer10.50►
◄txtfusion_projector0.50►
◄txtfusion_refiner00.50►
◄txtfusion_refiner10.50►
◄last0.50►
◄save_name►
◄save_curvefalse►

Merging two checkpoints is a weighted average of their weights, which takes minutes and needs no training data - that's why most of what CivitAI hosts is a merge (checkpoint.json). The catch is the standard interface: one slider, one number, applied everywhere. Your model is not one uniform thing. Early blocks hold structure and identity, late blocks hold detail and finish, and averaging them all at 0.5 because you couldn't be bothered to be selective is how you get the same-face problem at scale.

LC Krea2 Block Merge Advanced replaces that single ratio with a curve you drag, one value per block, plus individually addressable sliders for the parts of the architecture that aren't blocks.

Why a curve makes sense on Krea 2 specifically

Krea 2 is a 12B single-stream diffusion transformer: one stack of architecturally uniform blocks (krea-2.json). There are 28 of them, and one continuous curve across 28 uniform blocks is a coherent thing to reason about. On a double-stream model like Flux - where blocks come in two different flavours and the text and image streams run separately - a single curve across "all blocks" means much less, which is why you don't see this UI everywhere.

The 10 named regions are the exception: first, tmlp, txtmlp, tproj, the five txtfusion.* prefixes and last are architecturally distinct from the block stack, so they each get their own slider rather than living on the curve. Those prefixes aren't invented for this node - they're the ones ComfyUI core's own ModelMergeKrea2 uses.

How the merge actually runs

No hand-rolled tensor math, and that's the best thing about this node. It builds the same prefix → ratio mapping core uses and hands it to core's ModelMergeBlocks.merge(), which goes through get_key_patches() and add_patches() with longest-prefix matching. So you're driving the exact patch path ComfyUI already ships and tests - if core's merge is correct, this is correct.

One detail the source is honest about: core's ratio is the strength of model1, not model2. The node inverts at the handoff so its own UI keeps the convention every preset and tooltip uses - 0.0 = all model1, 1.0 = all model2. Remember that if you're cross-checking against another node's numbers.

The result is a patched model, not a file. It exists for the session until you write it out with LC Checkpoint Save.

The inputs

model1 and model2 are just two loaded checkpoints. Everything else is the merge itself:

  • blocks_curve - a comma list of 28 ratios, one per block (blocks.0. through blocks.27.). This is the source of truth whenever preset says Custom. You normally don't type it; the JavaScript curve graph writes it as you drag.
  • preset - nine bundled presets plus anything you save. The combo also contains literal separator rows (────────) and a Custom entry; that's the node listing its preset folder, not a UI glitch.
  • edit_mode and smooth_radius - smooth drags one block and blends its neighbours with a falloff set by smooth_radius (default 2, 0–8); spike moves only the block under the cursor. Smooth is what you want for a usable curve; spike is for surgically moving one block.
  • the 10 named sliders, all defaulting to 0.5.
  • save_name + save_curve - type a name, flip save_curve on, and the next queue writes web/krea2_block_presets/<name>.json inside the pack folder. A preset stores the curve and all ten named sliders together.

The nine presets, and what they mean

| Preset | Idea | |---|---| | 50_50 | Flat 0.5 everywhere. The default, and the honest starting point. | | face_favor | Low→high ramp (0.15→0.75): anchor identity in early blocks, take late-block refinement from model2. | | detail_focus | Low and mid blocks pinned near model1; only high-zone blocks and last ramp toward model2. | | style_favor | Mirror of face_favor - early structure from model2, late refinement stays with model1. | | sine_wave | Two full oscillations. Exploratory, not a target. | | resonance_blocks | Spikes blocks 1, 3, 5, 7, 11, 15 to 0.85, everything else 0.3 - the "certain blocks dominate" pattern. | | even_blend | Plain linear 0→1 ramp. The baseline. | | core_focus | Gaussian bump on the mid zone, edges (and txtfusion.*) held closer to model1. | | heavy_transplant_anchored | Nearly all model2 (0.9), except block 0 and first/tproj, which stay anchored to model1 to keep structure from drifting. |

heavy_transplant_anchored is the one to reach for when you want most of a second model's character without it falling apart structurally. sine_wave is the one to run once, look at, and never use again.

Install

ComfyUI Manager: search ComfyUI LC Modelbuilder Nodes. By hand:

cd ComfyUI/custom_nodes
git clone https://github.com/lonecatone23/ComfyUI_LC_ModelBuilder_nodes

No requirements.txt and nothing to pip install for this node - it's core patching and a bit of JavaScript. Restart, then hard-refresh the browser (Ctrl+Shift+R) or the curve graph won't load and you'll be staring at a plain comma-list text field.

Where people get burned

The curve only works in the browser. The graph, the live tooltip and the preset combo are frontend JS. If you loaded the pack with an update pending, or you're driving the node headlessly, blocks_curve is all you have - and that's fine, because it's the actual parameter.

Touching anything snaps preset to Custom. That's by design; the sliders are the truth, the preset name is a label. Load your preset first, then tweak.

A wrong-length curve gets quietly fixed. If blocks_curve isn't exactly 28 values, the node interpolates it to 28 when there are at least two values, and falls back to flat 0.5 otherwise. Silent, but predictable - edit the text field and count, or drag instead of typing.

Your saved presets live inside the pack folder. web/krea2_block_presets/ is in the cloned repo, not in a user directory, so a clean reinstall or a Manager "reinstall" that deletes the folder takes your presets with it. Copy them somewhere safe once you've tuned something you like.

This node doesn't quantize or save. If you were hoping for int8/int4 output, another Krea 2 merger pack does merge + quantize in one pass. This one is deliberately just a UI over core's block merge: merge here, test in a KSampler, then write it with LC Checkpoint Save.

CategoryLC ModelBuilder/Krea2

Inputs (18)

NameTypeDefaultDescription
model1MODELRatio 0 side. Blocks/regions at 0.0 come entirely from this checkpoint.
model2MODELRatio 1 side. Blocks/regions at 1.0 come entirely from this checkpoint.
presetCOMBO50_509 bundled presets (50_50, face_favor, detail_focus, style_favor, sine_wave, resonance_blocks, even_blend, core_focus, heavy_transplant_anchored) plus anything you save yourself. Loading one sets both the 28-block curve and the 10 named sliders. Custom keeps whatever is currently dragged/typed.
edit_modeCOMBOsmoothsmooth = drag one block and blend neighbors. spike = move one block only.
smooth_radiusINT20–8Neighbor window (in blocks) for smooth mode (0 = spike-like).
blocks_curveSTRING0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5Comma list of 28 ratios (blocks.0. - blocks.27.). 0 = all model1, 1 = all model2. Source of truth when preset is Custom.
firstFLOAT0.500–1first. — earliest input/embedding weights, before block 0.
tmlpFLOAT0.500–1tmlp. — timestep-embedding MLP (timestep conditioning).
txtmlpFLOAT0.500–1txtmlp. — text-embedding MLP (text conditioning).
tprojFLOAT0.500–1tproj. — timestep projection layer.
txtfusion_layer0FLOAT0.500–1txtfusion.layerwise_blocks.0. — first text/image fusion block.
txtfusion_layer1FLOAT0.500–1txtfusion.layerwise_blocks.1. — second text/image fusion block.
txtfusion_projectorFLOAT0.500–1txtfusion.projector. — projects fused text features into the main stream.
txtfusion_refiner0FLOAT0.500–1txtfusion.refiner_blocks.0. — first fusion refiner block.
txtfusion_refiner1FLOAT0.500–1txtfusion.refiner_blocks.1. — second fusion refiner block.
lastFLOAT0.500–1last. — final output layer, after block 27.
save_nameSTRINGFilename under web/krea2_block_presets/ (no extension).
save_curveBOOLEANfalseOn run, write save_name.json into web/krea2_block_presets/.

Outputs (1)

NameTypeDescription
modelMODEL—