TE DoRA Extract (Ratio)
DoRA for text encoders, rank by ratio
- output_path
This is the ratio-flavored sibling of the TE DoRA extractors in ModelUtils: same DoRA trick, rank decided per layer by a ratio instead of a fixed number or a percentile. Keep every singular value above max(S) / ratio, decompose the direction, stash the magnitude in a dora_scale. If you already understand the LoRA Ratio node, this is that, with the DoRA difference step swapped in.
Quick refresher on what changes with DoRA. Where LoRA extraction just computes A - B and decomposes the whole delta, the DoRA path rescales each row of the fine-tuned encoder to the base's row magnitude before subtracting. That separates the update into direction (what gets low-rank-decomposed) and magnitude (what gets saved as the per-layer dora_scale). So the output file has lora_A, lora_B, and dora_scale keys - the DoRA signature. Whether that's worth the extra moving parts is up to you; the community's DoRA enthusiasm cooled mostly because trained DoRAs don't stack like LoRAs do, but for distilling one specific delta the magnitude/direction split is a legitimate choice, not a gimmick.
The inputs that matter
- model_a / model_b - fine-tuned and base text encoders from
models/text_encoders. - linear_ratio / conv_ratio - the rank threshold for linear/attention vs convolution layers, default 2. Higher values keep more singular values (a higher ratio lowers the cutoff,
max(S) / ratio), so raise it for higher fidelity, lower it for a tighter, smaller file. Same kohya-style convention as the LoRA Ratio node. - linear_max_rank / conv_max_rank - hard caps (default 128) so no single noisy layer blows the rank up.
- probe_offset - extra singular values sampled past the cap so the threshold decision sees a full-enough spectrum.
- output_filename / save_dtype / device / lazy_load / force_clear_cache - the shared knobs: output name in your
lorasfolder, save precision (fp16 default), compute device with per-layer CPU fallback on OOM, streaming memory.
It's an output node; output_path tells you where the file landed.
Install
ComfyUI Manager → "Model Utility Toolkit", or:
cd ComfyUI/custom_nodes
git clone https://github.com/silveroxides/ComfyUI-ModelUtils
cd ComfyUI-ModelUtils
pip install -r requirements.txt
Restart; it sits under ModelUtils/DoRA Extract (TE). The streaming dependency that actually matters is unifiedefficientloader.
Gotchas
Same family warnings: mismatch_mode: skip is the default, so a wrong base means a silently small, useless file. DoRA extraction runs the full SVD per layer, so budget minutes, not seconds. And if the resulting file loads but does nothing, suspect the loader before the extraction - dora_scale support is not universal across LoraLoaders. When in doubt, compare against the plain LoRA Ratio output: if it behaves better in your stack, that's your answer about whether DoRA was worth it for your use case.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| model_a | COMBO | Finetuned Text Encoder model (A - B = LoRA) | |
| model_b | COMBO | Base Text Encoder model (A - B = LoRA) | |
| linear_ratio | FLOAT | 2.01–100 | Ratio threshold for linear layers; higher values retain more singular values. |
| conv_ratio | FLOAT | 2.01–100 | Ratio threshold for convolution layers; higher values retain more singular values. |
| probe_offset | INT | 321–4096 | Extra singular values sampled beyond Max Rank for a reliable bounded rank decision. |
| linear_max_rank | INT | 1281–16384 | Maximum extracted rank for linear layers. |
| conv_max_rank | INT | 1281–16384 | Maximum extracted rank for convolution layers. |
| lazy_load | BOOLEAN | true | Low memory mode: load tensors from disk on demand |
| force_clear_cache | BOOLEAN | false | Clear CUDA cache after each layer; slower but useful under severe VRAM pressure. |
| chunk_large_layers | BOOLEAN | false | Split large fused layers (QKV, MLP) into chunks |
| clamp_quantile | FLOAT | 0.990.5–1 | Clamp outlier singular values |
| min_diff | FLOAT | 0.0000–1 | Skip layers with max difference below this |
| mismatch_mode | COMBO | skip | Handle missing or incompatible text-encoder tensors by skipping them, substituting zeros where supported, or aborting. |
| output_filename | STRING | extracted_te_lora | Output filename without extension, written under the ComfyUI LoRA directory. |
| save_dtype | COMBO | fp16 | Data type used to save extracted text-encoder LoRA factors. |
| device | COMBO | cuda | Device used for per-layer extraction arithmetic; CUDA out-of-memory retries the affected layer on CPU where supported. |
| skip_patterns | STRING | Patterns for layers to skip (regex or glob depending on glob_skip_patterns) | |
| glob_skip_patterns | BOOLEAN | false | When 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)
| Name | Type | Description |
|---|---|---|
| output_path | * | — |