Nodes/ComfyUI-MiniMaxH3RefLoRA/Load H3 RefLoRA (LoRA + RefMod)
ComfyUI Node

Load H3 RefLoRA (LoRA + RefMod)

The node that loads a LoRA and its face reference out of one file

By malcolmamal·Created 22 days ago·Updated 22 days ago· 9
Load H3 RefLoRA (LoRA + RefMod)
  • model
  • clip
  • model
  • clip
  • mods
  • info
◄reflora_name▾►
◄lora_strength1.00►
◄refmod_retention1.00►
◄membersall►
◄attach_to_modelfalse►
◄lora_strength_clip1.00►
◄componentsAll►
◄max_total_tokens0►
◄show_infotrue►

If you've trained a character on MiniMax H3, you know the drill: the LoRA gets you the angles and the odd details, but your subject's face drifts a few percent from frame to frame. So you also drop a reference into the workflow - H3 takes references natively - and now you're managing two files per character per epoch, and sooner or later you pair the wrong refmod with the wrong checkpoint and waste an afternoon.

This node reads a RefLoRA: one .safetensors that contains a MiniMax H3 LoRA and its reference latents, side by side. You wire one file, you get a patched model and the references out in one go.

What's actually inside the file

A RefLoRA isn't a new format. It's a plain safetensors file that happens to hold two kinds of tensor: lora_unet_*.lora_down/up/alpha (kohya naming, byte-identical to the LoRA you packed in) plus ref_0 … ref_n, which are the latents - [1,24,T,H,W] for a visual reference, [1,32,2,T] for audio. The header carries the LoRA's ss_* metadata, the reference bundle JSON in ComfyUI-MiniMaxH3Mod's own version-5 format, and a small h3_hybrid marker saying how many weight tensors were supposed to be there.

That marker matters more than it sounds. ComfyUI's LoRA loader walks the model's key map looking for matching entries, so extra ref_* tensors are ignored - which is why Load LoRA, LoraLoaderModelOnly and rgthree's Power Lora Loader all read a RefLoRA as an ordinary LoRA and generate happily. You'll see a couple of "lora key not loaded" warnings in the console; that's the references being skipped, and it's harmless.

Why ship both instead of picking one

They cover different failure modes. A LoRA has baked in everything the training set showed it - that's the advantage over bolting consistency on at inference time, and why character LoRAs remain the community's most reliable approach. What a LoRA can't contain is anything the training images never showed. A reference covers exactly that gap, as a token-level identity lock the weights never learned - but references cost tokens at generation time, so the budget stretches to a handful of images and everything you didn't supply, the reference has to infer. Neither half is redundant, and one file means the two can't drift apart.

The inputs you'll actually touch

Wire model from your model line - in practice after whatever turbo or speed LoRA you already run. Then pick reflora_name from models/loras/; a normal LoRA works here too, it just loads with no references.

lora_strength is the usual weight dial on the model; at 0 the node skips patching entirely and passes the model through, which is a handy A/B switch. refmod_retention is the reference strength, and the tooltip gives you the author's own scale: 1.0 fully preserved, 0.7 partially, 0.4 attribute transfer, 0.15 weak, 0 none.

members picks which references in the container actually load, numbered as the Inspect node lists them - all, none, or something like 1,3-4. Handy for a two-reference container where you only want one, and unselected members are never read off disk.

attach_to_model is the fork in the road. Leave it off (default) and you take the mods output into an Apply node. Turn it on and the references ride the model line instead, so nothing needs wiring into the conditioning at all - one node, one wire. Don't do both; every reference gets injected twice.

Under the optional inputs: clip is usually left empty (H3 LoRAs are lora_unet_* only), components filters references to All / Visual / Audio before loading, max_total_tokens is your budget guard, and show_info prints the container contents on load. Outputs are model, clip, mods and info.

Install

ComfyUI Manager, search ComfyUI-MiniMaxH3RefLoRA, or:

cd ComfyUI/custom_nodes
git clone https://github.com/malcolmamal/ComfyUI-MiniMaxH3RefLoRA

Restart ComfyUI. That's the whole install - there's no requirements.txt in the repo. Put containers in models/loras/ (the pack's default subfolder is MinimaxH3/reflora) and standalone RefMods in models/refmods/; the pack registers that refmods path itself, so you don't need another pack just to make the directory visible. Working example graphs are in the repo's examples/ folder, all built off a MiniMax H3 turbo 8-step graph.

Where people get burned

Reference tokens aren't free. A full-resolution identity reference can cost several thousand tokens in every DiT block, and the budget check fires before sampling. Set max_total_tokens if you're stacking references, or you'll find out the expensive way.

Double injection. attach_to_model on and mods wired into an Apply node is the classic mistake - the run succeeds and the references are counted twice.

Re-saving through the wrong tool. If you have ComfyUI-MiniMaxH3Mod installed and you load a RefLoRA there, its Bundle Save node writes only the ref_i tensors - the LoRA half is dropped with no error. This pack's loader warns when a container's declared tensor count no longer matches what's present, and Inspect's verify_bytes catches it outright. Re-save through this pack's Pack node instead.

The licence. H3's open weights are territory-restricted - the Community License excludes the US, EU, UK and Korea. Nothing to do with this node, but worth knowing before you build a pipeline on it.

CategoryMiniMax-H3/reflora

Inputs (11)

NameTypeDefaultDescription
modelMODELThe model the LoRA weights patch.
reflora_nameCOMBOA RefLoRA container in models/loras/. An ordinary LoRA also works -- it simply has no references to load.
lora_strengthFLOAT1.00-10–10LoRA weight strength on the model. 0 skips patching entirely.
refmod_retentionFLOAT1.000–1Reference strength. 1.0 = fully preserved, 0.7 = partially preserved, 0.4 = attribute transfer, 0.15 = weak. 0 loads no references at all.
membersSTRINGallWhich references to load, numbered as the Inspect node shows them: 'all', 'none', or a list like '1' or '1,3-4'. Unselected members are never read off disk.
attach_to_modelBOOLEANfalseON: the references ride the MODEL output, so nothing has to be wired into the conditioning -- one node, one wire. OFF (default): use the H3_REF_MODS output with an Apply node. Do not do both, or every reference is injected twice.
clipoptCLIPOptional. MiniMax H3 LoRAs are lora_unet_* only, so this is usually left unconnected.
lora_strength_clipoptFLOAT1.00-10–10—
componentsoptCOMBOAllFilter references by modality before loading them.
max_total_tokensoptINT00–1048576Reference token budget; 0 disables it. References are not free -- a full-resolution identity reference can cost several thousand tokens in every DiT block.
show_infooptBOOLEANtruePrint the container's contents to the console on load.

Outputs (4)

NameTypeDescription
modelMODEL—
clipCLIP—
modsH3_REF_MODS—
infoSTRING—