From 6123655ac20e094eef1122cbed77caf36bd530c8 Mon Sep 17 00:00:00 2001 From: CalamitousFelicitousness Date: Wed, 13 Aug 2025 23:39:18 +0100 Subject: [PATCH 1/3] LoRA load Torch tuple and string version checking Due to BitsandBytes trying to use tuple and comparison to check Torch version which is given as a string, using LoRA with a quantized model results in a TypeError. This commit adds support for both. --- modules/lora/lora_load.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/modules/lora/lora_load.py b/modules/lora/lora_load.py index 0ad032c15..d88f9b764 100644 --- a/modules/lora/lora_load.py +++ b/modules/lora/lora_load.py @@ -16,6 +16,24 @@ forbidden_network_aliases = {} available_network_hash_lookup = {} dump_lora_keys = os.environ.get('SD_LORA_DUMP', None) is not None +def patch_torch_version(): + import torch + if not hasattr(torch, '__version_backup__'): + torch.__version_backup__ = torch.__version__ + # Convert string version to tuple format to solve TypeError caused by BnB + version_parts = torch.__version__.split('+')[0].split('.') + torch.__version_tuple__ = tuple(int(x) for x in version_parts[:3]) + # Support both string and tuple + class VersionString(str): + def __ge__(self, other): + if isinstance(other, tuple): + self_tuple = tuple(int(x) for x in self.split('+')[0].split('.')[:len(other)]) + return self_tuple >= other + return super().__ge__(other) + torch.__version__ = VersionString(torch.__version__) + +# Call before loading LoRA +patch_torch_version() def load_diffusers(name, network_on_disk, lora_scale=shared.opts.extra_networks_default_multiplier) -> Union[network.Network, None]: t0 = time.time() From afe900537d2b7b19e102a00c9339c85c43ad5791 Mon Sep 17 00:00:00 2001 From: CalamitousFelicitousness Date: Thu, 14 Aug 2025 00:25:56 +0100 Subject: [PATCH 2/3] Revert lora_load.py commit --- modules/lora/lora_load.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/modules/lora/lora_load.py b/modules/lora/lora_load.py index d88f9b764..0ad032c15 100644 --- a/modules/lora/lora_load.py +++ b/modules/lora/lora_load.py @@ -16,24 +16,6 @@ forbidden_network_aliases = {} available_network_hash_lookup = {} dump_lora_keys = os.environ.get('SD_LORA_DUMP', None) is not None -def patch_torch_version(): - import torch - if not hasattr(torch, '__version_backup__'): - torch.__version_backup__ = torch.__version__ - # Convert string version to tuple format to solve TypeError caused by BnB - version_parts = torch.__version__.split('+')[0].split('.') - torch.__version_tuple__ = tuple(int(x) for x in version_parts[:3]) - # Support both string and tuple - class VersionString(str): - def __ge__(self, other): - if isinstance(other, tuple): - self_tuple = tuple(int(x) for x in self.split('+')[0].split('.')[:len(other)]) - return self_tuple >= other - return super().__ge__(other) - torch.__version__ = VersionString(torch.__version__) - -# Call before loading LoRA -patch_torch_version() def load_diffusers(name, network_on_disk, lora_scale=shared.opts.extra_networks_default_multiplier) -> Union[network.Network, None]: t0 = time.time() From 70672d3267e46500fdaa01edebc737a557cba8b0 Mon Sep 17 00:00:00 2001 From: CalamitousFelicitousness Date: Thu, 14 Aug 2025 00:31:10 +0100 Subject: [PATCH 3/3] Move tuple/string versioning fix for BnB to loader.py --- modules/loader.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/modules/loader.py b/modules/loader.py index 87f88872a..8b889f382 100644 --- a/modules/loader.py +++ b/modules/loader.py @@ -199,6 +199,24 @@ def deprecate_warn(*args, **kwargs): diffusers.utils.deprecation_utils.deprecate = deprecate_warn diffusers.utils.deprecate = deprecate_warn +def patch_torch_version(): + import torch + if not hasattr(torch, '__version_backup__'): + torch.__version_backup__ = torch.__version__ + # Convert string version to tuple format to solve TypeError caused by BnB + version_parts = torch.__version__.split('+')[0].split('.') + torch.__version_tuple__ = tuple(int(x) for x in version_parts[:3]) + # Support both string and tuple for version check + class VersionString(str): + def __ge__(self, other): + if isinstance(other, tuple): + self_tuple = tuple(int(x) for x in self.split('+')[0].split('.')[:len(other)]) + return self_tuple >= other + return super().__ge__(other) + torch.__version__ = VersionString(torch.__version__) + +patch_torch_version() + errors.log.info(f'Torch: torch=={torch.__version__} torchvision=={torchvision.__version__}') errors.log.info(f'Packages: diffusers=={diffusers.__version__} transformers=={transformers.__version__} accelerate=={accelerate.__version__} gradio=={gradio.__version__} pydantic=={pydantic.__version__} numpy=={np.__version__}')