mirror of
https://github.com/vladmandic/automatic
synced 2026-09-20 01:31:13 +02:00
feat(pipelines): wire native_spec for Qwen-Image and custom-class arches
Qwen-Image: diffusers registers a no-op identity lambda for QwenImageTransformer2DModel; from_single_file silently accepted any key naming and loaded with mismatches. QWEN_SPEC sets converter=None to short-circuit the no-op. Custom transformer classes (Lens, Step1X-Edit, VIBE Sana, f-lite): runtime-registered onto diffusers, never in SINGLE_FILE_LOADABLE_CLASSES. Specs land in each arch's existing pipelines/<arch>/__init__.py. NextStep skipped: loader returns None up front.
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
from pipelines.native_transformer import TransformerSpec
|
||||
from .pipeline import FLitePipeline, FLitePipelineOutput, APGConfig
|
||||
from .model import DiT
|
||||
|
||||
|
||||
__all__ = ["APGConfig", "DiT", "FLitePipeline", "FLitePipelineOutput"]
|
||||
FLITE_SPEC = TransformerSpec(cls=DiT, subfolder='dit_model')
|
||||
|
||||
|
||||
__all__ = ["APGConfig", "DiT", "FLITE_SPEC", "FLitePipeline", "FLitePipelineOutput"]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import diffusers as _diffusers
|
||||
import transformers as _transformers
|
||||
from pipelines.native_transformer import TransformerSpec
|
||||
from .pipeline import LensPipeline, LensPipelineOutput
|
||||
from .pipeline_image import LensImg2ImgPipeline, LensInpaintPipeline
|
||||
from .reasoner import PromptReasoner
|
||||
@@ -9,6 +10,9 @@ from .resolution import RESOLUTION_BUCKETS, resolve_resolution
|
||||
from .text_encoder import LensGptOssEncoder
|
||||
from .transformer import LensTransformer2DModel
|
||||
|
||||
|
||||
LENS_SPEC = TransformerSpec(cls=LensTransformer2DModel)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Make our custom subclasses discoverable by ``diffusers.DiffusionPipeline``.
|
||||
#
|
||||
@@ -38,6 +42,7 @@ if not hasattr(_diffusers, "LensInpaintPipeline"):
|
||||
del _diffusers, _transformers
|
||||
|
||||
__all__ = [
|
||||
"LENS_SPEC",
|
||||
"LensPipeline",
|
||||
"LensPipelineOutput",
|
||||
"LensImg2ImgPipeline",
|
||||
|
||||
@@ -19,7 +19,7 @@ def load_flite(checkpoint_info, diffusers_load_config=None):
|
||||
diffusers.FLitePipeline = f_lite.FLitePipeline
|
||||
sys.modules['f_lite'] = f_lite
|
||||
|
||||
dit_model = generic.load_transformer(repo_id, cls_name=f_lite.DiT, load_config=diffusers_load_config, subfolder="dit_model")
|
||||
dit_model = generic.load_transformer(repo_id, cls_name=f_lite.DiT, load_config=diffusers_load_config, subfolder="dit_model", native_spec=f_lite.FLITE_SPEC)
|
||||
text_encoder = generic.load_text_encoder(repo_id, cls_name=transformers.T5EncoderModel, load_config=diffusers_load_config, subfolder="text_encoder")
|
||||
|
||||
pipe = f_lite.FLitePipeline.from_pretrained(
|
||||
|
||||
@@ -15,7 +15,7 @@ def load_lens(checkpoint_info, diffusers_load_config=None):
|
||||
load_args, _quant_args = model_quant.get_dit_args(diffusers_load_config, allow_quant=False)
|
||||
log.debug(f'Load model: type=Lens repo="{repo_id}" config={diffusers_load_config} offload={shared.opts.diffusers_offload_mode} dtype={devices.dtype} reasoner={shared.opts.model_lens_enable_pe} args={load_args}')
|
||||
|
||||
transformer = generic.load_transformer(repo_id, cls_name=lens.LensTransformer2DModel, load_config=diffusers_load_config)
|
||||
transformer = generic.load_transformer(repo_id, cls_name=lens.LensTransformer2DModel, load_config=diffusers_load_config, native_spec=lens.LENS_SPEC)
|
||||
text_encoder = generic.load_text_encoder(repo_id, cls_name=lens.LensGptOssEncoder, load_config=diffusers_load_config, allow_quant=False)
|
||||
|
||||
pipe = lens.LensPipeline.from_pretrained(
|
||||
|
||||
@@ -57,12 +57,14 @@ def load_qwen(checkpoint_info, diffusers_load_config=None):
|
||||
transformer_subfolder = "transformer"
|
||||
|
||||
if transformer is None:
|
||||
from pipelines.qwen import QWEN_SPEC
|
||||
transformer = generic.load_transformer(
|
||||
repo_transformer,
|
||||
subfolder=transformer_subfolder,
|
||||
cls_name=diffusers.QwenImageTransformer2DModel,
|
||||
load_config=diffusers_load_config,
|
||||
modules_to_not_convert=["transformer_blocks.0.img_mod.1.weight"],
|
||||
native_spec=QWEN_SPEC,
|
||||
)
|
||||
|
||||
repo_te = 'Qwen/Qwen-Image'
|
||||
|
||||
@@ -22,7 +22,8 @@ def load_step1x_edit(checkpoint_info, diffusers_load_config=None):
|
||||
|
||||
text_encoder = generic.load_text_encoder(repo_id, cls_name=transformers.Qwen2_5_VLForConditionalGeneration, load_config=diffusers_load_config)
|
||||
processor = transformers.Qwen2_5_VLProcessor.from_pretrained(repo_id, cache_dir=shared.opts.hfcache_dir, subfolder='processor')
|
||||
transformer = generic.load_transformer(repo_id, cls_name=Step1XEditTransformer2DModel, load_config=diffusers_load_config)
|
||||
from pipelines.step1x import STEP1X_SPEC
|
||||
transformer = generic.load_transformer(repo_id, cls_name=Step1XEditTransformer2DModel, load_config=diffusers_load_config, native_spec=STEP1X_SPEC)
|
||||
|
||||
pipe = Step1XEditPipeline.from_pretrained(
|
||||
repo_id,
|
||||
|
||||
@@ -21,11 +21,13 @@ def load_vibe(checkpoint_info, diffusers_load_config=None):
|
||||
|
||||
sys.modules['vibe.transformer.vibe_sana_editing'] = diffusers # monkey patch since hf model_index.json points to custom class path
|
||||
|
||||
from pipelines.vibe import VIBE_SPEC
|
||||
transformer = generic.load_transformer(
|
||||
repo_id,
|
||||
cls_name=VIBESanaEditingModel,
|
||||
load_config=diffusers_load_config,
|
||||
allow_quant=False,
|
||||
native_spec=VIBE_SPEC,
|
||||
)
|
||||
text_encoder = generic.load_text_encoder(
|
||||
repo_id,
|
||||
|
||||
@@ -1,2 +1,24 @@
|
||||
"""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.
|
||||
"""
|
||||
|
||||
import diffusers
|
||||
|
||||
from pipelines.native_transformer import TransformerSpec
|
||||
from pipelines.qwen.qwen_nunchaku import load_qwen_nunchaku
|
||||
from pipelines.qwen.qwen_pruning import check_qwen_pruning
|
||||
|
||||
|
||||
QWEN_SPEC = TransformerSpec(cls=diffusers.QwenImageTransformer2DModel, converter=None)
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
from pipelines.native_transformer import TransformerSpec
|
||||
from pipelines.step1x.pipeline_output import Step1XEditPipelineOutput
|
||||
from pipelines.step1x.pipeline_step1x_edit import Step1XEditPipeline
|
||||
from pipelines.step1x.transformer_step1x_edit import Step1XEditTransformer2DModel
|
||||
|
||||
|
||||
STEP1X_SPEC = TransformerSpec(cls=Step1XEditTransformer2DModel)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"STEP1X_SPEC",
|
||||
"Step1XEditPipeline",
|
||||
"Step1XEditPipelineOutput",
|
||||
"Step1XEditTransformer2DModel",
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
"""VIBE pipeline components for SD.Next."""
|
||||
|
||||
from pipelines.native_transformer import TransformerSpec
|
||||
from .vibe_sana_editing import VIBESanaEditingModel
|
||||
from .vibe_sana_pipeline import VIBESanaEditingPipeline, VIBESanaImagePipeline
|
||||
|
||||
__all__ = ["VIBESanaEditingModel", "VIBESanaEditingPipeline", "VIBESanaImagePipeline"]
|
||||
|
||||
VIBE_SPEC = TransformerSpec(cls=VIBESanaEditingModel)
|
||||
|
||||
|
||||
__all__ = ["VIBE_SPEC", "VIBESanaEditingModel", "VIBESanaEditingPipeline", "VIBESanaImagePipeline"]
|
||||
|
||||
Reference in New Issue
Block a user