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
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user