Nodes/Model Utility Toolkit/LoRA Extract (Quantile)
ComfyUI Node

LoRA Extract (Quantile)

LoRA Extract (Quantile) — extract a LoRA by cumulative singular-value mass

By silveroxides·Created about a year ago·Updated 4 days ago· 14
LoRA Extract (Quantile)
    • output_path
    model_a
    model_b
    linear_quantile0.90
    conv_quantile0.90
    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

    One of five LoRA extraction flavors in silveroxides' ComfyUI-ModelUtils, and the one to reach for when you'd rather think in "keep 90% of what matters" than in raw rank numbers. LoRA Extract (Quantile) diffs two checkpoints, runs SVD on each layer's difference, and keeps adding singular values until they account for a target cumulative percentage of the total - a size/fidelity dial expressed as a quantile instead of an absolute number.

    The mechanism. Standard setup for this whole pack: model_a is your fine-tune, model_b is the base it came from ("A - B = LoRA," per the node's own tooltips). For each layer, the weight difference gets SVD-decomposed into singular values ranked by size, and Quantile extraction keeps adding the largest ones until they reach your target share of the cumulative total - linear_quantile/conv_quantile, both defaulting to 0.9. That's a per-layer adaptive rank, same spirit as Frobenius extraction in this pack, just budgeted against the running total of singular values rather than the matrix's overall norm. For most layers the two will land in a similar place; Quantile is the more intuitive framing if "percentage of the important stuff kept" is how you naturally think about compression.

    Inputs that matter. linear_quantile/conv_quantile (0.9 default) are the actual controls - drop them for a smaller file, push toward 1.0 if the extraction feels like it's losing fidelity. linear_max_rank/conv_max_rank (both 128) cap how large a rank the quantile target is allowed to demand, protecting you from a layer with a very gradual decay eating an enormous rank chasing 90%. The rest is shared across every extraction node in this pack: svd_niter for SVD accuracy, clamp_quantile (0.99) to clip outlier singular values, min_diff to skip layers that barely changed, skip_patterns/glob_skip_patterns to exclude layers by name, save_dtype (fp16), device (cuda). Output is output_path, the saved LoRA's location.

    Installing it. Search "Model Utility Toolkit" in ComfyUI Manager, or cd ComfyUI/custom_nodes && git clone https://github.com/silveroxides/ComfyUI-ModelUtils and restart. No extra dependencies flagged in the README; you need the two source checkpoints already on disk.

    Why extraction is worth doing in the first place. If you have a base model and a full fine-tune, the difference between them can be compressed into a LoRA that's a fraction of the disk space and portable to other checkpoints in the same family - this is a well-established practice in the community, not something specific to this pack, and it's exactly what kohya-ss's training scripts (this pack's acknowledged inspiration for the LoRA tooling) have supported for years. Quantile is a reasonable default if you don't already have a strong opinion about rank and just want a sensible fidelity/size tradeoff without babysitting individual layers.

    Costs and where it goes wrong. SVD across every layer of two full checkpoints is slow and memory-hungry no matter which extraction node you use - lazy_load and force_clear_cache, both on by default, exist specifically to keep this from OOMing on modest GPUs, and chunk_large_layers (off by default) helps if you're extracting from an architecture with big fused transformer blocks. The recurring gotcha across this whole family: model_a and model_b have to be genuinely related checkpoints. mismatch_mode defaults to skip, which means feeding it two unrelated models won't error - it'll silently drop every layer that doesn't line up and hand you back a LoRA that looks fine and is missing most of what you wanted. If the result seems thin, that's the first thing to check, not the quantile setting.

    CategoryModelUtils/LoRA

    Inputs (17)

    NameTypeDefaultDescription
    model_aCOMBOFinetuned model (A - B = LoRA)
    model_bCOMBOBase model (A - B = LoRA)
    linear_quantileFLOAT0.900–1Target cumulative % for linear layers
    conv_quantileFLOAT0.900–1Target cumulative % for conv layers
    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