Nodes/ComfyUI-UltraTex/UltraTex Load LoRA
ComfyUI Node

UltraTex Load LoRA

Why the stock LoRA loader just shrugs at these files

By visualbruno·Created 23 days ago·Updated 3 days ago· 46
UltraTex Load LoRA
  • model
  • MODEL
◄lora_name▾►
◄strength1.00►

Here's the thing nobody tells you before you download an UltraTex checkpoint and wonder why ComfyUI's Load LoRA node reports zero patches applied: these aren't normal LoRAs. They aren't even in one format. This node exists purely to read them.

Two key layouts, neither of them ComfyUI's

UltraTex's LoRA files come out of the project's own training code, and they carry the naming that training code used.

The FLUX.2 ones (the albedo and metallic-roughness LoRAs that go with Klein) are PEFT exports: keys like base_model.model.<module>.lora_A.default.weight with the alpha baked to equal the rank, so the effective scale is 1. ComfyUI's loader wants lora_down.weight / lora_up.weight, doesn't recognise the .default infix, and skips the whole file.

The FLUX.1 ones are stranger. They're UNO-format: <block>.processor.qkv_lora1.down.weight and friends, where the names map onto FLUX's attention modules by a lookup table rather than by matching names - qkv_lora1 → img_attn.qkv, qkv_lora2 → txt_attn.qkv, proj_lora → linear2, and so on. The single-block case is the fiddly bit: the qkv LoRA only covers the first 3H rows of linear1, so the converter zero-pads an up-projection to fill the rest of the matrix. Get that wrong and you get a LoRA that loads cleanly and quietly does nothing useful.

So the node converts whichever format it detects into ComfyUI's generic patch format and hands the patched model back.

Inputs and output

Three inputs. model is the loaded diffusion model - FLUX.2-Klein-base-9B is the intended one, and yes, base rather than distilled, which is a deliberate choice: the UltraTex LoRA was trained on the undistilled backbone, and the base variant is exactly what the community says it's for, training and fine-tuning rather than 4-step generation. lora_name is a dropdown fed from models/loras, so the file has to live there. strength defaults to 1.0, which is what you want; there's a -10 to 10 range in case you enjoy suffering.

Output is MODEL. Wire it into UltraTex Sampler and nowhere else - this is a task LoRA, not a style, and putting it in front of anything else is going to produce interesting colours.

Splitting the model for albedo vs metallic-roughness

UltraTex ships two FLUX.2 LoRAs, and they're separately applied. You branch the model after loading it: one Load Diffusion Model → one UltraTex LoRA for albedo, a second copy → a second UltraTex LoRA for the MR file, then two samplers sharing the same VAE, positive conditioning and prep. The sampler doesn't have a "mode" switch; which LoRA it's wearing is what decides whether it's predicting colour or roughness and metalness. That's also why the MR pass can run at 1024 while albedo runs at 2048 - MR maps are low-frequency and there's nothing to gain from the extra resolution.

The check it does for you

The node inspects the loaded model's family before patching and raises a clear error if you've crossed the streams - an UNO/FLUX.1 LoRA onto a FLUX.2 model, or the reverse. After patching it counts how many layers matched and logs a warning if some didn't. That warning is worth reading instead of scrolling past: it means the checkpoint and the base model disagree, and the result will be subtly wrong rather than obviously broken.

Install

Manager → ComfyUI-UltraTex, or the clone:

cd ComfyUI/custom_nodes
git clone https://github.com/visualbruno/ComfyUI-UltraTex

Then get the weights. The LoRA files come from the UltraTex model release (ModelScope, Yibo-Zhang/UltraTex) as two files both literally named dit_lora.safetensors, one under flux2/lora/ and one under flux2_mr/lora/. Rename them on the way into models/loras - ultratex_flux2.safetensors and ultratex_flux2_mr.safetensors - or you'll be staring at two identical dropdown entries guessing which is which.

Gotchas

  • Renaming matters, and so does re-scanning: after adding files, refresh the node list so the dropdown picks them up.
  • Cross-family LoRAs are a hard error, not a warning, so if you see "this LoRA is for FLUX2 but the model is FLUX1", that's the check working, not a bug.
  • The FLUX.1 path also needs its own flux1/lora/dit_lora.safetensors; they're not interchangeable with the FLUX.2 pair, and the JSON key names in the converter are what tells them apart.
CategoryUltraTex

Inputs (3)

NameTypeDefaultDescription
modelMODEL—
lora_nameCOMBO0 options:
strengthFLOAT1.00-10–10—

Outputs (1)

NameTypeDescription
MODELMODEL—