Rebase LoRA From Finetune
Turn a finetune back into a LoRA
- base_model
- finetuned_model
- base_clip
- finetuned_clip
- saved_lora
- report
Somebody shares a finetune you love, and it's a 6 GB checkpoint. You don't want to host it, and honestly the model owner probably doesn't either. LoRA extraction is the classic middle ground - take the diff between a base and a finetune and compress it into a small adapter file. That's been a command-line trick for years. This node does it inside ComfyUI, with a twist: instead of base − finetune, it computes (base + source LoRA) − finetuned, then writes the result out as either a standard low-rank LoRA or an exact diff patch.
Why the twist matters: you often have a finetune and also know roughly which LoRA on a base produced it (or got you 90% there). Rebase lets you say "this finetune is really just base + that LoRA plus a small leftover" - and then package just the leftover, or the whole thing, as a file you can actually distribute. Think of it as cleaning up the residual between where the LoRA gets you and where the finetune actually is. It's the difference between "rebuild from scratch" and "subtract what you already have."
How it works
The node does three mechanical things, and the source is refreshingly honest about it:
- Loads your
base_lora_nameand applies it tobase_model(andbase_clip, if connected), honoringstrength_modelandstrength_clip. - For each selected weight, subtracts the
finetuned_model's weight from the patched base's weight. The cheap part - pure tensor subtraction. - Depending on
output_mode, either writes those deltas verbatim or runs SVD to factor each delta intolora_up/lora_downfactors plus an.alpha.
The expensive part is step 3. Standard LoRA output is inherently a low-rank approximation - the README doesn't sugarcoat it. full_diff_patch skips SVD entirely and writes exact .diff tensors, so it's both faster and lossless, just bigger. Bias deltas go out as .diff_b either way. It uses ComfyUI's own lora loading machinery under the hood, so there's nothing exotic to install.
The inputs that actually matter
There are a lot of widgets. Ignore most of them on your first run:
output_mode-standard(SVD LoRA, small) vsfull_diff_patch(exact diff, fast). Your first call should almost certainly befull_diff_patchjust to see the pipeline work.layer_scope-original_lora_onlykeeps just the layers your source LoRA touches (default and usually what you want);all_compatible_weightstries to reproduce the entire target delta.rank_mode-match_input_lora_when_possiblereuses each source layer's rank;fixedforces one rank everywhere.rankis the fallback forfixed.compute_device- GPU mainly helpsstandardmode. Forfull_diff_patch, CPU is fine.save_relpath- where it lands inside your ComfyUIlorasfolder (rebased/…). If the file exists, it auto-increments with a_00001suffix rather than overwriting.
Both outputs are strings: saved_lora is the path to the file it wrote, and report is a plain-text log of how many layers were processed, written as LoRA vs diff, skipped, or fell back to CPU. Wire saved_lora anywhere you'd show a path, or just read the report in the node's text display.
Installing it
No dependencies, no requirements.txt, nothing to download - it's a single Python file plus a tiny JS extension that adds right-click presets.
cd ComfyUI/custom_nodes
git clone https://github.com/srv1n/ComfyUI-Rebase-LoRA
Then restart ComfyUI. Or just search "Rebase LoRA" in ComfyUI Manager. Right-clicking the node gives you two handy presets: "Apply CPU exact patch preset" (fast + lossless) and "Apply CUDA speed preset" (standard mode with randomized SVD tuned for speed).
Where people get burned
The node validates that your LoRA loads keys onto the base, but it can't save you from a category error: base, source LoRA, and finetune must all be the same architecture family. Point an SDXL LoRA at an SD 1.5 base and it dies with "The selected LoRA did not load any keys" - that error is doing you a favor. Also remember the node uses the effective incoming weights, so if you feed it already-patched models, those patches quietly become part of the diff. And if the source LoRA was trained on a different base than the finetune, the leftover delta will be garbage - the whole thing hinges on "base + LoRA ≈ finetune" being roughly true to begin with.
One genuinely nice touch: svd_mode = lowrank uses randomized SVD, so you get tiny run-to-run numeric differences. The README calls the CPU fallback "instead of dying dramatically like a Victorian inventor." It's a small pack, but it behaves like someone actually runs it.
Inputs (21)
| Name | Type | Default | Description |
|---|---|---|---|
| base_model | MODEL | — | |
| finetuned_model | MODEL | — | |
| base_lora_name | COMBO | The source LoRA trained on top of the base model. | |
| save_relpath | STRING | rebased/rebased_lora | Relative path inside the ComfyUI loras folder. .safetensors is optional. |
| rank | INT | 161–4096 | — |
| layer_scope | COMBO | original_lora_only keeps only layers touched by the source LoRA. all_compatible_weights tries to recreate the full target delta. | |
| rank_mode | COMBO | Reuse the input LoRA layer rank when possible, or force one fixed rank for every extracted layer. | |
| output_mode | COMBO | standard writes LoRA factors where possible. full_diff_patch writes exact diff tensors instead. | |
| strength_model | FLOAT | 1.00-10–10 | — |
| strength_clip | FLOAT | 1.00-10–10 | — |
| save_dtype | COMBO | Tensor dtype used in the written safetensors file. | |
| bias_diff | BOOLEAN | true | When enabled, bias deltas are written as .diff_b patches. |
| clamp_quantile | FLOAT | 0.9900–1 | Symmetric clamp used before writing LoRA factors. Set to 0 or 1 to disable. |
| include_clip | BOOLEAN | true | Also extract text-encoder deltas when clip inputs are connected. |
| compute_device | COMBO | auto | Where to run subtraction and SVD. GPU mainly helps standard LoRA extraction; full_diff_patch is usually fine on CPU. |
| svd_mode | COMBO | auto | auto uses full SVD for most layers and randomized low-rank SVD only when the requested rank is much smaller than the matrix. |
| cuda_svd_driver | COMBO | auto | CUDA-only torch.linalg.svd driver. Leave on auto unless you are tuning speed/accuracy. |
| lowrank_oversample | INT | 160–512 | Extra rank budget used by randomized low-rank SVD in auto/lowrank mode. |
| lowrank_niter | INT | 20–16 | Power iterations for randomized low-rank SVD. Higher is slower but usually more accurate. |
| base_clipopt | CLIP | — | |
| finetuned_clipopt | CLIP | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| saved_lora | STRING | — |
| report | STRING | — |