From cffb92aa06b60a84fed6b1a04933920860904f42 Mon Sep 17 00:00:00 2001 From: silveroxides Date: Thu, 15 Jan 2026 02:43:42 +0100 Subject: [PATCH] fix: Add HuggingFace LoRA format support (.lora.down.weight/.lora.up.weight) - Add detection for HuggingFace format in detect_lora_format() - Strip trailing .lora suffix in extract_core_layer_lora() for proper key matching - Applied fix to resize_lora_via_base, merge_multi_loras_via_base, and merge_loras_to_model --- nodes/lora_resize.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/nodes/lora_resize.py b/nodes/lora_resize.py index 83c4615..b15c3ea 100644 --- a/nodes/lora_resize.py +++ b/nodes/lora_resize.py @@ -45,6 +45,7 @@ def detect_lora_format(keys: List[str]) -> Dict: - Diffusers: *.lora_A.weight, *.lora_B.weight - PEFT: base_model.model.*.lora_A/B - ComfyUI native: *.lora_down.weight, *.lora_up.weight + - HuggingFace: *.lora.down.weight, *.lora.up.weight (dots instead of underscores) - Full diff: *.diff, *.diff_b (full weight differences, not low-rank) - Flux/SDXL: Various transformer key patterns @@ -96,6 +97,13 @@ def detect_lora_format(keys: List[str]) -> Dict: format_info["down_suffix"] = ".lora_A.default.weight" format_info["up_suffix"] = ".lora_B.default.weight" + # HuggingFace format: transformer.*.lora.down.weight (dots instead of underscores) + elif any('.lora.down.weight' in k for k in sample_keys): + format_info["format"] = "huggingface" + format_info["down_suffix"] = ".lora.down.weight" + format_info["up_suffix"] = ".lora.up.weight" + format_info["alpha_suffix"] = ".alpha" + # ComfyUI native / standard elif any('.lora_down.weight' in k for k in sample_keys): format_info["format"] = "comfy" @@ -109,6 +117,7 @@ def detect_lora_format(keys: List[str]) -> Dict: return format_info + def extract_lora_pairs(keys: List[str], format_info: Dict) -> Dict[str, Dict[str, str]]: """ Group LoRA keys into down/up/alpha pairs. @@ -739,9 +748,13 @@ def resize_lora_via_base( if block_name.startswith(prefix): block_name = block_name[len(prefix):] break + # Strip trailing .lora suffix (HuggingFace format leaves this after suffix removal) + if block_name.endswith(".lora"): + block_name = block_name[:-5] # Convert dots to underscores (diffusers format uses dots) return block_name.replace(".", "_") + # Build lookup table: core layer name (underscored) -> original base key base_key_lookup = {} for bk in base_handler.keys(): @@ -1262,8 +1275,12 @@ def merge_multi_loras_via_base( if block_name.startswith(prefix): block_name = block_name[len(prefix):] break + # Strip trailing .lora suffix (HuggingFace format leaves this after suffix removal) + if block_name.endswith(".lora"): + block_name = block_name[:-5] return block_name.replace(".", "_") + # Build base key lookup base_key_lookup = {} for bk in base_handler.keys(): @@ -1657,8 +1674,12 @@ def merge_loras_to_model( if result.startswith(prefix): result = result[len(prefix):] break + # Strip trailing .lora suffix (HuggingFace format leaves this after suffix removal) + if result.endswith(".lora"): + result = result[:-5] return result.replace(".", "_") + # Build LoRA lookup: core layer name (underscored) -> list of (info, block_keys) lora_lookup = {} for info in lora_infos: