FL Model Difference to LoRA
Subtract the base, keep the style
- finetuned_model
- base_model
- lora_path
You've got a fine-tune. You'd rather distribute the difference than the whole checkpoint - a LoRA is a few hundred megabytes instead of twelve gigabytes, and it stacks with other things. LoRA extraction is the well-known middle ground here: take the diff between base and fine-tune and compress it into an adapter. FL Model Difference to LoRA does exactly that, inside ComfyUI, with both models loaded as MODEL objects.
No training loop, no dataset, no captions. Give it finetuned_model (the tune, or a merge) and base_model (the original), and it computes the weight difference, factorises it, and writes a safetensors file into your LoRA folder.
The mechanism, honestly
For every diffusion_model.* parameter present in both, it materialises the weight - respecting any LoRA patches and hook backups already applied, which matters if you're extracting a merge - subtracts the base, and factorises the result.
For 2D and 4D weights that means a low-rank decomposition: an exact SVD when the requested rank covers the matrix, and a randomised svd_lowrank otherwise. Those two halves become the lora_up and lora_down tensors that every LoRA loader understands. Anything else - the odd 1D weight, norms, biases - is stored as a raw delta under a .diff key rather than being approximated. The whole thing is written as fp16 safetensors.
rank (default 128, max 4096) is your only quality dial, and the description states the tradeoff plainly: higher rank preserves more detail. It also tracks and reports retained energy - how much of the difference's total squared magnitude the LoRA actually captured. That number is the honest answer to "did I lose anything?", and it's worth looking at.
filename_prefix defaults to Krea2/Dirtyrealism_difference, which tells you the intended use case: the Krea 2 finetune scene. The prefix is relative to your LoRA folder and validated to stay inside it - no path traversal, no absolute paths, and characters that would break a filename are rejected.
device gives you auto (GPU) or cpu. The CPU path is much slower and exists because you're holding two full models' parameters in memory at once.
Output is a single lora_path string, and it's an output node, so the file is written when you queue.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/filliptm/ComfyUI_Fill-Nodes
Restart ComfyUI. Nothing extra to install for this one - it uses ComfyUI's own LoRA and model-management utilities. The pack's long requirements list installs regardless of whether you use the other ninety percent of it.
Where people get burned
Quantised sources. Straight from the node's description: FP8 sources include quantization error. If you extract from an FP8 checkpoint, the difference carries the quantisation noise along with the style, and the resulting LoRA is subtly dirty. Extract from the highest-precision pair you can.
Mismatched models. The node demands identical diffusion_model parameter sets and matching shapes, and it tells you which key disagreed. You can't diff a fine-tune against a different architecture, however similar the names look.
Memory. Two models' worth of weights plus the working tensors. On a big 12B model with device: auto this will push a lot of VRAM; on CPU it will work and take a long time. Either way, close the other tab.
Slamming the rank. Rank 4096 on a 12B model gives you something approaching a second checkpoint in size, which defeats the point. 64–128 catches most style and aesthetic differences; go higher only if the retained-energy number looks bad and you actually need what's missing.
Non-finite output. There's a guard for weights that overflow fp16, and it refuses to save rather than handing you a broken file. If you hit it, lower the rank or extract at a lower precision difference - usually it means a handful of wild parameters are dominating.
Worth being clear about what you get: a faithful copy of whatever the fine-tune changed, including anything sloppy about it. It's a distribution format, not a cleanup step. And it stacks with LoRAs normally, which is the whole reason to bother.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| finetuned_model | MODEL | The fine-tune or merged model to extract. | |
| base_model | MODEL | The original model. Difference = fine-tune minus base. | |
| filename_prefix | STRING | Krea2/Dirtyrealism_difference | — |
| rank | INT | 1281–4096 | — |
| device | COMBO | 2 options: auto, cpu |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| lora_path | STRING | — |