ComfyUI Node

LoRA Extract and Save

Turn a model diff into an actual .safetensors LoRA

By NMWave·Created 2 years ago·Updated 7 months ago· 6
LoRA Extract and Save
  • model_diff
  • text_encoder_diff
    filename_prefixloras/ComfyUI_extracted_lora
    rank8
    iterations7
    lora_type
    bias_difftrue

    Every so often you end up with a merged model - you stacked LoRAs, or you merged a couple of checkpoints - and you realize what you actually want is a LoRA file, not a Frankenstein checkpoint. That's the entire job of LoRA Extract and Save: it takes a model diff (a merged model minus its base) and factorizes it into a proper low-rank LoRA, saved as a .safetensors file you can load like any other.

    The workflow that feeds it is simple to describe and a little fiddly to build: apply the LoRAs you care about to a base model, use ModelMergeSubtract to compute merged − base, and wire that subtraction output into this node. The node's own tooltips say it plainly - the model_diff input is "The ModelSubtract output to be converted to a lora," and text_encoder_diff is the equivalent CLIPSubtract output.

    The technique has real community history: extracting LoRAs this way was popularized for Wan training, where the original brute-force script could take hours and people gave up on it. This pack ships the speeded-up version that uses a modern low-rank approximation instead.

    How it works

    For every weight layer in the diff, the node runs torch.svd_lowrank - an approximate SVD that factors the layer into two smaller matrices (lora_up and lora_down) instead of computing the full decomposition. It clamps outlier values to a sane range, and saves the whole thing as a LoRA file in ComfyUI's output folder under the loras/ subfolder.

    The inputs that matter:

    • model_diff (MODEL) and text_encoder_diff (CLIP) - optional, but at least one must be wired or the node just logs "nothing to do" and returns.
    • rank - the rank of the extracted LoRA. Default 8. Higher rank = more fidelity, bigger file. Realistic range for this kind of extraction is 8–64.
    • iterations - how much effort the approximate SVD spends (default 7). This is the "bump it up if you see softness" knob from the original technique writeup.
    • lora_type - standard produces a proper low-rank LoRA (slower, small file); full_diff skips factorization and saves the raw per-layer diffs (very fast, but the file is huge).
    • bias_diff - also extract bias differences (default on).

    It's an output node with no return values - its "output" is the file it writes.

    Install

    Manager → "Nader Tagging", or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/NMWave/ComfyUI-Nader-Tagging
    

    No extra Python dependencies - it uses ComfyUI's own torch, model management, and folder-path utilities.

    The honest warnings

    This is the least beginner-friendly node in the pack, and it deserves the warning. Standard extraction on a big UNet - say a Wan 14B - is genuinely heavy: it loads the model to GPU, walks every layer, and factors each one. With the speeded-up SVD it's minutes instead of hours, but it's still not "set and forget on a laptop." Expect the console to churn through layer-by-layer logging.

    Two things will scare you the first time and are actually normal: layers whose diff is all zeros (a LoRA never touched them) throw warnings and get skipped, and the whole run can look stalled if you aren't watching the log. The original community thread exists precisely because people saw "zero diff" warnings and assumed it failed.

    Uses: pull a LoRA out of a merge you like, so you can share it or retrain on top of it; or capture the difference between two checkpoints as a reusable adapter. If you're on SDXL-era merges, this is overkill - but for Wan-style stacked-LoRA merges, it's the tool that turns a one-off Frankenstein into something portable.

    CategoryNMWave/lora

    Inputs (7)

    NameTypeDefaultDescription
    filename_prefixSTRINGloras/ComfyUI_extracted_lora
    rankINT81–4096
    iterationsINT71–50
    lora_typeCOMBO2 options: standard, full_diff
    bias_diffBOOLEANtrue
    model_diffoptMODELThe ModelSubtract output to be converted to a lora.
    text_encoder_diffoptCLIPThe CLIPSubtract output to be converted to a lora.

    Outputs (0)

    No outputs