- monkey-patch LTX2ConnectorTransformer1d.forward to restore pre-#13564
padding logic when the upstream torch.flip pattern is detected; fixes
word-order scrambling in audio dialogue tracks
- reorganize LTX model entries into version-group separators (2.3 v1.1,
2.3 v1.0, 2.0, 0.9.x) with base/distilled subgroups; separators are
selectable no-ops handled in run_ltx
Five if-blocks in lora_load.load_safetensors reduce to one lookup in
_NATIVE_DISPATCH, a string -> module-path map keyed by shared.sd_model_type.
Each entry's module exposes try_load(name, network_on_disk, lora_scale).
flux2 / zimage / chroma / ernie use the umbrella that binds native_loader's
generics via try_load_chain. Anima keeps its own try_load (aliased to
try_load_lora) since its multi-component routing doesn't fit the shared
suffix-table model.
New native archs land by adding one entry to the dict and shipping a
try_load.
Replaces ernie's four family loaders with thin wrappers binding
native_loader's generics to ernie's prefix tuples and resolve_targets.
ErnieImageAttention has fully split to_q / to_k / to_v with no fused QKV
and ErnieImageFeedForward has three separate Linear modules, so
resolve_targets is a straight passthrough across every recognized prefix.
BARE_DIFFUSERS_PREFIXES covers layers., adaLN_modulation., final_norm.,
final_linear. for bare-diffusers exports (e.g. via save_lora_adapter).
parse_key returns (prefix_used, base, suffix) instead of the old
(network_key, suffix); parse test updated.
Replaces chroma's four family loaders with thin wrappers binding
native_loader's generics to chroma's prefix tuples and resolve_targets.
resolve_targets folds the Flux-to-diffusers rename table and the two
fused-weight splits into one path-resolution step:
- img_attn.qkv / txt_attn.qkv: ChunkSpec(idx, total=3) for equal Q/K/V
- single_blocks.linear1: ChunkSpec(start, end) for the unequal
Q/K/V/proj_mlp partition
QKV_DIMS and LINEAR1_DIMS stay as module-level constants (tests patch
them for the scaled-down mock).
Behavior changes:
- LoKR on equal-chunk QKV now dispatches to NetworkModuleLokrChunk
instead of NetworkModuleLokrSliceChunk (the slice variant was used
pre-migration for both forms since chroma had no equal-chunk path).
- LoHA on fused img_attn.qkv now binds via NetworkModuleHadaChunk
instead of being skipped; the shared HadaChunk added in the flux2 PR
is general for equal-chunks dispatch.
parse_key returns (prefix_used, base, suffix) instead of the old
(flat_key, suffix); rename happens in resolve_targets. test_static_rename_table
replaced with test_resolve_targets_static_renames driving the same
remappings through the new interface.
Replaces zimage's four family loaders with thin wrappers binding
native_loader's generics to z-image's prefix tuples and resolve_targets.
resolve_targets folds the legacy attention.qkv split and attention.out
alias rename into the path-resolution step. Fused qkv now emits three
ChunkSpec(idx, total=3) entries; attention.out / attention.out.0 /
attention.wo aliases collapse to attention.to_out.0.
BARE_DIFFUSERS_PREFIXES allows bare paths starting with layers. /
noise_refiner. / context_refiner. to pass through to the loader. This
matches real Z-Image LoRAs exported via
ZImageTransformer2DModel.save_lora_adapter().
LoHA on fused qkv now binds via NetworkModuleHadaChunk (added to shared
infra by the flux2 PR) instead of being skipped. Test renamed to
test_loha_legacy_fused_qkv_chunked.
parse_key returns (prefix_used, base, suffix) instead of the old
(network_key, suffix); parse test updated.
Covers ernie's four-family surface (LoRA, LoKR, LoHA, OFT).
ErnieImageAttention has fully split to_q / to_k / to_v with no fused QKV,
and ErnieImageFeedForward has three separate Linear modules. The loader
has no chunking, renames, or fused-target dispatch.
Mock matches diffusers.ErnieImageTransformer2DModel
(ErnieImageSharedAdaLNBlock with self_attention + mlp + RMSNorms, plus
module-level adaLN_modulation Sequential and final_linear).
Formats exercised:
- BFL / AI-toolkit
- kohya
- BFL LoKR
Covers chroma's four-family surface plus the Flux-to-diffusers rename
and the unique single-block linear1 unequal-chunk slicing.
Mock transformer matches diffusers.ChromaTransformer2DModel
(transformer_blocks with FluxAttention(added_kv_proj_dim), single
transformer_blocks with pre-only attn + proj_mlp + proj_out, plus
distilled_guidance_layer).
Formats exercised:
- BFL / AI-toolkit
- kohya
- PEFT
- LyCORIS oft_diag
install_mock_pipe patches chroma_lora.QKV_DIMS and LINEAR1_DIMS to the
test scale (HIDDEN=96, MLP_HIDDEN=384); the module otherwise hardcodes
Chroma1-HD's 3072 / 12288.
try_load_lokr renamed slice_info keys via static_rename but didn't add
the lora_transformer_ prefix that apply_static_rename adds to the groups
dict. slice_info.get(network_key) always returned None for fused targets,
so the loader fell back to NetworkModuleLokr instead of
NetworkModuleLokrSliceChunk on every fused-QKV / fused-linear1 adapter.
The full kron(w1, w2) was applied against split target modules, either
shape-mismatching at apply time or broadcasting wrong.
Caught by test_lokr_bfl_img_attn_qkv_slice_chunked. No real-world chroma
LoKR adapters on fused targets are known in the wild.
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.
Same parameterized shape as the core 4.
- IA3: .on_input is the marker disambiguator (.weight is too generic).
Fused targets skipped.
- GLoRA: requires a1/a2/b1/b2 per group. Fused skipped (target-dependent
term doesn't slice cleanly).
- Norm: never fused. Loader-local network_layer_name stamping bypasses
lora_convert's transformer-norm guard without changing the carve-out.
- Full: fused skipped (no chunk class for diff tensors).
Family loaders parameterized on per-arch resolve_targets callable and
prefix tuples. Build network keys as
"lora_transformer_" + path.replace(".", "_").
Fused-target handling:
- LoRA: chunk at load time, supports both equal and unequal ChunkSpec
- LoKR: dispatch to NetworkModuleLokrChunk (equal) or LokrSliceChunk
(unequal), materialize kron(w1, w2) lazily
- LoHA: NetworkModuleHadaChunk for equal only; Tucker-on-fused and
unequal skipped with warning
- OFT/BOFT: fused skipped with warning. Algorithm discriminated by
oft_blocks.ndim (3-D OFT, 4-D BOFT)
Plus try_load_chain umbrella for per-arch family-iteration wrappers.
Lifts the slice variant from chroma_lora into network_lokr so the generic
LoKR loader can dispatch to either NetworkModuleLokrChunk (equal chunks)
or NetworkModuleLokrSliceChunk (unequal ranges) based on ChunkSpec shape.
chroma_lora keeps the same slice path through an updated import.
Lifts the parts of the per-arch native loaders that are byte-identical
across z-image, chroma, ernie, and flux2 into a new shared module.
- Suffix and marker tables for all nine families
- SUFFIX_NORMALIZE (lora_A/lora_B to lora_down/lora_up)
- KNOWN_PREFIXES_DEFAULT and BARE_DIFFUSERS_PREFIX_USED sentinel
- ChunkSpec dataclass for fused-weight slicing (equal idx+total or
unequal start+end)
- unwrap_peft_wrapper and strip_peft_adapter_name
- has_marker, resolve_mapping, new_network, finalize_network, shapes_match
- Parameterized parse_key and group_by_suffixes