The parser no longer takes reference-name prefixes to tell bare
reference keys from bare diffusers keys. Any bare key carries the
sentinel and the arch resolver renames what it knows and passes the rest
through. Flux2 keeps its list for file-format detection only.
A bare key that matches no known prefix is parsed with the
bare-diffusers sentinel and handed to the resolver instead of being
dropped at parse time. The per-arch lists of bare diffusers prefixes are
gone, and a path that names no live module counts as unmapped.
The lycoris_ save format is arch-independent: LyCORIS standalone wraps
the loaded diffusers model and emits the wrapped module path with dots
as underscores, so verbatim passthrough is correct for any arch. Only
flux2 handled it; zimage, chroma, ernie and krea2 reported such files
as not loaded.
- add lycoris_ to KNOWN_PREFIXES_DEFAULT and PASSTHROUGH_PREFIXES_DEFAULT
- drop flux2's per-arch prefix append and resolve_targets branch
- add lycoris_ to ANIMA_PREFIXES (anima replaces the default tuple);
network_prefix_for already routes it to the transformer namespace
- cover the passthrough with a zimage loader test
BFL-format adapters targeting the embedders, timestep/guidance MLPs,
modulation layers and the final layer resolved to nothing and were
dropped as unmapped, for every adapter family on the f2 native path.
- add F2_EXTRA_MAP exact-match lookups in both target resolvers, with
the kohya underscore form derived from the BFL path
- add guidance_in. to BARE_FLUX_PREFIXES; groups targeting the guidance
embedder stay unmapped on models built without guidance_embeds
- extend the offline test mock with the non-block targets and cover all
three key forms plus full-matrix LoKR with placeholder alpha
transformer., bare-diffusers, and lora_transformer_ bases are already in
network-key form for every arch, yet each per-arch resolve_targets repeated the
same passthrough branch for them. Move that into a shared
PASSTHROUGH_PREFIXES_DEFAULT set consulted by resolve_group_targets, leaving each
arch's resolve_targets to only the prefixes it actually rewrites (kohya / BFL).
lycoris_ stays in flux2, the one arch that recognizes it.
Pure refactor: the same keys resolve to the same modules.
Replaces flux2's eight family loaders with thin wrappers binding
native_loader's generics to flux2's prefix tuples and resolve_targets.
Constants and helpers (has_marker, parse_key, group_by_suffixes) are
re-exported from native_loader so the offline tests address them through
flux2_lora's surface unchanged.
resolve_targets now returns (diffusers_path, ChunkSpec | None) tuples
instead of (path, idx, num_chunks). Three parse-level tests updated.
PEFT-fallback path (apply_lora_alphas, preprocess_f2_keys, apply_patch)
stays in flux2_lora.
Move the family-iteration loop into pipelines/flux/flux2_lora.try_load
so the f2 branch in lora_load.load_safetensors becomes a one-line call.
Per-family try_load_* entry points stay public for direct testing.
Addresses review feedback on PR #4841.
Discriminated from OFT by 4-D oft_blocks shape (boft_m, block_num,
block_size, block_size), mirroring LyCORIS algo_check. The cascade
of log_2(block_num)+1 Cayley rotations is applied via the
unflatten/transpose/flatten reshape sequence in NetworkModuleBOFT,
porting LyCORIS make_weight verbatim.
base_model.model. is the peft.save_pretrained wrapper; stripped
via _unwrap_peft_wrapper and re-parsed against the standard prefix
list (so the same code path handles whatever format peft wrapped).
lycoris_ is LyCORIS-standalone (e.g. SimpleTuner LoKR); base path
is an underscore-rendered diffusers path returned verbatim.
Targets the elementwise-affine RMSNorms inside attention (norm_q,
norm_k, norm_added_q, norm_added_k). lora_convert.py:502 skips
network_layer_name on transformer norm modules outside SD3, so this
loader stamps it directly on the modules it binds — surgical, no
shared-code edit, no impact on modules a Norm adapter doesn't target.
Loads the four ab.weight tensors plus alpha. Fused QKV is skipped:
GLoRA's target-dependent term doesn't row-slice cleanly without
recomputing against a fused proxy weight.
The .on_input marker disambiguates IA3 from other families that also
have .weight keys; the per-group gate insists on both. Fused QKV is
skipped with a warning.
Both kohya (oft_blocks + alpha-as-constraint) and LyCORIS (oft_diag)
layouts route through NetworkModuleOFT. Fused QKV in double_blocks is
skipped: the block-diagonal rotation's block_size = out_features /
num_blocks would need re-derivation per chunk to fit a Q/K/V split.
Standard non-Tucker LoHAs route through NetworkModuleHadaChunk for
fused QKV in double_blocks. Tucker (CP-decomposed) variants on fused
targets are skipped with a warning. Single-block linear1 and non-QKV
double-block targets work for any LoHA layout.
Adds per-family SUFFIX/MARKER tables and shared parse_key /
group_by_suffixes / resolve_targets helpers, mirroring the pattern
in pipelines/z_image/zimage_lora.py. try_load_lora and try_load_lokr
now share this scaffolding alongside the family loaders that follow.
Load Flux2/Klein LoRAs as native NetworkModuleLora objects, bypassing
diffusers PEFT. Handles kohya (lora_unet_), AI toolkit (diffusion_model.),
diffusers PEFT (transformer.), and bare BFL key formats with automatic
QKV splitting for double block fused attention weights.
Includes shape validation to reject architecture-mismatched LoRAs early.
Respects lora_force_diffusers setting to fall back to PEFT when needed.
- detect f2 model type for LoRAs via metadata, architecture, and filename/folder
- preprocess bare BFL-format keys with diffusion_model prefix for Flux2LoraLoaderMixin
- handle LoKR format via native NetworkModuleLokr with on-the-fly kron(w1, w2)
- add NetworkModuleLokrChunk for fused QKV split into separate Q/K/V modules
- activate native modules loaded via diffusers path
- improve error message for Flux1/Flux2 architecture mismatch
- Rename HuggingFace org from nunchaku-tech to nunchaku-ai across all
nunchaku model repos (flux, sdxl, sana, z-image, qwen, t5)
- Add per-torch-version nunchaku version mapping instead of single global
version, with robust torch version parsing