Skip to content

feat(lora): support kohya-format MiniMax H3 LoRAs - #9703

Merged
lstein merged 7 commits into
invoke-ai:mainfrom
lstein:feat/minimax-h3-kohya-lora
Oct 17, 2026
Merged

lstein merged 7 commits into
invoke-ai:mainfrom
lstein:feat/minimax-h3-kohya-lora

Conversation

@lstein

@lstein lstein commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

MiniMax H3 LoRAs trained with kohya sd-scripts / musubi-tuner (e.g. Inner-Reflections/MiniMax-H3-Looping-Sketch-Anime) failed to install with "not recognized": they use flattened keys with per-layer alpha (lora_unet_blocks_0_attn_qkv_proj.lora_down.weight, .alpha), while H3 LoRA identification only understood the dotted native layout used by the Turbo LoRA (blocks.0.attn.qkv_proj.lora_A.weight).

  • Kohya keys are un-flattened against the H3 Linear vocabulary (block qkv/out/fc1/fc2/AdaLN, token-refiner qkv/out/fc1/fc2, final-layer AdaLN), so identification and conversion share the dotted layout and the existing fused-QKV split, SwiGLU half-swap, and pruned-model AdaLN routing apply unchanged. File .alpha tensors are honored.
  • A lora_unet_ key that does not reconstruct to an H3 Linear rejects the file instead of installing a LoRA that silently patches nothing.
  • The kohya leaf check moves from krea2_lora_constants to kohya_key_utils so Krea-2 and H3 share it (no Krea-2 behavior change).

Related Issues / Discussions

None.

QA Instructions

  • uv run --no-sync pytest tests/backend/patches tests/backend/model_manager tests/backend/minimax_h3 tests/app/invocations — 4610 passed.
  • ruff@0.11.2 check/format clean.
  • minimax_h3_looping_sketch_anime_v1.safetensors (musubi-tuner, 600 tensors, rank 32, alpha 32): main identifies it as Unknown_Config; this branch identifies it only as LoRA_LyCORIS_MiniMaxH3_Config. It converts to 300 layers, each resolving to an nn.Linear with matching shape on a meta-device MiniMaxH3Transformer3DModel built from the released transformer config.
  • Manual: installed a kohya-format H3 LoRA with the same 600-key layout and generated with it on an H3 model; the LoRA takes effect.
  • New tests were mutation-checked: removing the converter normalization, the unresolvable-key rejection, the leaf check, or the refiner-has-no-AdaLN restriction each fails a test.

Review

No material findings. Known limitations shared with the existing dotted-key path, left out of scope: factorized LoKR / .diff keys are accepted at install but fail at load, non-lora_unet_ foreign keys (e.g. lora_te_*) convert to no-op layers, and zero-padded block indices are not rejected.

Checklist

  • The PR has a short but descriptive title, suitable for a changelog
  • Meaningful regression coverage added / updated where needed; obsolete tests/code removed
  • Persisted-state and API changes include required migrations / compatibility validation
  • Relevant performance/efficiency opportunities considered; material claims have evidence
  • Material review findings resolved and relevant checks rerun
  • Documentation added / updated (if applicable)
  • Updated What's New copy (if doing a release after this PR)

🤖 Generated with Claude Code

Un-flatten lora_unet_* keys against the H3 Linear vocabulary so detection and
conversion share the dotted native layout; unresolvable kohya keys reject the file.
Move the kohya leaf check into kohya_key_utils for reuse by Krea-2 and H3.
@github-actions github-actions Bot added python PRs that change python files backend PRs that change backend files python-tests PRs that change python tests labels Oct 8, 2026
@lstein
lstein requested a review from Pfannkuchensack October 8, 2026 02:14
@lstein lstein added the 7.0.0 label Oct 8, 2026

@JPPhoto JPPhoto left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No merge blockers, but there is something to investigate:

  • invokeai/backend/patches/lora_conversions/minimax_h3_lora_constants.py:136: Flattened H3 keys pass the probe, which checks for any LoRA suffix at invokeai/backend/model_manager/configs/lora.py:1238. A file with lora_down but no matching lora_up is accepted; conversion then raises KeyError at invokeai/backend/patches/lora_conversions/minimax_h3_lora_conversion_utils.py:120. The equivalent dotted PEFT gap predates this PR. Effect: installation succeeds, then loading or generation fails. Likelihood: plausible for an incomplete or corrupt adapter. Recovery: replace and reinstall it. Test: assert the H3 probe rejects an unmatched Kohya pair.

Corner/impossible cases to note but not do anything about:

  • invokeai/backend/patches/lora_conversions/minimax_h3_lora_conversion_utils.py:109: If a file contains the same layer in dotted and flattened forms with different tensors, normalization overwrites one based on key order. Effect: one adapter weight is silently discarded. Likelihood: rare mixed-format file. Recovery: re-export one form. Test: assert duplicate normalized keys are rejected.

Suggested follow-up work (pre-existing):

  • invokeai/backend/patches/lora_conversions/minimax_h3_lora_constants.py:118: The existing H3 probe does not reject PEFT lora_magnitude_vector.weight; _normalize_lora_param_names drops that DoRA magnitude. Please make an issue: reject or support PEFT DoRA magnitude keys.

Probe and converter share one rule: each layer is exactly one lora_A/lora_B or lora_down/lora_up pair plus optional alpha.
Half pairs, a layer in two spellings, mixed naming and stray tensors (incl. PEFT DoRA magnitudes) now fail with a clear error instead of crashing or being dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lstein

lstein commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator Author

@JPPhoto thanks for the review. All three points are addressed in e8b8992.

Unmatched pairs (main finding). Confirmed for both kohya and dotted keys. The probe and the converter now share one rule, group_minimax_h3_lora_keys in minimax_h3_lora_constants.py: every layer must carry exactly one lora_A/lora_B or lora_down/lora_up pair, optionally with alpha. A lone half now fails at install with a "malformed MiniMax H3 LoRA" message, and the converter raises ValueError instead of KeyError. _get_base_or_raise and is_state_dict_likely_in_minimax_h3_format apply the same rule. The test you asked for is test_h3_probe_rejects_malformed_lora, parametrised over an unmatched kohya pair, an unmatched dotted pair, and the cases below.

Same layer in two spellings. Confirmed. It was also slightly worse than described: with A/B in one form and down/up in the other, nothing was overwritten, but the down/up pair was silently dropped. Grouping now un-flattens kohya keys and strips the PEFT prefix before checking for duplicates. Dotted vs. kohya, prefixed vs. unprefixed, and mixed A/B with down/up in one layer are all rejected.

PEFT DoRA magnitude. Instead of only filing an issue, I folded the rejection into the same rule: any tensor that isn't a LoRA pair or alpha is rejected, lora_magnitude_vector.weight included. So DoRA adapters are no longer applied silently as plain LoRA. Actual support is #9900. It's mostly runtime-limited: both H3 starter transformers are int8-convrot and AdaLN-pruned, neither of which exposes the original weight that DoRA needs.

All three published Turbo LoRA variants pass the new rule, and conversion output on real H3 LoRAs (published Turbo, kohya with alpha, ComfyUI A/B with alpha) is identical to the previous head.

@JPPhoto
JPPhoto self-requested a review October 17, 2026 19:54

@JPPhoto JPPhoto left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved! I am making an issue for two findings that pre-date this work and assigning to you. You're welcome.

@lstein
lstein enabled auto-merge October 17, 2026 20:28
@lstein
lstein merged commit 490d0d0 into invoke-ai:main Oct 17, 2026
17 checks passed
@lstein
lstein deleted the feat/minimax-h3-kohya-lora branch October 17, 2026 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

7.0.0 backend PRs that change backend files python PRs that change python files python-tests PRs that change python tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants