Styles in nested subfolders that shared a base JSON name were being
overwritten because load_style keyed self.styles by the raw style["name"]
while the Style object stored the prefixed name. The extra networks page
iterates dict keys, so only one card per name surfaced.
Key the dict by the same prefixed name, and warn when a true duplicate
(same prefix and same name) is still detected.
NetworkOnDisk.fullname stripped only "/" from the post-lora_dir slice,
leaving a leading "\" on Windows. Every prompt typing the file's
natural dot-form name missed both registered aliases. On Linux,
dot-form lookup already missed when the file lived in any subfolder
because only the subfolder-prefixed form was registered.
- network.py: lstrip both separators and normalize backslashes to
forward slashes so fullname has one canonical shape per OS.
- lora_load.py: register a bare-basename-with-dots alias so typing
<lora:my.lora:1> resolves regardless of subfolder placement.
setdefault preserves explicit primary registrations on cross-subfolder
basename collisions.
Existing prompts using the legacy dots-to-underscores form continue
to resolve via entry.name unchanged.
modules/ui_extra_networks.py emits onclick="cardClicked(...)" on
every network card, but cardClicked was module-private in
ui/extraNetworks.ts and got tree-shaken out of the bundle. Attach
it to window like showCardDetails so card clicks resolve and the
<lora:...> insertion path works.
Replaces anima_lora.py's bespoke try_load_lora / group_keys /
resolve_network_key with thin wrappers binding native_loader's generics
to anima's prefix tuples and resolve_targets, mirroring flux2 / zimage /
chroma / ernie. The hand-rolled apply_lora_alphas bake-with-balance
pass goes away; alpha / scale / dora_scale flow through NetworkWeights.w
to NetworkModule.calc_scale at apply time.
native_loader gains an optional network_prefix kwarg (str or
Callable[[prefix_used], str], default "lora_transformer_") used when
constructing network_key. Anima passes a callable picking
lora_transformer_ / lora_llm_adapter_ / lora_te_ per matched prefix.
Single-component siblings keep the default and are unchanged.
network.NetworkModule.apply_weight_decompose grows a dual-path DoRA
convention detector. The pre-fix implementation only handled per-input
dora_scale (DoRA paper / kohya, shape (1, in)), silently broadcasting
per-output LyCORIS / PEFT dora_scale (shape (out, 1)) into an incoherent
element-wise rescaling. Detection is structural: (out, 1, ...) routes
to per-output; everything else (including the square-weight 1D ambiguity)
defaults to per-input for legacy compat. Pre-existing bug surfaced by
the LoKR+DoRA LyCORIS files Anima now loads.
Behavior changes:
- LoHA via the generic try_load_loha (NetworkModuleHada); covers
scenery-anima-base and any other LyCORIS .hada_w* export.
- Kohya lora_te_ prefix recognized. The legacy resolver only matched
BFL text_encoders.qwen3_06b.transformer.model. and silently dropped
lora_te_layers_N_* keys (41% of BlueArcStyle's bases were unloaded).
- LoKR+DoRA LyCORIS files now apply correctly; the per-output dora_scale
is honored instead of silently scrambled.
Adds test/test-anima-native-adapters.py: 37 offline tests across all
five prefixes (LoRA + LoHA), every COSMOS_2_FLAT_RENAME entry, DoRA
threading, marker disambiguation, try_load_chain dispatch, calc_updown
sanity, and both DoRA conventions (per-input / per-output / 1D ambiguous).
Adapter mock mirrors AnimaLLMAdapter's real module tree.
Editable dropdowns (sd_model_checkpoint, sd_text_encoder) fired a
.change event on every keystroke because Gradio's allow_custom_value
keyup handler sets the value to the typed text.
- Use .blur instead of .change for DropdownEditable in quicksettings
- Validate model keys in run_settings_single before committing
- 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.