diff --git a/CHANGELOG.md b/CHANGELOG.md index b0871fec3..5000743af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,9 +19,14 @@ - **Process** - create videos from batch or folder processing supports GIF, PNG and MP4 with full interpolation, scene change detection, etc. + - **LoRA** + - add support for block weights, thanks @AI-Casanova + example `` + - reintroduce alternative loading method in settings: `lora_force_diffusers` + - add support for `lora_fuse_diffusers` if using alternative method + use if you have multiple complex loras that may be causing performance degradation + as it fuses lora with model during load instead of interpreting lora on-the-fly - **General** - - **LoRA** add support for block weights, thanks @AI-Casanova - example `` - **Extra networks** new *settting -> extra networks -> build info on first access* indexes all networks on first access instead of server startup - **Ipex** improvements, thanks @disty0 diff --git a/extensions-builtin/Lora/extra_networks_lora.py b/extensions-builtin/Lora/extra_networks_lora.py index a5d9e1726..5ef27e0fc 100644 --- a/extensions-builtin/Lora/extra_networks_lora.py +++ b/extensions-builtin/Lora/extra_networks_lora.py @@ -69,6 +69,8 @@ class ExtraNetworkLora(extra_networks.ExtraNetwork): def deactivate(self, p): if shared.backend == shared.Backend.DIFFUSERS and hasattr(shared.sd_model, "unload_lora_weights") and hasattr(shared.sd_model, "text_encoder"): if 'CLIP' in shared.sd_model.text_encoder.__class__.__name__ and not (shared.opts.cuda_compile and shared.opts.cuda_compile_backend == "openvino_fx"): + if shared.opts.lora_fuse_diffusers: + shared.sd_model.unfuse_lora() shared.sd_model.unload_lora_weights() if not self.active and getattr(networks, "originals", None ) is not None: networks.originals.undo() # remove patches diff --git a/extensions-builtin/Lora/lora_patches.py b/extensions-builtin/Lora/lora_patches.py index 983d80240..9ea6a10c3 100644 --- a/extensions-builtin/Lora/lora_patches.py +++ b/extensions-builtin/Lora/lora_patches.py @@ -1,10 +1,7 @@ -import os import torch import networks from modules import patches, shared -# OpenVINO only works with Diffusers LoRa loading -force_lora_diffusers = os.environ.get('SD_LORA_DIFFUSERS', None) is not None class LoraPatches: def __init__(self): @@ -21,7 +18,7 @@ class LoraPatches: self.MultiheadAttention_load_state_dict = None def apply(self): - if self.active or force_lora_diffusers: + if self.active or shared.opts.lora_force_diffusers: return self.Linear_forward = patches.patch(__name__, torch.nn.Linear, 'forward', networks.network_Linear_forward) self.Linear_load_state_dict = patches.patch(__name__, torch.nn.Linear, '_load_from_state_dict', networks.network_Linear_load_state_dict) @@ -39,7 +36,7 @@ class LoraPatches: self.active = True def undo(self): - if not self.active or force_lora_diffusers: + if not self.active or shared.opts.lora_force_diffusers: return self.Linear_forward = patches.undo(__name__, torch.nn.Linear, 'forward') # pylint: disable=E1128 self.Linear_load_state_dict = patches.undo(__name__, torch.nn.Linear, '_load_from_state_dict') # pylint: disable=E1128 diff --git a/extensions-builtin/Lora/networks.py b/extensions-builtin/Lora/networks.py index 05e36e8db..8c2d11b5b 100644 --- a/extensions-builtin/Lora/networks.py +++ b/extensions-builtin/Lora/networks.py @@ -39,7 +39,6 @@ module_types = [ network_norm.ModuleTypeNorm(), ] convert_diffusers_name_to_compvis = lora_convert.convert_diffusers_name_to_compvis # supermerger compatibility item -force_lora_diffusers = os.environ.get('SD_LORA_DIFFUSERS', None) is not None # OpenVINO only works with Diffusers LoRa loading def assign_network_names_to_compvis_modules(sd_model): @@ -79,13 +78,13 @@ def load_diffusers(name, network_on_disk, lora_scale=1.0): t0 = time.time() cached = lora_cache.get(name, None) # if debug: - shared.log.debug(f'LoRA load: name={name} file={network_on_disk.filename} type=diffusers {"cached" if cached else ""}') + shared.log.debug(f'LoRA load: name={name} file={network_on_disk.filename} type=diffusers {"cached" if cached else ""} fuse={shared.opts.lora_fuse_diffusers}') if cached is not None: return cached if shared.backend != shared.Backend.DIFFUSERS: return None shared.sd_model.load_lora_weights(network_on_disk.filename) - if shared.opts.cuda_compile and shared.opts.cuda_compile_backend == "openvino_fx": + if (shared.opts.cuda_compile and shared.opts.cuda_compile_backend == "openvino_fx") or shared.opts.lora_fuse_diffusers: shared.sd_model.fuse_lora(lora_scale=lora_scale) net = network.Network(name, network_on_disk) net.mtime = os.path.getmtime(network_on_disk.filename) @@ -171,7 +170,7 @@ def load_networks(names, te_multipliers=None, unet_multipliers=None, dyn_dims=No try: if recompile_model: shared.compiled_model_state.lora_model.append(f"{name}:{te_multipliers[i] if te_multipliers else 1.0}") - if shared.backend == shared.Backend.DIFFUSERS and force_lora_diffusers: # OpenVINO only works with Diffusers LoRa loading. + if shared.backend == shared.Backend.DIFFUSERS and shared.opts.lora_force_diffusers: # OpenVINO only works with Diffusers LoRa loading. # or getattr(network_on_disk, 'shorthash', '').lower() == 'aaebf6360f7d' # sd15-lcm # or getattr(network_on_disk, 'shorthash', '').lower() == '3d18b05e4f56' # sdxl-lcm # or getattr(network_on_disk, 'shorthash', '').lower() == '813ea5fb1c67' # turbo sdxl-turbo diff --git a/modules/patches.py b/modules/patches.py index a6c3a25bb..cff6bfd64 100644 --- a/modules/patches.py +++ b/modules/patches.py @@ -50,6 +50,7 @@ def undo(key, obj, field): original_func = originals[key].pop(patch_key) setattr(obj, field, original_func) + return None def original(key, obj, field): diff --git a/modules/shared.py b/modules/shared.py index 6569ab443..e75a66c17 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -607,6 +607,8 @@ options_templates.update(options_section(('extra_networks', "Extra Networks"), { "extra_networks_styles": OptionInfo(True, "Show built-in styles"), "lora_preferred_name": OptionInfo("filename", "LoRA preffered name", gr.Radio, {"choices": ["filename", "alias"]}), "lora_add_hashes_to_infotext": OptionInfo(True, "LoRA add hash info"), + "lora_force_diffusers": OptionInfo(False if not cmd_opts.use_openvino else True, "LoRA use alternative loading method"), + "lora_fuse_diffusers": OptionInfo(False, "LoRA use merge when using alternative method"), "lora_in_memory_limit": OptionInfo(0, "LoRA memory cache", gr.Slider, {"minimum": 0, "maximum": 24, "step": 1}), "lora_functional": OptionInfo(False, "Use Kohya method for handling multiple LoRA", gr.Checkbox, { "visible": False }), "sd_hypernetwork": OptionInfo("None", "Add hypernetwork to prompt", gr.Dropdown, { "choices": ["None"], "visible": False }),