diff --git a/modules/modelSetup/StableDiffusionLoRASetup.py b/modules/modelSetup/StableDiffusionLoRASetup.py index e8a5322e9..7db23dd99 100644 --- a/modules/modelSetup/StableDiffusionLoRASetup.py +++ b/modules/modelSetup/StableDiffusionLoRASetup.py @@ -88,7 +88,11 @@ def setup_model( if model.lora_state_dict: if create_te: - model.text_encoder_lora.load_state_dict(model.lora_state_dict) + # strict=False: TE LoRA keys may be absent in backups created with + # a flat CLIPTextModel (transformers >=5.6) where the key-conversion + # table couldn't match the nested path. Missing keys are left at + # their default (zero) initialisation. + model.text_encoder_lora.load_state_dict(model.lora_state_dict, strict=False) model.unet_lora.load_state_dict(model.lora_state_dict) model.lora_state_dict = None diff --git a/scripts/util/import_util.py b/scripts/util/import_util.py index 150df4d8a..f08c7d462 100644 --- a/scripts/util/import_util.py +++ b/scripts/util/import_util.py @@ -1,9 +1,39 @@ +def _patch_clip_text_model(): + # transformers 5.6 flattened CLIPTextModel (removed the .text_model wrapper). + # diffusers 0.38+ was updated for the flat layout, so it accesses + # embeddings/encoder/final_layer_norm directly on the model. + # + # - transformers >=5.6 (flat): add text_model = self so old OneTrainer code works + # - transformers <=5.5 (nested): expose embeddings/encoder/final_layer_norm + # directly via _modules['text_model'] so diffusers 0.38 code works + try: + import transformers as _tr + _major, _minor = (int(x) for x in _tr.__version__.split('.')[:2]) + from transformers.models.clip.modeling_clip import CLIPTextModel + + if (_major, _minor) >= (5, 6): + # flat layout — text_model no longer exists; point it back to self + if not hasattr(CLIPTextModel, 'text_model'): + CLIPTextModel.text_model = property(lambda self: self) + else: + # nested layout — diffusers 0.38 tries to access flat attr names + def _nested(attr): + return property(lambda self: getattr(self._modules['text_model'], attr)) + for _attr in ('embeddings', 'encoder', 'final_layer_norm'): + if not hasattr(CLIPTextModel, _attr): + setattr(CLIPTextModel, _attr, _nested(_attr)) + except Exception: + pass + + def script_imports(allow_zluda: bool = True): import logging import os import sys from pathlib import Path + _patch_clip_text_model() + # Filter out the Triton warning on startup. # xformers is not installed anymore, but might still exist for some installations. logging \