Nodes/ComfyUI LoRA Block Weight Loader/LoRA Block Weight Loader
ComfyUI Node

LoRA Block Weight Loader

The Name Says Nunchaku, But It Loads Any LoRA

By bhvbhushan·Created about a year ago·Updated about a year ago· 5
LoRA Block Weight Loader
  • model
  • clip
  • model
  • clip
  • info
lora_name
strength_model1.00
strength_clip1.00
block_weights1.0
weight_mode
interpolation_start1.00
interpolation_end1.00
interpolation_curve1.0
block_rangeall
normalize_weightsfalse
preserve_meantrue
verbosefalse
preset

A single strength_model float treats a LoRA like a light dimmer, but the model doesn't work that way. The LoRA Block Weight Loader lets you give every transformer block its own strength - stronger on the early blocks that shape composition, quieter on the late ones that bake in texture. The name says Nunchaku and it's pitched at Flux, but the first honest thing to know is that it's a general per-block LoRA loader that works on plain SD 1.5 and SDXL models too. It doesn't even depend on Nunchaku: the pack's actual requirements are just torch and numpy. If you're running quantized Flux via Nunchaku in ComfyUI, great, it slots in - the word in the class name is compatibility, not a dependency.

This is the Flux-era successor to the old sd-webui-lora-block-weight extension and its :IN / :MID / :OUT suffixes. Where that gave you three buckets, this gives you a number per block. When does that pay off? When a LoRA nails the subject but overbakes skin texture, or two stacked LoRAs fight over the same layers, or a style LoRA sags in the middle of the network. Per-block weights let you keep the parts that work.

How it works

The node detects your model's architecture by inspecting it, not by asking: if the diffusion model has double_blocks / single_blocks, it's treated as Flux (19 double + 38 single = 57 blocks; the code also recognizes the 22/24 and 38/44/48 variants). Plain UNet models get a ~25-block SD-style mapping. It then loads the LoRA file itself, matches each tensor to a block by key name (double_block.N, single_block.N, or SD's input_blocks.N / output_blocks.N / layer.N), multiplies each tensor by your weight for that block, and hands the weighted tensors to ComfyUI's built-in comfy.lora.load_lora. Tensors that don't match any block - attention weights, embed tensors - get the average of your weights. If anything blows up, it falls back to a uniform average-weight load rather than failing.

The inputs that matter

  • model, clip, lora_name, strength_model, strength_clip - the standard LoRA stack, exactly like the core Load LoRA node. lora_name picks from ComfyUI/models/loras/.
  • block_weights - the heart of it. A single value (1.0) for uniform, space or comma separated lists (1.5, 1.2, 0.9, ...), a JSON array, a JSON object keyed by block index, or for Flux a multi-line block-specific format with double_blocks: and single_blocks: sections. Shorter lists get padded with the last value; longer ones get truncated.
  • weight_mode - uniform, block_specific, or one of linear_interpolation / exponential / gaussian / custom_curve. The interpolated modes generate a smooth gradient from interpolation_start to interpolation_end, shaped by interpolation_curve (1.0 = straight line).
  • block_range - target a slice instead of everything: all, 0-6, 7-12,15-18.
  • preset - bell_curve, u_shape, emphasis_early / emphasis_middle / emphasis_late, linear_decay, linear_growth, or any JSON preset you drop in the pack's presets/ folder.
  • verbose - turn it on and the info output becomes a report: detected architecture, block counts, and min/max/mean/std of the weights you actually applied.

Outputs are model and clip, which wire into your sampler exactly like any LoRA loader, plus an info STRING you can eyeball with a text node.

Installing and the rough edges

cd ComfyUI/custom_nodes
git clone https://github.com/bhvbhushan/ComfyUI-LoRABlockWeight
# restart ComfyUI

Or use ComfyUI Manager (search "LoRA Block Weight"). No models to download, no heavy deps. Where people get burned: assuming the block count - if your model isn't Flux's 57, set the editor's total_blocks to match, or your carefully shaped curve gets padded or chopped. And keep normalize_weights off until you're sure - with preserve_mean (default on) it rescales so the average stays 1.0, which is safer than a curve whose mean drifts the whole LoRA strength. Finally, the honest workflow advice: run a plain uniform load first as a baseline. If the LoRA looks fine everywhere, per-block weighting is a solution looking for a problem. When it actually fights your checkpoint, this node is the thing you reach for.

Categoryloaders/advanced

Inputs (15)

NameTypeDefaultDescription
modelMODEL
clipCLIP
lora_nameCOMBO0 options:
strength_modelFLOAT1.00-20–20
strength_clipFLOAT1.00-20–20
block_weightsoptSTRING1.0
weight_modeoptCOMBO6 options: uniform, block_specific, linear_interpolation, exponential, gaussian, custom_curve
interpolation_startoptFLOAT1.000–2
interpolation_endoptFLOAT1.000–2
interpolation_curveoptFLOAT1.00.1–10
block_rangeoptSTRINGall
normalize_weightsoptBOOLEANfalse
preserve_meanoptBOOLEANtrue
verboseoptBOOLEANfalse
presetoptCOMBO9 options: none, bell_curve, emphasis_early, emphasis_late, emphasis_middle, example_custom, +3

Outputs (3)

NameTypeDescription
modelMODEL
clipCLIP
infoSTRING