Nodes/EasyLoRAMerger/🔬 Easy LoRA Extractor
ComfyUI Node

🔬 Easy LoRA Extractor

Have the Before and After? Get the LoRA Out of It

By Terpentinas·Created 7 months ago·Updated 4 months ago· 12
🔬 Easy LoRA Extractor
  • model
  • clip
  • model
  • clip
  • forensics
  • lora_path
checkpoint_base
checkpoint_tuned
rank_modeauto
rank64
alpha_modeauto
alpha64
svd_modeauto_energy
energy_threshold0.95
noise_thresholdingtrue
strength_multiplierauto
detection_modeauto_fast
save_triggerfalse
filenameextracted_lora
lora_formatnative
deviceauto
strength_model1.00
strength_clip1.00
save_folder/tmp/ComfyUI/models/checkpoints

You know the situation: someone trained a checkpoint on top of a base you have, and you want the difference - the character, the style, the concept - as a reusable LoRA. Or you trained one yourself and want to hand out a 100 MB adapter instead of a 7 GB file. That's exactly what the Easy LoRA Extractor does: it takes a base (before) and a fine-tuned (after) checkpoint and extracts the delta as a LoRA.

This is the same trick the "LoRA extraction" scripts and web UIs do, but wrapped as a node with the full Easy LoRAMerger treatment - SVD rank selection, noise-aware thresholding, and a forensic report at the end.

How it works

The pipeline is straightforward under the hood:

  1. Both checkpoints get normalized into a shared key space.
  2. Keys present in both with compatible shapes get matched.
  3. The delta is computed: Δ = tuned − base.
  4. Each delta matrix is decomposed with SVD into the low-rank lora_A / lora_B pair that is a LoRA.

The clever parts are the knobs around step 4. svd_mode defaults to auto_energy, which keeps the singular values that retain your chosen energy_threshold (default 0.95 - higher rank, more fidelity; lower, more compression). noise_thresholding is on by default and uses Marchenko-Pastur theory to tell real signal from noise - but the tooltip has the gotcha: turn it off for cross-model deltas, like a Turbo checkpoint vs its Base, where the "noise model" can wrongly reject genuine signal.

It also handles the bane of extraction: models that were trained with a baked-in LoRA attenuation. strength_multiplier set to auto detects that attenuation (via detection_mode - auto_fast samples 30 layers, auto_precise checks all of them) and compensates before the SVD runs.

Inputs worth setting

  • checkpoint_base - the unedited "before" state.
  • checkpoint_tuned - the "after" state whose concept you're extracting.
  • rank / rank_mode - leave rank_mode on auto and let the spectrum decide; it's the upper bound when auto.
  • lora_format - native (CivitAI-compatible diffusion_model.* keys, merged QKV) or diffusers (HuggingFace-style transformer.* keys, split QKV). Native unless you specifically need the Diffusers one.
  • save_trigger - off by default, which previews the extraction applied to an optional connected model / clip instead of writing a file.

Outputs: model and clip (the extraction applied at strength_model / strength_clip, so you can preview before saving), forensics (the extraction report), and lora_path (where the .safetensors landed once save_trigger is on).

Installing it

Same as the rest of the pack - Manager (search "Easy LoRA Merger") or:

cd ComfyUI/custom_nodes
git clone https://github.com/Terpentinas/EasyLoRAMerger

Restart and you're done. No extra model files.

Gotchas

Cross-architecture extraction (Flux base + SDXL tuned) is a non-starter - the normalizer can't reconcile the key spaces, and the report will tell you so. And the #1 "why is my extracted LoRA weak" fix is letting strength_multiplier run in auto; the #2 fix is remembering that if your tuned checkpoint barely differs from base, there's not much signal to extract. Preview with save_trigger off before you commit anything to disk.

CategoryEasyLoRAMerger/extraction

Inputs (20)

NameTypeDefaultDescription
checkpoint_baseCOMBOReference (unedited) checkpoint — the 'before' state.
checkpoint_tunedCOMBOFine-tuned checkpoint — the 'after' state whose concept to extract.
rank_modeCOMBOautoauto: automatically determine optimal rank from SVD spectrum analysis. manual: use the specified rank value below.
rankINT641–320Target rank (when rank_mode='manual') or upper bound (when rank_mode='auto').
alpha_modeCOMBOautoauto: alpha = effective_rank × component_scale (e.g., TE=0.5×). manual: use the specified alpha value below.
alphaFLOAT641–512Alpha value (only used when alpha_mode='manual').
svd_modeCOMBOauto_energyauto_energy: automatic rank selection via energy threshold. manual: use specified rank. full: keep all singular values (no compression).
energy_thresholdFLOAT0.950.5–1Only used in 'auto_energy' mode. Energy retention threshold (0.50–1.0). Higher = more precision (higher effective rank). Lower = more compression.
noise_thresholdingBOOLEANtrueEnable Marchenko-Pastur noise-aware SVD thresholding. Disable for cross-model deltas (e.g., Turbo vs. Base) where the noise model may incorrectly reject signal.
strength_multiplierCOMBOautoauto: automatically detect baking attenuation and compensate. 1.5/2.0/3.0: manual multiplier applied before SVD.
detection_modeCOMBOauto_fastauto_fast: sample 30 layers for quick attenuation estimate (default). auto_precise: analyze ALL layers for exact estimate.
save_triggerBOOLEANfalse
filenameSTRINGextracted_loraFilename for the output LoRA (.safetensors added automatically).
lora_formatCOMBOnativenative: standard CivitAI-compatible format (diffusion_model.* keys, merged QKV). diffusers: HuggingFace Diffusers format (transformer.* keys, QKV split).
deviceCOMBOautoauto: pick best available (CUDA if enough VRAM). cuda: force GPU. cpu: force CPU.
modeloptMODELOptional: connect a model to preview the extracted LoRA applied to it.
clipoptCLIPOptional: connect a CLIP to preview the extracted LoRA applied to it.
strength_modeloptFLOAT1.000–10Strength of the extracted LoRA when applied to the model (0.0–10.0). Ignored if model/clip not connected.
strength_clipoptFLOAT1.000–10Strength of the extracted LoRA when applied to the CLIP (0.0–10.0). Ignored if model/clip not connected.
save_folderoptSTRING/tmp/ComfyUI/models/checkpointsOutput folder. Leave blank to use ComfyUI's default loras folder.

Outputs (4)

NameTypeDescription
modelMODEL
clipCLIP
forensicsSTRING
lora_pathSTRING