Bobs LoRA Loader (SDXL)
Stop turning the whole LoRA down just to fix the style
- model
- clip
- MODEL
- CLIP
- info
You know the moment. A character LoRA gets the face perfect but drags in the stiff, overbaked style it was trained with, and your only lever is the strength slider - which turns the face and the style down together. Bobs LoRA Loader (SDXL) exists to break that coupling. Instead of one knob, you get four, one per conceptual slice of the SDXL model, so you can keep the subject detail and gut the style, or the reverse.
It's one of three loaders in the BobsBlazed/Bobs-Lora-Loader pack (the siblings are a FLUX version and a Universal one that covers everything else), all sitting under the Bobs_Nodes category. The SDXL node works on SDXL proper, and per the README, on SD1.5/SD2 too - those share the same UNet shape, so the same buckets apply.
How it actually works
Here's the part worth knowing before you touch a slider: the node never parses the LoRA file's own key names. ComfyUI's comfy.lora already translates every exporter dialect - kohya's lora_unet_*, OneTrainer's lora_transformer_*, diffusers, LyCORIS - into canonical model keys via a key map. This loader just classifies each canonical key into one of four buckets:
- Input Blocks - the UNet down path (
input_blocks.*). Composition and structure. - Middle Block - the bottleneck (
middle_block.*). The concept and style core. - Output Blocks - the up path (
output_blocks.*). Style, detail, texture. - Text Encoder - whatever patches the CLIP text encoder instead of the UNet.
Each bucket gets its own weight, then the model and CLIP are patched bucket by bucket. The one real gotcha from the changelog: some community SDXL LoRAs use the unet. naming convention rather than lora_unet_, and older versions of this node misfiled those. That's been overhauled, and the loader now handles both.
The inputs that matter
You wire in model and clip from your checkpoint loader (the README says clip is optional - leave it unconnected to patch the model only), pick the file from lora_name, and then it's three things:
strength- a global multiplier applied on top of every block weight. Range −5 to 5, so it doubles as an "unapply this LoRA" dial.preset-Character,Style,Concept,Fix Hands/Anatomy(plusDetail & Texture). These aren't marketing; they're real weight tables.Characterkeeps text encoder, input and middle at 1.0 and drops output to 0.2;Styledoes the opposite, zeroing the text encoder and pushing output to 1.0.Fix Hands/Anatomyruns at a gentle global 0.4 with input blocks at 1.0.- The four block sliders - only live when
presetisCustom.
The trap, straight from the README: any preset other than Custom ignores the sliders entirely. It doesn't blend with them. Only strength still applies on top. Want the Character preset but with a hint more style? Copy it into Custom and nudge output blocks from 0.2.
Pick Full (Normal LoRA) and every block is 1.0 - a drop-in replacement for ComfyUI's built-in LoraLoader, which is a nice way to sanity-check that the node isn't the thing changing your output.
Installing it
This one is easy, and that's genuinely unusual. There's no requirements.txt - it's pure Python over ComfyUI's own API, no torch-level deps, no model files to download. Either install Bobs_LoRA_Loader from ComfyUI Manager (search the registry), or:
cd ComfyUI/custom_nodes/
git clone https://github.com/BobsBlazed/Bobs-Lora-Loader
Then restart ComfyUI. Your LoRAs come from the same models/loras folder the standard loader uses.
Where people get burned
- Wrong loader for the model. Point this node at a FLUX model or FLUX LoRA and the sliders quietly do nothing useful - every tensor piles into one bucket. Since version 1.2.1 the node logs a warning when 90%+ of UNet tensors land in a single block, and suggests the Universal loader. If your log starts shouting about a dominant block, trust it.
- Preset vs. slider confusion - covered above; it's the most common "why is my Custom doing nothing" report.
- "Other Tensors" won't go to zero. It should be near zero for a correctly-classified SDXL LoRA, and the console prints a per-block report - weight, tensors found, tensors actually patched - so you can see the lie. A block with a nonzero weight and zero tensors means your LoRA simply doesn't touch it.
That per-block report is worth wiring into your mental model: it tells you which of a LoRA's concepts actually live where, which is exactly the knowledge you need to split a character from its style.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | Diffusion model to patch. | |
| lora_name | COMBO | LoRA file to load. 'None' passes the model through untouched. | |
| strength | FLOAT | 1.00-5–5 | Global multiplier applied on top of every block weight. |
| preset | COMBO | Choose 'Custom' to use the sliders below; any other preset overrides them. | |
| Text Encoder | FLOAT | 1.00-2–2 | CLIP-L / T5 text encoder weights. Lower this to keep a LoRA's look while weakening its trigger words. |
| Input Blocks | FLOAT | 1.00-2–2 | UNet down path (diffusion_model.input_blocks.*). Composition and structure. |
| Middle Block | FLOAT | 1.00-2–2 | UNet bottleneck (diffusion_model.middle_block.*). Concept and style core. |
| Output Blocks | FLOAT | 1.00-2–2 | UNet up path (diffusion_model.output_blocks.*). Style, detail and texture. |
| Other Tensors | FLOAT | 1.00-2–2 | UNet tensors outside the three stages (time_embed, label_emb, out.*). |
| clipopt | CLIP | Optional. Leave unconnected to patch the model only. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | Model with the block-weighted LoRA applied. |
| CLIP | CLIP | CLIP with the text-encoder portion of the LoRA applied. |
| info | STRING | Per-block report: weight, tensors found and tensors actually patched. |