Nodes/ComfyUI-DonutNodes/DonutLoRAStack
ComfyUI Node

DonutLoRAStack

The block-weighted LoRA stacker the pack is built around

By DonutsDelivery·Created about a year ago·Updated about 14 hours ago· 25
DonutLoRAStack
  • lora_stack
  • lora_stack
model_typeAuto
switch_1
lora_name_1
model_weight_11.00
clip_weight_11.00
block_preset_1None
block_vector_1
switch_2
lora_name_2
model_weight_21.00
clip_weight_21.00
block_preset_2None
block_vector_2
switch_3
lora_name_3
model_weight_31.00
clip_weight_31.00
block_preset_3None
block_vector_3
civitai_lookupOn

This is the node the pack is named around. DonutLoRAStack gives you three LoRA slots, and for each one - on top of the usual model/CLIP weights - a block vector: a per-layer list of strengths that lets you say "apply this LoRA hard in the middle blocks, barely in the out blocks." Normal LoRA stacking treats a LoRA as one scalar; this treats it as 12 numbers for SDXL, 17 for SD 1.5, 30 for Z-Image, 28 for Krea 2, with presets so you never have to type them. The README calls it "block-weighted LoRA stacking with presets," and that's the honest one-line summary.

Why block weighting exists: LoRA blocks do different jobs. Early blocks hold composition and structure, middle blocks hold style and detail, late blocks hold fine texture. Stack two full-strength character LoRAs and they fight over the same middle blocks; block weighting is how you park each LoRA where it earns its keep. The community has clearly adopted it - the author's own Z-Image LoRA workflow is a known quantity on CivitAI, and there's at least one real thread of a user chasing "improving DonutLoraStack" for character LoRAs on Z-Image with bbox detailers, mostly around the apply side being finicky.

How it works

For each of the three slots: a switch (On/Off), the lora_name picker, model_weight and clip_weight (defaults 1, range -1000 to 1000 so you can go negative), a block_preset dropdown, and a block_vector string.

The clever part is how preset meets vector: block_preset is a UI helper that populates block_vector with a comma-separated strength list - SDXL-IN-MID:1,1,1,1,1,1,1,1,1,1,1,0,0 style. The model_type selector at the top (Auto / SDXL / SD15 / FLUX / ZIT / ZIT-NE / KREA2) filters which presets you're offered by architecture, and the placeholder text reminds you the vector length differs per model. The actual apply path always uses the block_vector - the source notes the preset "only populates the field via JS."

There's also a civitai_lookup toggle (default On) that fetches LoRA info from CivitAI when the stack applies - the README notes it needs an API key in settings. And an optional lora_stack input, so you can chain this onto a stack built by a previous node.

Output and the next step

Output is a lora_stack of type LORA_STACK - an abstract pipe type, not a model. The node's job ends there; DonutApplyLoRAStack (same pack) is what turns it into model + CLIP patches for your sampler. That's the pairing you'll actually wire: DonutLoRAStack → DonutApplyLoRAStack → KSampler.

Install

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

or ComfyUI Manager → "DonutNodes," restart.

Where people get burned

The apply side is where the pack's own fix history lives - there's a whole CACHE_INVALIDATION_FIX.md and a cache-invalidation validation suite in the repo about merge results going stale when you change strengths. If you tweak a weight and the output doesn't change, that's your bug, and the fix is usually clearing ComfyUI's model cache or restarting. Second: block vectors must match the model's block count - a 12-length SDXL vector fed to a Z-Image stack is silent garbage, which is exactly what the model_type filter exists to prevent. And on negative weights: they're supported, they're a legit technique for subtracting a LoRA's influence, but they amplify any fragility in the apply path.

Categorydonut/LoRA

Inputs (21)

NameTypeDefaultDescription
model_typeCOMBOAutoFilter block presets by model architecture. Auto shows all presets.
switch_1COMBO2 options: Off, On
lora_name_1COMBO1 options: None
model_weight_1FLOAT1.00-1000–1000
clip_weight_1FLOAT1.00-1000–1000
block_preset_1COMBONoneSelect a preset to populate block_vector_1.
block_vector_1STRING
switch_2COMBO2 options: Off, On
lora_name_2COMBO1 options: None
model_weight_2FLOAT1.00-1000–1000
clip_weight_2FLOAT1.00-1000–1000
block_preset_2COMBONoneSelect a preset to populate block_vector_2.
block_vector_2STRING
switch_3COMBO2 options: Off, On
lora_name_3COMBO1 options: None
model_weight_3FLOAT1.00-1000–1000
clip_weight_3FLOAT1.00-1000–1000
block_preset_3COMBONoneSelect a preset to populate block_vector_3.
block_vector_3STRING
civitai_lookupCOMBOOnFetch LoRA info from CivitAI (requires API key in settings)
lora_stackoptLORA_STACK

Outputs (1)

NameTypeDescription
lora_stackLORA_STACK