ERNIE-Image Diffusers LoRA 训练与加载完全指南:从报错到 ComfyUI 部署

Jun 13, 2026

ERNIE-Image Diffusers LoRA 训练与加载完全指南:从报错到 ComfyUI 部署

摘要:ERNIE-Image 在 Diffusers 生态中最大的痛点是 ErnieImagePipeline 不支持 load_lora_weights() 方法。本文从 GitHub #13501 报错复现开始,深入分析 DiT 架构与标准 UNet 的 LoRA 注入差异,提供 AI Toolkit 训练全流程、PEFT 手动注入方案、ComfyUI 加载链路,以及完整的生产级 LoRA 训练部署方案。无论你是想训练角色一致性 LoRA 还是风格定制 LoRA,本文都能帮你打通从训练到部署的最后一公里。


从报错开始:为什么 Diffusers 加载 LoRA 失败?

如果你尝试过在 Diffusers 中加载 ERNIE-Image LoRA,一定会遇到这个报错:

from diffusers import ErnieImagePipeline

pipe = ErnieImagePipeline.from_pretrained("baidu/ERNIE-Image")
pipe.load_lora_weights("path/to/lora.safetensors") # ❌ 报错!

错误信息:

AttributeError: 'ErnieImagePipeline' object has no attribute 'load_lora_weights'

这个报错来自 GitHub diffusers #13501,是社区最常被问到的 ERNIE-Image 问题。

根因分析:DiT 单流架构 vs 标准 UNet

LoRA(Low-Rank Adaptation)的核心思路是将全量参数更新 ΔW 近似为两个低秩矩阵的乘积 ΔW ≈ BA。对于不同架构,LoRA 需要注入到不同层:

架构 LoRA 注入位置 Diffusers 支持
UNet (SDXL) cross_attn + self_attn ✅ 原生支持
MMDiT (FLUX.1) context_attn + img_attn ✅ 原生支持
DiT 单流 (ERNIE-Image) single_transformer_blocks.attn ❌ 尚未实现

ERNIE-Image 采用**单流 DiT(Diffusion Transformer)**架构,与 FLUX 的双流 MMDiT 和 SDXL 的 UNet 都不同。Diffusers 的 load_lora_weights() 基于 UNet 命名空间设计,而 ERNIE-Image 的权重命名空间为:

transformer.single_transformer_blocks.0.attn.to_q.lora_A.weight
transformer.single_transformer_blocks.0.attn.to_k.lora_B.weight

这就是标准 API 调用失败的原因。


方案一:AI Toolkit 训练 + ComfyUI 加载(推荐)

目前最成熟的方案:使用 AI Toolkit 训练 LoRA,通过 ComfyUI 加载。AI Toolkit 是 Day-0 支持 ERNIE-Image 的训练方案。

安装 AI Toolkit

git clone https://github.com/ostris/ai-toolkit.git
cd ai-toolkit
pip install -r requirements.txt

准备数据集

AI Toolkit 支持标准数据集格式:

dataset/
├── 001.jpg    # 图片
├── 002.jpg
├── 003.jpg
└── captions.txt  # 每行对应一张图的提示词

关键配置 (config.yaml):

model: ernie-image
output_dir: ./lora_output
rank: 16            # LoRA 秩,推荐 8-32
alpha: 16           # 缩放因子,通常等于 rank
target_modules:
  - "attn.to_q"
  - "attn.to_k"
  - "attn.to_v"
  - "attn.to_out.0"
learning_rate: 1e-4
num_epochs: 20
batch_size: 1

训练命令

python train.py --config config.yaml --dataset dataset/

训练完成后,输出 lora.safetensors。

ComfyUI 加载 LoRA

ComfyUI 原生支持 ERNIE-Image LoRA:

[Load Checkpoint (ernie-image.safetensors)]
       ↓
[LoraLoader (lora.safetensors, strength=0.8)]
       ↓
[CLIP Text Encode]
       ↓
[KSampler] → [VAE Decode] → [Save Image]

关键参数:

  • strength:LoRA 强度,通常 0.6-1.0
  • 过高可能导致图像失真

方案二:PEFT 手动注入到 Diffusers(高级)

如果你坚持使用 Diffusers Pipeline,可以通过 PEFT 库手动注入 LoRA:

import torch
from diffusers import ErnieImagePipeline
from peft import LoraConfig, get_peft_model

1. 加载基础模型

pipe = ErnieImagePipeline.from_pretrained("baidu/ERNIE-Image")

2. 配置 LoRA

lora_config = LoraConfig(
r=16,
lora_alpha=16,
target_modules=["to_q", "to_k", "to_v", "to_out.0"],
lora_dropout=0.0,
)

3. 注入到 DiT 模型

dit_model = pipe.transformer # ERNIE-Image 用 transformer 而非 unet
peft_model = get_peft_model(dit_model, lora_config)

4. 加载预训练 LoRA 权重

lora_state_dict = torch.load("path/to/lora.pt", map_location="cpu")
peft_model.load_state_dict(lora_state_dict, strict=False)

5. 生成图像(LoRA 已生效)

image = pipe(
prompt="a photorealistic portrait",
num_inference_steps=50,
guidance_scale=7.0,
).images[0]

注意:

  • 权重键名需与训练时一致(single_transformer_blocks 命名空间)
  • safetensors 格式使用 safetensors.torch.load_file()
  • 此方法绕过了 diffusers 标准 API,不保证向后兼容

方案三:从 safetensors 手动加载

from safetensors.torch import load_file

lora_weights = load_file("lora.safetensors")

for key, value in lora_weights.items():
if "lora_A" in key or "lora_B" in key:
# 解析目标模块路径并注入
# 例如: "transformer.single_transformer_blocks.0.attn.to_q.lora_A.weight"
pass

提示:想快速验证 LoRA 效果?直接使用 ComfyUI 的 LoraLoader 节点。


LoRA 训练最佳实践

数据集选择

目标 图片数 训练轮数 推荐 Rank
角色一致性 15-30 20-30 16
风格迁移 20-50 15-25 32
概念注入 10-20 25-40 8-16

提示词编写原则

  1. 一致性前缀:所有图片用相同标识符,如 a photo of [V] character
  2. 描述性后缀:每张图片补充场景描述
  3. 避免过拟合:不要在所有提示词中重复相同修饰词

训练参数调优

learning_rate: 1e-4        # 太高容易过拟合
num_epochs: 20             # 角色 LoRA 一般 20 轮足够
rank: 16                   # 太小无法捕获细节,太大容易过拟合
alpha: 16                  # 通常等于 rank

常见问题排查

Q1: ComfyUI 报 "lora key not loaded"

lora key not loaded: transformer.single_transformer_blocks.0.attn.to_k.lora_A.weight

原因:LoRA 在不同架构(如 FLUX)上训练,命名空间不兼容。

解决:使用 AI Toolkit 训练 ERNIE-Image 专用 LoRA,不要混用 FLUX/SDXL LoRA。

Q2: 加载 LoRA 后图像质量下降

原因:strength 设置过高。

解决:从 0.5 开始逐步调高,通常 0.6-0.8 最佳。

Q3: PEFT 注入后无效果

原因:权重键名与实际层名不匹配。

解决:打印 pipe.transformer.state_dict().keys() 确认命名空间。


与其他模型的 LoRA 生态对比

模型 Diffusers 原生 LoRA AI Toolkit ComfyUI 生态成熟度
SDXL ✅ ✅ ✅ ⭐⭐⭐⭐⭐
FLUX.1 ✅ ✅ ✅ ⭐⭐⭐⭐
ERNIE-Image ❌ ✅ ✅ ⭐⭐⭐

ERNIE-Image 的 LoRA 生态正在快速成长。AI Toolkit + ComfyUI 已覆盖大部分场景,等待 Diffusers 官方实现 load_lora_weights() 后会更完善。


总结

ERNIE-Image 的 DiT 单流架构使其 LoRA 加载路径与标准 Diffusers Pipeline 不同,但通过 AI Toolkit 训练 + ComfyUI 加载的方案,可以完成从训练到部署的完整流程。

核心推荐:

  1. 训练:AI Toolkit(Day-0 ERNIE-Image 支持,输出 safetensors)
  2. 加载:首选 ComfyUI LoraLoader 节点
  3. 高级用户:PEFT 手动注入到 Diffusers
  4. 数据集:15-30 张图片即可训练出良好效果

未来展望:Diffusers 官方正在推进 ERNIE-Image LoRA 支持(#13501),届时将实现标准 API 调用。


关键词: ernie-image diffusers lora ernie-image lora training ernie-image ai toolkit ernie-image load_lora_weights ernie-image comfyui lora ernie-image DiT lora ernie-image lora safetensors

ERNIE-Image Team