Nodes/ComfyUI-DonutNodes/Donut Apply LoRA Stack
ComfyUI Node

Donut Apply LoRA Stack

The apply half of the best-known Z-Image LoRA stack in ComfyUI

By DonutsDelivery·Created about a year ago·Updated about 10 hours ago· 25
Donut Apply LoRA Stack
  • model
  • clip
  • lora_stack
  • model
  • clip
  • show_help
safe_stackOff
fusion_awareOff
max_fusion_boost2.00
safe_limit1.00
execution_modeComfy patches

If you came here from a Z-Image character workflow, you already know this node - it's the apply half of DonutsDelivery's famous DonutLora workflow on CivitAI, the one people keep reporting "the best results" with for stacking character LoRAs. DonutApplyLoRAStack takes a stack of LoRAs and actually pushes them into your model and CLIP. It's the boring, essential end of the pipeline that DonutLoRAStack builds up.

The name is honest about the interface. Three inputs: model, clip, and lora_stack (the LORA_STACK object built by DonutLoRAStack or combined with DonutLoraStackCombine). Three outputs: the patched model, the patched clip, and a show_help string that's just a URL to Comfyroll's LoRA docs - wire it into a Show Text node if you ever want to know what the stack format means.

How it works

Under the hood it loads each LoRA in the stack with a block-weighted loader (LoraLoaderBlockWeight), so every LoRA isn't just a flat strength - each entry in the stack carries per-block strength vectors. That's the whole selling point of the pack. For each LoRA it then auto-detects the architecture from the tensor keys: layers.N keys mean a Z-Image/Lumina2 model, input_blocks./output_blocks. keys mean a UNet-style SD 1.5/SDXL model. If a stack entry supplies its own block vector it uses that; otherwise it counts blocks itself so the per-block weights land on the right places.

Two details the source makes explicit and that will save you a confused run:

  • LoRAs with both model and CLIP strength at 0.0 are skipped.
  • A LoRA already applied earlier in the same run is skipped with a console note. That's the duplicate-guard - if your stack has the same LoRA twice, the second occurrence silently does nothing, which is by design, not a bug.

The merge order is fixed: per-block UNet merges first, then uniform CLIP merges. You don't get to reorder it, and you don't need to.

How to use it

Typical wiring: checkpoint → model/clip into this node; DonutLoRAStacklora_stack; then feed the output model to your sampler and the output clip to your text encoder.

Load Checkpoint → model, clip → DonutApplyLoRAStack → model → KSampler
DonutLoRAStack ──────── lora_stack ↗                 clip ────→ CLIP Text Encode

That's the whole job. If you're only applying a single LoRA, the core LoraLoaderModelOnly is simpler - reach for this node when you have two or more LoRAs and you care about their per-block interaction, which is exactly the Z-Image character case.

Installing it

It ships with the whole pack, so install once: ComfyUI Manager → search DonutNodes → install, or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/DonutsDelivery/ComfyUI-DonutNodes.git donutnodes
cd donutnodes
python -m pip install -r requirements.txt

Use the same Python that launches ComfyUI. The requirements.txt is light - opencv-python-headless, scipy, matplotlib, psutil, tqdm, requests - and there are no model files to download; it reads LoRAs from your normal models/loras folder. To be safe, the pack suggests installing ComfyUI-DonutLocalAutomation alongside it if you load older workflows that reference its companion nodes.

Common issues

The most-reported real-world snag, straight from the community: a character LoRA that "sometimes works, mostly doesn't" when bbox detailers are attached downstream. If your LoRA genuinely fails to apply, check the console - the duplicate-skip message is easy to mistake for silence. And remember this is a patch-time node: bypassing it mid-workflow does not un-patch anything, it just stops the next run from applying the stack. If you see no effect at all, check that the stack isn't empty - a zero-entry stack passes your model through untouched and still returns a valid model/clip.

CategoryComfyanonymous/LoRA

Inputs (8)

NameTypeDefaultDescription
modelMODEL
clipCLIP
lora_stackLORA_STACK
safe_stackCOMBOOffKrea2 only. RMS-limits overlapping LoRA strength per block so stacked LoRAs cannot collectively exceed one full-strength LoRA worth of block energy. Off preserves legacy behaviour.
fusion_awareCOMBOOffRequires the model output from Donut Krea2 Fusion Control. Budgets projector LoRA columns against the resolved 12-channel projector gains. Use headroom can boost quiet columns; dynamic tensor_rms profiles are attenuation-only.
max_fusion_boostFLOAT2.001–10Maximum per-column LoRA boost in Use headroom mode.
safe_limitFLOAT1.000–10Maximum combined RMS energy for overlapping Krea2 LoRAs. 1.0 equals one full-strength LoRA; lower values are stricter. Set Safe Stack to Off to disable limiting completely.
execution_modeoptCOMBOComfy patchesGlobal for the connected Donut model path: downstream edit and UncensorFix nodes inherit this selection. Experimental bypass computes base(x) + LoRA(x) without rebuilding quantized model weights. Supports linear LoRA, LoHa, LoKr, and ungrouped zero-padded Conv1d/2d/3d LoRA/LoCon. LoHa builds a dense delta each forward and can be slower. Unsupported targets stay ordered on Comfy's regular path.

Outputs (3)

NameTypeDescription
modelMODEL
clipCLIP
show_helpSTRING