Normalize Model
Two models, different scales — normalize before you merge
- model_a
- model_b
- MODEL
Fine-tunes of the same base model don't all sit at the same scale. One checkpoint might have beefier weights in the attention blocks, another in the feed-forward layers - and when you merge two models that are speaking different magnitudes, the blend can wobble even though each parent is fine on its own. DM_NormalizeModel is DareMerge's answer: it rescales one model's parameter norms toward another's so the merger is combining like with like.
How it works
Feed it two models, model_a and model_b. It computes the ratio of the norms between corresponding parameters, then scales model_a's weights by that ratio (via model_b's, if you flip magnify to on). The output is a patched clone of model_a - so you chain it in front of a merger node, not instead of one. This isn't a merge, it's a preconditioner.
The method dropdown is where the thinking happens:
- attn_only (default) - only scales Q and K relative to each other, and nothing else. The README's pitch: "You should see no difference in the model's performance, but it might make the merge more stable." That's the one to try first, because it's the least invasive.
- q_norm - scales the whole attention stack (Q, K, and the output projection) using Q as the reference.
- all - normalizes weight+bias pairs across the board, the broadest sweep.
- none - passes
model_athrough untouched (mostly useful as a baseline when you're testing whether normalization is even doing anything).
Where it fits in a workflow
If you're doing an advanced or DARE merge, the standard chain is: load both checkpoints, run model_a through Normalize Model, then feed the normalized result plus model_b into the merger. The normalization happens once, then you can sweep merge ratios without re-running it. It's especially worth trying when you're merging models that are related but trained differently - the kind of merge that's "mostly fine but the hands are weird" and you're not sure why.
The honest caveats
- The key-group logic is built around SD1.5. The node's layer targeting (
generate_key_groups_sd15) explicitly spells out SD1.5's architecture. On SDXL, many of those groups simply won't match and get skipped - so treat this as an SD1.5-first tool and test carefully if you're on SDXL. - It's subtle by design. If you're expecting a night-and-day change, you'll be disappointed. Normalization is the kind of thing that quietly moves a merge from "almost" to "there," not something that transforms the output. The README says as much - the selling point is stability, not visible difference.
- Magnify is experimental. Flipping it inverts the scaling direction; the README frames the whole normalization approach as "testing out a new method," so expect the rougher edges.
Installing it
One of ~25 nodes in the 54rt1n/ComfyUI-DareMerge pack. Install the pack once via ComfyUI Manager (search "ComfyUI-DareMerge") or:
cd ComfyUI/custom_nodes
git clone https://github.com/54rt1n/ComfyUI-DareMerge
then restart ComfyUI. Dependencies (matplotlib, numpy, torch, pillow) are standard ComfyUI fare; no model files to download.
The bottom line: this is the "try the boring fix first" node. When a merge is unstable and you've already fiddled with ratios, a quick normalization pass is cheap insurance - and attn_only is deliberately safe enough to leave in the pipeline permanently.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| model_a | MODEL | — | |
| model_b | MODEL | — | |
| method | COMBO | attn_only | 4 options: q_norm, all, none, attn_only |
| magnify | COMBO | off | 2 options: off, on |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | — |