Nodes/Model Utility Toolkit/DoRA Learned Extract (Ratio) (WIP)
ComfyUI Node

DoRA Learned Extract (Ratio) (WIP)

DoRA Learned Extract (Ratio) — magnitude-threshold extraction, gradient-refined

By silveroxides·Created 2 years ago·Updated 3 days ago· 17
DoRA Learned Extract (Ratio) (WIP)
  • layer_parameters
  • output_path
◄model_a▾►
◄model_b▾►
◄linear_ratio2.0►
◄conv_ratio2.0►
◄probe_offset32►
◄linear_max_rank128►
◄conv_max_rank128►
◄optimize_iters500►
◄learning_rate1.000►
◄optimizerprodigy►
◄lr_scheduleplateau►
◄lr_patience2►
◄lr_factor0.90►
◄lr_cooldown2►
◄early_stop_loss0►
◄early_stop_stall2000►
◄early_stop_lr0►
◄lazy_loadtrue►
◄force_clear_cachefalse►
◄chunk_large_layersfalse►
◄clamp_quantile0.99►
◄min_diff0.000►
◄mismatch_modeskip►
◄output_filenameextracted_lora►
◄save_dtypefp16►
◄devicecuda►
◄skip_patterns►
◄glob_skip_patternsfalse►
◄include_modefalse►

The last of the eight DoRA extraction nodes in this pack, and - like its four Learned siblings - it's labeled "(WIP)" in its own display name. Take that seriously: this is the newest and least-verified layer of an already fairly specialist toolset, and the honest move is to check its output against something you trust rather than assume it just works because it ran without errors.

This one pairs DoRAExtractRatio's rank-selection rule with the gradient-descent refinement stage shared across all five Learned nodes. The ratio method itself is the simplest of the three non-learned selection strategies in this pack: instead of accumulating cumulative energy (quantile) or finding a curve elbow (knee), it just keeps any singular value that's still at least 1/ratio the size of the layer's largest one, and drops everything smaller. It's a local, per-value cutoff rather than a global, cumulative one - which means it can behave a bit differently from quantile-based selection on a layer where the singular values don't have one obvious dominant peak, since a flat spread of similarly-sized values either mostly clears the threshold or mostly doesn't, rather than accumulating gracefully toward a target.

What the "Learned" stage adds. SVD gives the mathematically optimal low-rank fit to a weight matrix in isolation, but that optimality is narrow - it doesn't account for DoRA's magnitude-and-direction reconstruction or for how layers interact once the adapter is actually loaded. This node uses the ratio-selected SVD result as a starting point, then runs an optimizer to directly minimize reconstruction loss against the real weight delta, on the theory that it can close some of that gap. Whether it reliably does, for your particular model pair, is exactly the kind of thing "(WIP)" means you should verify rather than assume.

Inputs that matter. model_a (finetune) and model_b (base) set up the diff. linear_ratio and conv_ratio (both default 2, range 1–100) are the actual selection dial - a value of 2 keeps singular values at least half the size of the layer's largest; raising it lowers the bar and keeps more, weaker values. linear_max_rank and conv_max_rank (both default 128) cap rank regardless of what the ratio threshold would otherwise select.

Optimization controls match the rest of the Learned family: optimize_iters (default 500, 0 skips refinement and falls back to plain ratio-based SVD - effectively DoRAExtractRatio for less compute), optimizer (default "prodigy" - adaptive, doesn't need you to hand-tune a learning rate), learning_rate (default 1, correct for Prodigy; the tooltip flags AdamW as wanting closer to 0.01), lr_schedule (default "plateau") shaped by lr_patience (default 2), lr_factor (default 0.9), and lr_cooldown (default 2), and three early-stop conditions - early_stop_loss (1e-6), early_stop_stall (2000 iterations), early_stop_lr (9.01e-9).

Shared plumbing: chunk_large_layers for fused transformer QKV/MLP blocks, clamp_quantile (default 0.99), min_diff (default 0), mismatch_mode (default "skip"), skip_patterns/glob_skip_patterns, output_filename (default "extracted_lora"), save_dtype (default fp16), device (default cuda), lazy_load (on by default), force_clear_cache (on by default).

Output. output_path (STRING). Output node - it executes as a terminal step whether or not that path is wired downstream.

Installing it. ComfyUI Manager, search "Model Utility Toolkit," or:

cd ComfyUI/custom_nodes
git clone https://github.com/silveroxides/ComfyUI-ModelUtils

then restart.

Troubleshooting. Run this against DoRAExtractRatio on the same model pair and the same ratio settings before trusting the refined version over the plain one - given the WIP label, that comparison is the whole troubleshooting process. If optimize_iters keeps running to the full budget without an early stop, adjust learning_rate for whichever optimizer you've got selected before concluding anything about the model pair itself. And the usual resource note applies here as everywhere in this extraction family: two full checkpoints have to be in memory for the diff, so leave lazy_load and force_clear_cache on unless your hardware has room to spare.

CategoryModelUtils/DoRA

Inputs (30)

NameTypeDefaultDescription
model_aCOMBOFinetuned model (A - B = LoRA)
model_bCOMBOBase model (A - B = LoRA)
linear_ratioFLOAT2.01–100Ratio threshold for linear layers; higher values retain more singular values.
conv_ratioFLOAT2.01–100Ratio threshold for convolution layers; higher values retain more singular values.
probe_offsetINT321–4096Extra singular values sampled beyond Max Rank for a reliable bounded rank decision.
linear_max_rankINT1281–16384Maximum extracted rank for linear layers.
conv_max_rankINT1281–16384Maximum extracted rank for convolution layers.
optimize_itersINT5000–10000Number of gradient descent iterations (0 = skip optimization)
learning_rateFLOAT1.0000.0001–100Base learning rate. AdamW prefers ~0.01, Prodigy prefers ~1.0
optimizerCOMBOprodigyOptimization algorithm
lr_scheduleCOMBOplateauLearning rate scheduling strategy
lr_patienceINT20–1000Steps to wait before decaying LR (Plateau)
lr_factorFLOAT0.900.01–1Factor to decay LR by (Plateau)
lr_cooldownINT20–1000Steps to wait after decay before checking again (Plateau)
early_stop_lossFLOAT00–1Stop early if MSE loss drops below this value
early_stop_stallINT20000–10000Stop early if loss doesn't improve for this many iterations
early_stop_lrFLOAT00–1Stop early if learning rate drops below this value
lazy_loadBOOLEANtrueLow memory mode: load tensors from disk on demand
force_clear_cacheBOOLEANfalseClear CUDA cache after each layer; slower but useful under severe VRAM pressure.
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_modeCOMBOskipHandle missing or incompatible model tensors by skipping them, substituting zeros where supported, or aborting.
output_filenameSTRINGextracted_loraOutput filename without extension, written under ComfyUI's LoRA directory.
save_dtypeCOMBOfp16Data type used to save the extracted DoRA tensors.
deviceCOMBOcudaDevice used for extraction arithmetic; CUDA out-of-memory processing falls back per affected layer where supported.
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.
include_modeBOOLEANfalseUse Skip Patterns as a whitelist instead. Only matching layers are extracted; an empty whitelist extracts nothing.
layer_parametersoptMODELUTILS_LAYER_PARAMETERSOptional Layer Parameter Configuration. a=linear_ratio; b=conv_ratio; c=clamp_quantile; d=min_diff; e=linear_max_rank; f=conv_max_rank Full names are also accepted. Unassigned values use this node's settings; existing filters still apply.

Outputs (1)

NameTypeDescription
output_path*—