diff --git a/modules/lora/native_adapter.py b/modules/lora/native_adapter.py index d0a1679ef..f2bed9ec3 100644 --- a/modules/lora/native_adapter.py +++ b/modules/lora/native_adapter.py @@ -1,7 +1,6 @@ """Shared scaffolding for native adapter loaders. -The four native adapter loaders (z-image, chroma, ernie, flux2) all implement -the same algorithm: +Each per-arch native adapter loader implements the same algorithm: 1. Read the safetensors state dict 2. Test for family-specific markers; bail out if absent @@ -25,7 +24,7 @@ diffusers paths plus optional chunk descriptors). Per-arch loader modules import this module and pass their own ``prefixes``, ``bare_prefixes``, ``bare_diffusers_prefixes``, and ``resolve_targets`` to the -generic helpers. Loader business logic itself lands in subsequent commits. +generic helpers. """ import os @@ -45,7 +44,8 @@ from modules.lora import lora_common as l # Universal prefix list shared by every native arch loader. Per-arch loaders -# extend this with arch-specific entries (e.g. flux2 adds ``"lycoris_"``). +# extend this with arch-specific entries when their files use additional +# vendor-specific naming conventions. KNOWN_PREFIXES_DEFAULT = ("diffusion_model.", "transformer.", "lora_unet_") @@ -56,9 +56,10 @@ KNOWN_PREFIXES_DEFAULT = ("diffusion_model.", "transformer.", "lora_unet_") BARE_DIFFUSERS_PREFIX_USED = "bare_diffusers" -# Default network-key prefix. Single-component arches (flux2, zimage, chroma, -# ernie) keep this default; multi-component arches (anima: transformer plus -# llm_adapter plus text_encoder) pass a callable that picks per ``prefix_used``. +# Default network-key prefix. Single-component arches keep this default; +# multi-component arches (those with separate text-encoder or adapter +# components alongside the transformer) pass a callable that picks per +# ``prefix_used``. NETWORK_PREFIX_DEFAULT = "lora_transformer_" diff --git a/pipelines/ernie/__init__.py b/pipelines/ernie/__init__.py index dfed6ff84..d73a4f7ef 100644 --- a/pipelines/ernie/__init__.py +++ b/pipelines/ernie/__init__.py @@ -1,23 +1,17 @@ """ERNIE-Image pipeline package. -Exports :data:`ERNIE_SPEC` for use by :mod:`pipelines.model_ernie` together -with :mod:`pipelines.native_transformer`. The spec captures the -ERNIE-Image-specific knobs that differ from the native-loader defaults: +Exports :data:`ERNIE_SPEC`. The minimum +``TransformerSpec(cls=ErnieImageTransformer2DModel)`` works because Ernie +trainer dumps use BFL-style ``model.diffusion_model.``-prefixed keys +whose names match the diffusers state_dict verbatim after prefix strip +(probed against a community finetune: full key overlap with zero +missing or unexpected). No siblings, no converter, no forbidden markers. -- No converter is needed: community Ernie trainer dumps use BFL-style keys - (``model.diffusion_model.``-prefixed) whose names match diffusers' - ``ErnieImageTransformer2DModel.state_dict()`` verbatim after prefix strip. - Probed against ``jibMixErnie_v20.safetensors`` (the upstream community - finetune): 409/409 keys overlap with zero missing or unexpected. -- No siblings; no forbidden markers; default prefixes - (``model.diffusion_model.``, ``diffusion_model.``, ``net.``) cover every - exporter seen in the wild. - -Before this spec, selecting an Ernie finetune via the UNET dropdown crashed -in :func:`diffusers.loaders.ModelMixin.from_pretrained` with a misleading -``OSError: ... is not a valid JSON file`` because -``ErnieImageTransformer2DModel`` lacks ``from_single_file`` support and the -fallback path treats the safetensors as a directory looking for +Without this spec, selecting an Ernie file via the UNET dropdown crashes +in :func:`diffusers.loaders.ModelMixin.from_pretrained` with a +misleading ``OSError: ... is not a valid JSON file``, because +``ErnieImageTransformer2DModel`` lacks ``from_single_file`` and the +fallback treats the safetensors as a directory looking for ``config.json``. """ diff --git a/pipelines/qwen/__init__.py b/pipelines/qwen/__init__.py index 6dffd74b0..aac930654 100644 --- a/pipelines/qwen/__init__.py +++ b/pipelines/qwen/__init__.py @@ -1,17 +1,12 @@ """Qwen-Image pipeline package. -Exports :data:`QWEN_SPEC` for use by :mod:`pipelines.model_qwen` together -with :mod:`pipelines.native_transformer`. Qwen-Image is the lone Mode C -arch: diffusers registers a no-op identity lambda as its -``SINGLE_FILE_LOADABLE_CLASSES`` converter, so ``from_single_file`` silently -accepts whatever key naming the community file uses and loads with mangled -weights instead of raising. - -The spec explicitly sets ``converter=None`` to short-circuit the no-op -pickup; if a real Qwen-Image converter is needed for some trainer dump -in the wild, it can be plugged in here. Until then, validation surfaces a -clear error listing unexpected/missing keys instead of letting a malformed -file load silently. +Exports :data:`QWEN_SPEC`. diffusers registers a no-op identity lambda +for ``QwenImageTransformer2DModel`` in ``SINGLE_FILE_LOADABLE_CLASSES``, +so ``from_single_file`` silently accepts whatever key naming the file +uses and loads with mismatched weights. The spec sets ``converter=None`` +explicitly to skip that no-op; validation then surfaces mismatches as +clear errors. A real converter can be plugged in here if a trainer +format that needs one is encountered. """ import diffusers diff --git a/test/test-anima-native-adapters.py b/test/test-anima-native-adapters.py index f017512e4..abbe25213 100644 --- a/test/test-anima-native-adapters.py +++ b/test/test-anima-native-adapters.py @@ -8,7 +8,7 @@ custom Qwen3-projection MLP), or ``lora_te_*`` (Qwen3 text encoder). Routing is parameterized in ``modules.lora.native_adapter`` via the ``network_prefix`` callable that ``pipelines.anima.anima_lora`` supplies. -Covers the eight families exposed through native_adapter's generics (LoRA, +Covers the families exposed through native_adapter's generics (LoRA, LoKR, LoHA, OFT, IA3, GLoRA, Norm, Full), focused on: - LoRA across all five recognized prefixes (BFL transformer / BFL llm_adapter / diff --git a/test/test-flux2-native-adapters.py b/test/test-flux2-native-adapters.py index f7bd043b0..196a95763 100644 --- a/test/test-flux2-native-adapters.py +++ b/test/test-flux2-native-adapters.py @@ -2,8 +2,8 @@ """ Offline unit tests for Flux2/Klein native adapter loaders. -Covers the nine native families (LoRA, LoKR, LoHA, OFT, BOFT, IA3, -GLoRA, Norm, Full) plus DoRA threading via the universal +Covers the native families (LoRA, LoKR, LoHA, OFT, BOFT, IA3, GLoRA, +Norm, Full) plus DoRA threading via the universal NetworkModule.finalize_updown hook, and ex_bias accumulation across stacked Norm adapters.