Qwen-Image LoRA 模型加载失效?

引言

自己训练的 Qwen-Image LoRA 模型在推理时“不生效”——输出结果与原始基模型几乎一致,微调效果完全未体现。经过排查,发现一个高频但容易被忽视的问题:LoRA 权重字典中的键名(key)前缀与目标模型结构不匹配。


问题现象与根源

现象描述

使用 AI-Toolkit(或其他训练框架)训练的 Qwen-Image LoRA 模型,在推理时无法体现训练数据特征;而从 ModelScope 社区下载的同类 LoRA 模型却能正常工作;对比两者 .safetensors 文件中的权重键名,发现存在前缀差异。

原因分析

LoRA 模型本质上是一组低秩增量权重(如 lora_A、lora_B),其键名必须与目标模型中被替换模块的完整路径完全一致,才能被正确注入。


解决方案:键名前缀转换脚本

脚本 1:检查 LoRA 键名(inspect_lora.py)

# inspect_lora.py
import os
import torch
import safetensors.torch

def print_keys(lora_file):
    try:
        if lora_file.endswith(".safetensors"):
            lora_data = safetensors.torch.load_file(lora_file, device="cpu")
        else:
            lora_data = torch.load(lora_file, map_location="cpu")
    except Exception as e:
        print(f"读取失败: {e}")
        return

    # 打印 key 和 shape
    for k, v in lora_data.items():
        print(f"{k}  ->  {tuple(v.shape)}")

# 示例调用
if __name__ == "__main__":
    lora_file = "Kook_千问写实_Kook_Qwen_V2美人版.safetensors"  # 替换为实际的LoRA文件名
    print_keys(lora_file)

社区训练的Lora键值
在这里插入图片描述
自己训练AI-Toolkit训练的模型键值(有人说是放在ComfyUI中可以用,但是我自己训练的Lora上传到modelscope和liblibai中均不能用)
在这里插入图片描述

脚本 2:转换键名前缀(convert_lora.py)

# convert_lora.py
import os
import torch
import safetensors.torch

def convert_lora_keys(lora_file, output_file):
    try:
        if lora_file.endswith(".safetensors"):
            lora_data = safetensors.torch.load_file(lora_file, device="cpu")
        else:
            lora_data = torch.load(lora_file, map_location="cpu")
    except Exception as e:
        print(f"读取失败: {e}")
        return

    # 修改 key 名称
    converted_data = {}
    for k, v in lora_data.items():
        # 去掉键名中的 "diffusion_model." 前缀
        k = k.replace("diffusion_model.", "")
        # 将键名中的 ".weight" 替换为 ".default.weight"
        k = k.replace(".weight", ".default.weight")
        converted_data[k] = v

    # 保存修改后的数据到新的文件
    try:
        if output_file.endswith(".safetensors"):
            safetensors.torch.save_file(converted_data, output_file)
        else:
            torch.save(converted_data, output_file)
        print(f"修改后的 LoRA 文件已保存到: {output_file}")
    except Exception as e:
        print(f"保存失败: {e}")

# 遍历当前目录下的所有 .safetensors 文件并转换
if __name__ == "__main__":
    # 获取当前目录下的所有文件
    files = os.listdir(".")
    for file in files:
        if file.endswith(".safetensors"):
            input_lora_file = file
            output_lora_file = file.replace(".safetensors", "_converted.safetensors")
            convert_lora_keys(input_lora_file, output_lora_file)

转换后Lora键值
在这里插入图片描述

分析总结
    # 去掉键名中的 "diffusion_model." 前缀
    k = k.replace("diffusion_model.", "")
    # 将键名中的 ".weight" 替换为 ".default.weight"
    k = k.replace(".weight", ".default.weight")

不知道具体是不是这个原因、但确实靠谱可用

✅ 转换后,上传modelscope、liblibai 加载,即可正常生效。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐