Nodes/LoRA Optimizer/LoRA Optimizer
ComfyUI Node

LoRA Optimizer

Stop your stacked LoRAs from fighting each other

By ethanfel·Created 5 months ago·Updated 23 days ago· 135
LoRA Optimizer
  • model
  • lora_stack
  • clip
  • tuner_data
  • settings
  • model
  • clip
  • analysis_report
  • tuner_data
  • lora_data
output_strength1.00
clip_strength_multiplier1.00

Stack two or three LoRAs the normal way and you'll eventually hit the same wall: oversaturated colors, melted detail, a face that looks like it's fighting the style LoRA for control of the canvas. That's not you doing it wrong - it's two adapters editing the same weights in ways that partially cancel or double up, and a plain strength slider can't fix it because the conflict isn't uniform across the model. It's dense in some layers and absent in others. LoRA Optimizer is the node that actually looks at where the conflicts are and resolves them per layer instead of asking you to eyeball a global compromise.

This is the node the whole pack is built around. Everything else - the Stack nodes, the Settings nodes, the AutoTuner - either feeds it or extends it.

How it works

Connect a MODEL and a lora_stack (from LoRA Stack or LoRA Stack (Dynamic)) and it runs a two-pass analysis: pass one samples conflict and magnitude statistics across the model without holding full diffs in memory, pass two recomputes each target group's diff, decides on a merge strategy for that specific group, and merges it. A layer only one LoRA touches gets that LoRA's full, undiluted effect. A layer two LoRAs touch and mostly agree on gets averaged. A layer where they genuinely fight gets TIES-Merging (trim, elect sign, disjoint merge) - the same technique from a NeurIPS 2023 paper, repurposed here for LoRA diffs instead of full model weights. Nothing is decided globally by default; per_prefix mode (the default, tunable via the Settings node) means the strategy can and does vary block by block.

One real-world data point on why this matters: someone on r/StableDiffusion pushed back that the optimizer must be "presupposing all LoRAs are trained to a normalized 1.0," and the pack's author corrected them directly - it's not balancing on a global weight total, it's measuring how much each LoRA actually shifts the individual model keys at whatever strength you set. That's the mechanism, not marketing.

The inputs and outputs that matter

  • model - your base checkpoint's MODEL output. lora_stack - the merge candidates, from a Stack node.
  • output_strength (default 1.0) - master volume on the merged result. Set it to -1 for auto, and the optimizer picks a sensible max strength instead of you guessing.
  • clip (optional) - connect it if you want LoRAs to also affect prompt understanding, not just the image. Leave it disconnected for video models with no CLIP.
  • clip_strength_multiplier - separate volume knob for the text-encoder side; lower it to keep the visual effect while easing off how much the LoRAs bend your prompts.
  • tuner_data (optional) - feed in results from a LoRA AutoTuner or Load Tuner Data node to use its winning config instead of defaults.
  • settings (optional) - connect a LoRA Optimizer Settings node for full manual control; it overrides tuner_data and the built-in defaults.

Outputs: model/clip go straight to your sampler. analysis_report is a STRING - wire it to a Show Text node to see exactly which strategy was used per block and why. tuner_data and lora_data are for chaining into a Merge Selector or Save Merged LoRA node later.

How to install it

ComfyUI Manager: search "LoRA Optimizer", install, restart. Manually:

cd ComfyUI/custom_nodes/
git clone https://github.com/ethanfel/ComfyUI-LoRA-Optimizer.git

Restart - it lands under loaders. No models to download; it operates on the LoRA files and checkpoint you already have loaded.

Common issues & troubleshooting

Don't put distillation or edit LoRAs in the stack. The README is explicit about this: LCM, Lightning, Turbo, Hyper, DPO LoRAs, and instruction-editing LoRAs (Qwen Edit, Klein edit) have precisely calibrated weights that merging can break. Apply those with a normal Load LoRA node upstream, and only feed your style/character LoRAs into the optimizer.

The optimizer only sees its own stack. It can't detect LoRA patches from an upstream Load LoRA node, and it can't detect a LoRA already baked into a checkpoint. If you want to capture an existing Load LoRA chain instead of rebuilding it as a Stack, that's what LoRA Optimizer (Inline Chain) is for.

Results look flat or over-averaged. If everything's blending into mush instead of resolving cleanly, try a LoRA Optimizer Settings node with merge_refinement set to refine - it's cheap and often fixes exactly this.

High-conflict stacks (e.g. two very similar character LoRAs). The default heuristics handle most stacks well, but genuinely near-duplicate LoRAs (two checkpoints from the same training run) are an edge case the pack treats specially - see the Conflict Editor's consensus strategy if output_strength=-1 and defaults aren't cutting it.

CategoryLoRA Optimizer

Inputs (7)

NameTypeDefaultDescription
modelMODELYour base model (e.g. SDXL, Flux). The merged LoRAs will be applied to it.
lora_stackLORA_STACKConnect your LoRA Stack node here — this is the list of LoRAs you want to merge together.
output_strengthFLOAT1.00-1–10Master volume for the merged result. 1.0 = full effect, 0.5 = half. Set to -1 for auto: the optimizer picks a good strength for you.
clipoptCLIPConnect your text encoder so LoRAs can also affect how prompts are understood. Leave empty for video models.
clip_strength_multiplieroptFLOAT1.000–10How strongly LoRAs affect text understanding. At 1.0, same strength as the model. Lower values reduce LoRA influence on prompts while keeping the visual effect.
tuner_dataoptTUNER_DATAConnect results from a LoRA AutoTuner or Load Tuner Data node. The optimizer will use the best settings found by the tuner instead of defaults.
settingsoptOPTIMIZER_SETTINGSConnect a Settings node (Optimizer Settings or AutoTuner Settings) for full control. Takes priority over tuner_data and defaults.

Outputs (5)

NameTypeDescription
modelMODEL
clipCLIP
analysis_reportSTRING
tuner_dataTUNER_DATA
lora_dataLORA_DATA