Donut Weight-Vector Scale
Scale LoRA block weights without nuking the neutral layers
- weights
Here's a sharp little bug that trips up everyone who uses per-layer weight vectors: a lot of tools multiply those weights by a strength value, raw. So if your vector is 1.0, 1.0, 1.0, 2.5, 5.0 and you set strength to 0.5, the "neutral" 1.0 entries become 0.5 - which silently weakens every layer you meant to leave alone. DonutWeightVectorScale exists to fix exactly that. It scales each entry's deviation from 1.0 instead, so 1.0 stays 1.0 and only the non-neutral layers move.
The pack even documents the origin story: the author wrote it to fix the third-party ConditioningKrea2Rebalance node, whose own multiplier zeroed even the neutral layers at 0. If you've ever wondered why a per-layer weight slider produced a flat, washed-out conditioning, that's the bug.
What it does
Three inputs, all straightforward:
- weights - a comma or semicolon-separated list of floats, default
1.0,1.0,1.0,1.0,1.0,1.0,1.0,2.5,5.0,1.1,4.0,1.0. These are per-layer strengths where 1.0 = full strength / neutral. - scale - the lever. 1.0 = unchanged, 0.0 collapses everything back to 1.0 (a no-op), and values above 1 amplify the existing deviations. That's the whole personality of the node: it amplifies shape, not volume.
- rebalance - the interesting one. When on, the result is renormalized so the mean of the vector is exactly 1.0. Raising one layer's weight proportionally lowers the others, which holds the overall conditioning strength - and with it the effective CFG - constant. Turn this on when you want to move emphasis rather than boost it.
One output: weights, the rewritten string.
Where you plug it in
The output is a string, so it feeds any input that accepts a weight-vector string:
per_layer_weightson conditioning-rebalance nodes (like theConditioningKrea2Rebalanceit was written for - leave that node's own multiplier at 1.0 and drive it from here).block_vectorfields on block-weighted LoRA stacking nodes like the pack's ownDonutLoRAStack, which use the same 1.0-neutral convention.- Any other comma-list widget that wants per-layer strengths.
The typical move: put this node between a weight source and the consumer, and use scale to nudge how pronounced the vector's differences are. Set rebalance on when you want a pure reshuffle instead of an overall gain - that's the case where most people accidentally crank overall CFG without meaning to.
The honest take
This is a small utility and it knows it. It's not flashy; it's the kind of node that saves you twenty minutes of confusion once and then lives quietly in your toolbox. If you never touch per-layer weight vectors, you don't need it. If you do - especially with block-weighted LoRA stacks - the 1.0-deviation scaling is the correct behavior you probably assumed the other node had.
Install
Part of ComfyUI-DonutNodes: ComfyUI Manager → search "DonutNodes" → install → restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/DonutsDelivery/ComfyUI-DonutNodes.git donutnodes
cd donutnodes
python -m pip install -r requirements.txt
It's pure string math - no GPU, no model files, and the pack's only real dependencies (opencv-python-headless, scipy, matplotlib, psutil, tqdm, requests) are shared with the rest of the pack.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| weights | STRING | 1.0,1.0,1.0,1.0,1.0,1.0,1.0,2.5,5.0,1.1,4.0,1.0 | — |
| scale | FLOAT | 1.00-1000–1000 | Scales each weight's deviation from 1.0. 1.0 = unchanged, 0.0 = all weights become 1.0 (neutral). |
| rebalance | BOOLEAN | false | Renormalize so the weights' mean is 1.0 - raising one layer proportionally lowers the others, keeping overall conditioning strength (and effective CFG) constant. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| weights | STRING | — |