Nodes/Model Utility Toolkit/LoRA Extract (Knee Detection)
ComfyUI Node

LoRA Extract (Knee Detection)

LoRA Extract (Knee Detection) — auto-rank LoRA extraction from two checkpoints

By silveroxides·Created about a year ago·Updated 4 days ago· 14
LoRA Extract (Knee Detection)
    • output_path
    model_a
    model_b
    knee_methodsv_knee
    linear_max_rank128
    conv_max_rank128
    lazy_loadtrue
    force_clear_cachetrue
    chunk_large_layersfalse
    clamp_quantile0.99
    min_diff0.000
    mismatch_modeskip
    output_filenameextracted_lora
    save_dtypefp16
    devicecuda
    skip_patterns
    glob_skip_patternsfalse

    Of the five LoRA extraction nodes in silveroxides' ComfyUI-ModelUtils, this is the one for people who don't want to pick a rank, a ratio, or a percentage at all. LoRA Extract (Knee Detection) looks at the singular-value decay curve for each layer and finds the "knee" - the point where adding more singular values stops paying for itself - and sets the rank there automatically. You give it a ceiling and let the math decide the rest.

    The mechanism, and why a knee. Extraction works by diffing your fine-tune (model_a) against its base (model_b, per the node's own tooltip labeling: "A - B = LoRA") and running SVD on the difference for each layer. Plot the singular values of that diff in descending order and you typically get a curve that drops fast at first, then flattens - the "knee" is where it bends from steep to flat, and everything past that point is mostly noise rather than signal. Instead of a fixed rank (uniform everywhere) or a percentage target (Frobenius/Quantile), Knee Detection reads that curve per layer and picks the cutoff itself, which means simple layers end up with a small rank and complex ones get more, without you tuning either.

    Inputs that matter. knee_method (default sv_knee) picks which detection algorithm runs the curve analysis - the dropdown will show whatever variants the node ships with; if you're not sure, the default is the reasonable starting point. linear_max_rank/conv_max_rank (both 128) cap how far the automatic selection is allowed to go, since a layer with a very gradual, almost-flat decay could otherwise get assigned a huge rank chasing a knee that barely exists. Beyond that, this shares the same toolkit as every extraction node here: svd_niter, clamp_quantile (0.99, clips outlier singular values), min_diff (skips layers that barely changed), skip_patterns/glob_skip_patterns, save_dtype (fp16), and device (cuda). One output, output_path, points to the saved LoRA file.

    Installing it. ComfyUI Manager, search "Model Utility Toolkit" - or clone directly: cd ComfyUI/custom_nodes && git clone https://github.com/silveroxides/ComfyUI-ModelUtils, restart ComfyUI. No extra dependencies in the README; you supply the two checkpoints.

    When to actually reach for this one. If you've already tried Fixed Rank and found some layers over-provisioned (wasting file size on a layer that barely changed) while others feel under-served, Knee Detection is the fix - it's the node built specifically to stop you from having to guess rank layer by layer. It's also the right first attempt if you have no strong intuition about how much any given layer actually changed between your two checkpoints, which, honestly, is most of the time.

    Costs and failure modes, same family as its siblings. You're loading two full checkpoints and running SVD across every layer, which is slow and memory-hungry regardless of which extraction node you pick - lazy_load and force_clear_cache (both on by default) exist to keep that from blowing out VRAM, and chunk_large_layers helps on modern DiT architectures with big fused QKV/MLP blocks if extraction is choking. And the constraint that applies to all five: model_a and model_b need to be the same architecture. mismatch_mode defaults to skip, meaning a genuine architecture mismatch between the two checkpoints won't throw an error - it'll just quietly drop the layers that don't line up, and knee detection has nothing to say about layers it never saw. If your extracted LoRA seems oddly thin, check that both source checkpoints actually share a lineage before blaming the knee-detection logic.

    CategoryModelUtils/LoRA

    Inputs (16)

    NameTypeDefaultDescription
    model_aCOMBOFinetuned model (A - B = LoRA)
    model_bCOMBOBase model (A - B = LoRA)
    knee_methodCOMBOsv_kneeKnee detection method
    linear_max_rankINT1281–16384Maximum rank for linear layers
    conv_max_rankINT1281–16384Maximum rank for conv layers
    lazy_loadBOOLEANtrueLow memory mode: load tensors from disk on demand
    force_clear_cacheBOOLEANtrueClear CUDA cache after each layer
    chunk_large_layersBOOLEANfalseSplit large fused layers (QKV, MLP) into chunks
    clamp_quantileFLOAT0.990.5–1Clamp outlier singular values
    min_diffFLOAT0.0000–1Skip layers with max difference below this
    mismatch_modeCOMBOskip3 options: skip, zeros, error
    output_filenameSTRINGextracted_lora
    save_dtypeCOMBOfp163 options: fp16, bf16, fp32
    deviceCOMBOcuda2 options: cuda, cpu
    skip_patternsSTRINGPatterns for layers to skip (regex or glob depending on glob_skip_patterns)
    glob_skip_patternsBOOLEANfalseWhen True, skip_patterns use glob syntax (* = any sequence, ? = any char, dots are literal). When False (default), patterns are Python regex matched as substrings.

    Outputs (1)

    NameTypeDescription
    output_pathSTRING