DoRA Loader (Custom) π―
The DoRA loader that does the real decomposition, not a scaled LoRA β with honest limits
- model
- model
- summary
DoRA (weight-Decomposed Low-Rank Adaptation) is LoRA's cleverer cousin: instead of just adding a low-rank delta, it splits the update into a magnitude vector and a normalized direction. That decomposition is the whole point - the trained magnitude only makes sense relative to the normalization. So a DoRA file is not "a LoRA with a bonus scaling vector," and loading it through a plain LoRA loader (or worse, treating dora_scale as an extra strength multiplier) reproduces none of what was actually trained.
This node does the real math. It reads the file's standard LoRA keys plus the dora_scale magnitude vector, computes W' = m Β· (W0 + BA) / βW0 + BAβ_c - magnitude times the column-normalized base-plus-delta - and hands the resulting delta to ComfyUI's ModelPatcher.add_patches() API. Not a state-dict edit, not a scaled LoRA. It's verified against the defining property of the algorithm: post-merge weight row norms should equal the trained magnitude vector.
The inputs are model, dora_name (a dropdown of files in your loras/ folder - ComfyUI has no separate DoRA folder, the file is just a LoRA-format safetensors with the extra marker), and strength (default 1.0, blends the final delta uniformly toward 0 or past it). Outputs are the patched model and a summary string that reports what got applied and - this is the part to read - what got skipped.
Because the math needs each layer's original weight, there are real constraints you need to respect:
- Linear/2D layers only. Conv2d (4D) weights - the ResBlock/UNet convs found in many real files - are not implemented and get reported as skipped. The effect on a full file is typically partial. Check
summarybefore assuming the merge fully applied. - Apply it early. DoRA's normalization is computed against the model's current weights. If other patches already changed those same layers upstream in your graph, the math silently uses the already-patched weight. Put this node before other model-patching nodes, not after.
- Confirm the format first. The pack ships a LyCORIS Format Inspector for exactly this: it reads the file's tensor key names and tells you whether it's really DoRA (has the
dora_scalemarker) or a plain LoRA. If this loader gets a plain LoRA, it'll tell you - it checks for the marker and returns a clear message rather than mis-merging.
Why bother, when ComfyUI's built-in loader sometimes handles these files? Because built-in LyCORIS auto-detection has a documented issue (ComfyUI #8683) where LoHa/LoKr/DoRA files can be silently routed through the plain-LoRA merge path - technically running, mathematically wrong. Loading explicitly through this node avoids betting on that auto-detection. That's the strongest argument for it.
The wider context, honestly: DoRA never reached LoRA's critical mass. The community's verdict was that per-adapter magnitude breaks stacking - you can't pile DoRAs the way you can LoRAs - and likeness gains didn't reliably reproduce, so its corpus presence stayed small. That doesn't make this loader wrong; it makes DoRA a niche you'd only seek out deliberately, and if you do, this is the rare node that executes it faithfully.
Install
Part of OmniNodes:
cd ComfyUI/custom_nodes
git clone https://github.com/TensorVizion/OmniNodes
Restart ComfyUI (or ComfyUI Manager β "OmniNodes"). No extra dependencies.
Troubleshooting
- "has standard LoRA keys but NO dora_scale marker" - the file is a plain LoRA. Use a normal LoRA loader.
summaryshows skipped Conv2d layers - expected. Linear layers applied, convs didn't. Decide whether the partial effect is acceptable before building a workflow on it.- Unexpected results - check whether another patch node ran on the same model before this one in the graph, and reorder.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | β | |
| dora_name | COMBO | 0 options: | |
| strength | FLOAT | 1.00-5β5 | β |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| model | MODEL | β |
| summary | STRING | β |