MiniMax H3 Power LoRA Stack
The H3 LoRA loader that stops ComfyUI quietly eating your LoRA
- model
- adaln_modality
- schedule
- MODEL
- report
On a quantized H3 checkpoint, the stock LoRA path doesn't just do a worse job - it does almost nothing. ComfyUI dequantizes the layer, adds your LoRA delta, and requantizes. That round trip isn't idempotent: refitting the int4 codebook injects roughly 1.5% relative weight noise, while a typical H3 LoRA delta is 0.01–0.08% of the weight. The LoRA disappears into the rounding error, and you spend an evening wondering why strength 1.4 still looks like no LoRA at all.
That's the problem this node exists for. It's a multi-LoRA loader like rgthree's Power Lora Loader - rows, toggles, per-row strength - rebuilt for the ways H3 specifically breaks generic loaders.
What it actually fixes
Three things, and the README is unusually blunt about all of them.
Quantized bases. With quantized_layers=auto, quantized layers are patched through an exact runtime low-rank branch, y = W_q(x) + B @ A @ x, instead of being merged into the weights. The quantized kernel keeps working; you pay about 1.5% extra FLOPs at rank 64. The rest of the model merges normally. The README's own numbers: on a w4a8 checkpoint the stock merge recovers under a third of the LoRA's magnitude (cosine 0.12–0.14) and takes 128s where the branch takes 6.5s. merge is still there so you can compare, and branch refuses to modify any weight at all.
adaLN basis mismatch. H3 ships in two forms. Dense checkpoints feed silu(time_embedder(t)) - 2688 wide - into every adaln_proj.linear. Curve (pruned) checkpoints store a [grid, 8] table and drop the time embedder. A LoRA trained on one has the wrong lora_A width for the other, so ComfyUI logs a shape error and skips the layer. On turbo distillation LoRAs, the constant term alone is about 100% of dW @ S(t), so "just drop those pairs" isn't a fix. This node recovers S(t) = c + V @ table(t) by least squares, changes basis preserving rank, and emits the difference as a .diff_b bias. End-to-end the ported adapter matches the dense contribution at cos 0.999998.
Key conventions. ai-toolkit, kohya/musubi, lycoris, peft and bare-prefix layouts all resolve against the model's own state dict, so qkv_proj is never split into two tokens. Unmatched keys get reported per row.
Stacking itself is cheap: N LoRAs on the same layer fuse by concatenating along the rank axis, so a ten-LoRA stack costs one extra matmul pair per layer, not ten.
The inputs you'll actually touch
Wire your model into model, and leave quantized_layers on auto unless you're debugging - that's the whole configuration for most people. adaln_port defaults to auto as well; set it to off only if you mean to keep a separate AdaLN-fix node attached to the same MODEL, because the two fight. (The README also documents a strip mode that drops mismatched pairs rather than rebasing them.)
adaln_modality and schedule are the two optional wires into the pack's other nodes: one scales modulation per modality, the other varies row strengths across the denoising trajectory. Rows themselves are added in the node's UI - each gets a LoRA picker, an on/off toggle and a strength, and the frontend mints them dynamically, which is why the node has no fixed list of LoRA inputs in its schema.
Two outputs. MODEL goes on to your sampler like any patched model. report is a plain string - wire it to a Show Text node. Read it at least once; it's where this pack tells you what it did instead of failing silently.
Install
Nothing to pip install - the pyproject declares zero dependencies. Python 3.10+ and a recent ComfyUI build with MiniMax H3 support.
cd ComfyUI/custom_nodes
git clone https://github.com/cicalooo/ComfyUI-H3-PowerLoraStack
Then restart - not just refresh the node list. The pack installs a checkpoint-load hook at import time that peels adaln_basis / adaln_mean / silu_t_emb_grid off the state dict before Comfy discards them, and that only takes effect at startup. ComfyUI Manager works too: search MiniMax H3 Power LoRA Stack.
For the dense↔curve port you need h3_silu_temb_grid.safetensors in any of ComfyUI/models/h3_adaln/, models/loras/, models/diffusion_models/, or one level under custom_nodes/. Table-to-table porting needs no grid, and the README says to prefer a grid baked into your checkpoint when one exists.
Where people get burned
The famous error is ERROR lora ... adaln_proj.linear.weight shape '[96768, 8]' is invalid for input of size 260112384 - that's the dense/curve mismatch, and it's the signal to leave adaln_port on auto.
The nastier case is the one with no error. Two curve bakes can share AdaLN width, so a LoRA trained against one loads on the other without complaint and is simply wrong - the README measured cos −0.375. If you're getting mush on a pruned checkpoint and nothing in the log looks off, check which bake your LoRA was trained against.
Also worth knowing: runtime branches only apply to MODEL coming from ComfyUI's native H3 loader - the streaming loader in minimaxh3chinkloader uses its own handle and LoRA path. branch mode rejects DoRA, LoHa, LoKr and locon adapters (only plain rank decompositions have a runtime branch path), and mlp.fc2 under TensorWiseINT8Layout merges even in branch mode because it's reached through comfy.ops.linear_input_act.
Finally, strength 1.0 is not a unit. Perturbation across the non-distillation H3 corpus spans 65× at the same strength. That's what the node's Auto-balance button is for - it measures each active LoRA and trims outliers onto one scale, never boosting a deliberately quiet turbo adapter, and never weakening your other rows.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| modelopt | MODEL | — | |
| quantized_layersopt | COMBO | auto | auto: runtime branch for quantized layers, merge for the rest. branch: never modify a weight. merge: stock behaviour (destroys LoRAs on w4a8/int4). |
| adaln_portopt | COMBO | auto | Rebase adaLN LoRA pairs between dense (2688) and curve (8) checkpoints. Needs h3_silu_temb_grid.safetensors. |
| adaln_modalityopt | H3_MODALITY | Optional. Wire a MiniMax H3 adaLN Modality node here to scale every stacked LoRA's adaLN modulation per modality. | |
| scheduleopt | H3_SCHEDULE | Optional. Wire an H3 LoRA Schedule chain here to vary selected row strengths over the denoising trajectory. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | Patched model |
| report | STRING | Per-LoRA account of what was applied |