ComfyUI Node

LoRA Loader

The QG LoRA Loader Actually Earns Its Canvas Space

By live1617·Created 23 days ago·Updated 2 days ago· 4
LoRA Loader
  • model
  • clip
  • model
  • clip
  • triggers
◄loras[]►
◄trigger_separator, ►
◄on_missingerror►

The problem it's solving

Core ComfyUI gives you one LoRA per node. Stack four on a checkpoint and you're looking at five nodes, eight wires, and a trigger word you've definitely forgotten. Stacking is normal practice now - heavier ones first, weights down to 0.5–0.8 when a LoRA starts overruling your prompt - and the stock chain makes all of that fiddly.

QG LoRA Loader is one node that holds the whole stack. Rows you can drag to reorder, toggle off, search by name, and scrub the strength of by dragging left and right on the name itself. That alone isn't novel - rgthree's Power Lora Loader has been the community's default answer for years. What's actually different here: the stack spits out a merged trigger words string, the whole stack can be saved as a named template and reapplied in one click, and there's an "absorb" action that eats the other LoRA loaders sitting in your model chain.

How it works, briefly

The node keeps its rows as JSON inside a multiline STRING widget called loras. That's deliberate - save, undo, copy-paste and API export all travel through ComfyUI's normal paths. On execution the backend parses the rows, resolves each name against your loras folder, and patches in row order, exactly like chained nodes would.

Trigger words come from three places, in order of preference: what you typed on the row, what the file says about itself (an explicit trigger phrase in its safetensors metadata, otherwise the top few tags from ss_tag_frequency), or a Civitai lookup for LoRAs you've cached. Everything from enabled rows is deduplicated and joined with trigger_separator.

The inputs and outputs that matter

  • model - required. The diffusion model the stack patches.
  • loras - required, and panel-managed. Edit the rows on the node, not this value.
  • clip - optional. Wire it. Without it, every row's CLIP strength is forced to zero and your per-row CLIP weights silently do nothing.
  • trigger_separator - how trigger words get joined, default , . Set from the gear menu; hidden on the canvas.
  • on_missing - error (default) or skip. Also gear-menu only.

Outputs are model, clip, and triggers. Wire the first two onward as usual, and run triggers into a text node or a concat before your positive prompt so the activation words follow the LoRAs automatically.

One design choice worth knowing: a row at strength 0 keeps its trigger words. That's on purpose - you can A/B a LoRA by scrubbing its weight to zero without touching the prompt at all. Only rows skipped for a missing file contribute nothing.

Absorb chain LoRAs

This is the part I haven't seen elsewhere. In the gear menu, Absorb chain LoRAs walks the model chain in both directions, pulls every LoRA out of the other loaders it finds there - including rgthree, JPS and Pixaroma nodes - folds them into this stack, and bypasses the originals. Output is supposed to be identical; all that changed is where the stack is managed.

Two things will stop it. If a loader on the chain gets its LoRAs from a wired input instead of its own widgets (think rgthree's Power Lora Loader fed externally), the menu tells you to disconnect first. And there's a row cap, so a huge stack has to be trimmed before it'll absorb anything.

Installing it

cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/live1617/ComfyUI-QG-tools

Manager works too - search ComfyUI-QG-Tools. The README says that path only goes live once the pack is on the Comfy Registry, so if the search comes up empty, clone it.

Then fully restart ComfyUI - not a page refresh. You should see:

[QG-tools] v0.5.0 加载完成 | 节点数 4

No pip install anything: the requirements.txt is deliberately comments-only and the package declares zero dependencies. Expect 节点数 4 even though the README still says three - an image crop/rotate/pad node landed after it was last touched.

Quick sanity check that the backend routes loaded:

curl http://127.0.0.1:8188/qg/lora/list

That endpoint returns your LoRA filenames. If it 404s, the pack didn't load - restart again and read the console.

Where people get burned

A LoRA that does nothing. Base-model mismatch, almost always. The node prints a warning naming the LoRA and the base model it declares - if you see "matched nothing in the connected model", you've put an SDXL LoRA on a Flux checkpoint. The other two classics still apply: weight too high, or a missing trigger word.

A missing file. A LoRA that was just moved elsewhere inside your loras folder resolves by filename at run time, no action needed. A genuinely missing one is where the default on_missing: error earns its keep: it fails validation before anything samples and names the file, so an unattended run never quietly renders without a LoRA you asked for. Turn off Stop on missing LoRA in the gear menu if you'd rather get a console warning and a skipped row.

Stale panel. Front-end changes only get read when the page loads, so a hard refresh (Ctrl+Shift+R) after updating.

One honest caution: this is a young, single-author pack, and it's a heavily customised canvas panel. That's exactly the category of node ComfyUI's Nodes 2.0 frontend rewrite broke for other packs - rgthree's LoRA toggles were still not redrawing properly months after the rewrite. If your canvas panels start misbehaving, turn Nodes 2.0 off before blaming the node.

Also: saved stack templates live in your browser's local storage - they follow you, not the workflow file.

CategoryQG-tools/Loaders

Inputs (5)

NameTypeDefaultDescription
modelMODELThe diffusion model the LoRA stack patches.
lorasSTRING[]Serialized LoRA stack managed by the node's row editor; edit the rows, not this value.
clipoptCLIPOptional CLIP to patch; without it, CLIP strengths are ignored.
trigger_separatoroptSTRING, Joins the enabled rows' trigger words into the triggers output. Set from the node's gear menu; hidden on the canvas.
on_missingoptCOMBOerrorWhat happens when an enabled row's file cannot be found. error (the default) fails validation before sampling and names the file, so an unattended or scripted run never renders without a LoRA it asked for; skip warns once in the console and applies the rest of the stack. Set from the node's gear menu (Stop on missing LoRA); hidden on the canvas.

Outputs (3)

NameTypeDescription
modelMODELThe model with every enabled LoRA applied in row order.
clipCLIPThe CLIP with every enabled LoRA applied in row order.
triggersSTRINGEnabled rows' trigger words, deduplicated and joined with trigger_separator (set in the gear menu). A row skipped for a missing file adds none.