NP-LoRA Loader (Subject + Style)
Make your character and style LoRAs stop fighting each other
- model
- clip
- model
- clip
- merge info
You've got a character LoRA that's perfect on its own and a style LoRA that's perfect on its own, and the moment you stack them at full strength they fight each other. The character's face melts, or the style vanishes, or you spend an hour nudging two strength sliders that keep fighting back. That's the exact problem NP-LoRA Loader (Subject + Style) is built for. Instead of adding both LoRAs' updates blindly and letting them collide, it projects the content LoRA's overlap with the style LoRA out before merging, so the style gets to own its directions and the subject keeps what's left. One node in, merged model and CLIP out.
What it's actually doing
The loader is a runtime implementation of NP-LoRA's Eq. 12 (from the NP-LoRA paper). When two LoRAs patch the same layer, both updates push on the same weight space and one can eat the other. NP-LoRA's trick: compute the style update's right-singular-subspace basis (the directions the style actually uses), then subtract the component of the content update that lives in those directions, scaled by a knob called mu:
D_merged = D_style + D_content (I - mu/(1+mu) · V·Vᵀ)
Set mu = 0 and that's a plain additive merge - same thing your basic LoRA merger does. Raise mu and the content gets progressively purged of the style's directions, which stops the two from double-pushing. The implementation is honest about it: it handles conventional linear and 1×1-conv LoRA factors (both Kohya lora_down/lora_up and Diffusers lora_A/lora_B naming), re-factorizes the merged delta into a standard LoRA state dict, and hands it to ComfyUI's own load_lora_for_models. Spatial LoCon kernels, DoRA, LoHa, LoKr and friends are deliberately skipped with a console warning - it can't safely SVD those, and it'd rather tell you than silently mangle them.
The inputs that matter
Only a few knobs exist, and you'll mostly touch two.
content_lora- your subject/character LoRA, the one you want to preserve.style_lora- the style LoRA whose subspace gets protected.mu(default 0.5, range 0–100) - the whole ballgame. Start at 0.5. Style too weak? Turn it up. Subject details washing out? Turn it down. The README's advice is sound:mu = 0is a direct merge, so it's your "what would the boring merge give me" baseline.
There are also four strength sliders - content_strength_model, style_strength_model, content_strength_clip, style_strength_clip - because CLIP-side adapters get their own separate weights. Defaults are 1.0 and you'll rarely need them until you've tuned mu first.
Outputs: model and clip, ready to wire into your sampler exactly like a normal LoraLoader, plus a merge info string that tells you how many adapters were fused and how many got skipped (see the console for why).
Install and first run
This ships in the ComfyUI-LoRA-Merge-EXPERIMENTAL pack, along with two SSR-Merge nodes. Easiest path is ComfyUI Manager - search "LoRA Merge EXPERIMENTAL" - or:
cd ComfyUI/custom_nodes
git clone https://github.com/hybskgks28275/ComfyUI-LoRA-Merge-EXPERIMENTAL
Restart ComfyUI and the nodes appear under loaders/LoRA. There's no requirements.txt and no model downloads - it runs on stock ComfyUI dependencies (torch, comfy.sd, folder_paths). One real gotcha: the pack targets ComfyUI's newer V3 extension API (comfy_entrypoint). If the nodes don't show up after install, your ComfyUI is too old - update ComfyUI itself first. Both LoRA dropdowns read from your loras folder, so drop the files in there before you try.
Where people get burned
The two LoRAs need matching layer geometry on the layers you actually want fused; where a layer's factors don't line up, that layer is skipped with a warning, and if nothing overlaps at all the node throws "No compatible conventional LoRA up/down pairs." Also keep expectations calibrated: this is a projection-based approximation, not a retrained LoRA. If your character LoRA and style LoRA are aggressively incompatible, mu can't fix everything - but for the common "character + painterly style" case, it usually lands closer to what you actually meant than the naive merge ever does. The repo's brand new and there's zero community track record yet, so treat it as an experiment that happens to work well, not a settled tool.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| clip | CLIP | — | |
| content_lora | COMBO | Subject, character, or content LoRA to preserve. | |
| style_lora | COMBO | Style LoRA whose right-singular subspace is protected. | |
| mu | FLOAT | 0.500–100 | 0 = direct merge; higher values protect style more strongly. |
| content_strength_model | FLOAT | 1.00-20–20 | — |
| style_strength_model | FLOAT | 1.00-20–20 | — |
| content_strength_clip | FLOAT | 1.00-20–20 | — |
| style_strength_clip | FLOAT | 1.00-20–20 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| model | MODEL | — |
| clip | CLIP | — |
| merge info | STRING | — |