Skip to content

T2I-Adapter

T2I-Adapter 是一个轻量级的适配器模型,它提供了一个额外的条件输入图像(线稿、canny、草图、深度、姿态)来更好地控制图像生成。它类似于一个 ControlNet,但它的体积要小得多(约77M参数和约300MB文件大小),因为它只在 UNet 中插入权重,而不是复制和训练整个模型。

T2I-Adapter 仅适用于与 Stable Diffusion XL (SDXL) 模型一起训练。

本指南将探讨 train_t2i_adapter_sdxl.py 训练脚本,帮助你熟悉它,以及如何根据你的用例进行调整。

在运行脚本之前,请确保从源代码安装库:

bash
git clone https://github.com/huggingface/diffusers
cd diffusers
pip install .

然后导航到包含训练脚本的示例文件夹,并安装你使用的脚本所需的所有依赖项:

bash
cd examples/t2i_adapter
pip install -r requirements.txt

初始化一个 🤗 Accelerate 环境:

bash
accelerate config

要设置一个默认的 🤗 Accelerate 环境而不选择任何配置:

bash
accelerate config default

或者如果你的环境不支持交互式 shell,比如笔记本,你可以使用:

py
from accelerate.utils import write_basic_config

write_basic_config()

最后,如果你想在自己的数据集上训练模型,请查看创建训练数据集指南,学习如何创建与训练脚本兼容的数据集。

脚本参数

训练脚本提供了许多参数,帮助你自定义训练过程。所有参数及其描述都可以在parse_args()函数中找到。该函数为每个参数提供了默认值,例如训练批次大小和学习率,但你也可以在训练命令中设置自己的值。

例如,要激活梯度累积,请在训练命令中添加--gradient_accumulation_steps参数:

bash
accelerate launch train_t2i_adapter_sdxl.py \
  ----gradient_accumulation_steps=4

许多基本和重要的参数在文本到图像训练指南中有详细描述,因此本指南仅关注相关的T2I-Adapter参数:

  • --pretrained_vae_model_name_or_path:预训练VAE的路径;SDXL的VAE存在数值不稳定性问题,因此此参数允许你指定一个更好的VAE
  • --crops_coords_top_left_h--crops_coords_top_left_w:包含在SDXL裁剪坐标嵌入中的高度和宽度坐标
  • --conditioning_image_column:数据集中条件图像的列
  • --proportion_empty_prompts:替换为空字符串的图像提示的比例

训练脚本

与脚本参数一样,训练脚本的演练在文本到图像训练指南中提供。相反,本指南将查看脚本中与T2I-Adapter相关的部分。

训练脚本首先准备数据集。这包括标记化提示和应用变换到图像和条件图像。

py
conditioning_image_transforms = transforms.Compose(
    [
        transforms.Resize(args.resolution, interpolation=transforms.InterpolationMode.BILINEAR),
        transforms.CenterCrop(args.resolution),
        transforms.ToTensor(),
    ]
)

main()函数中,T2I-Adapter要么从预训练的适配器加载,要么随机初始化:

py
if args.adapter_model_name_or_path:
    logger.info("Loading existing adapter weights.")
    t2iadapter = T2IAdapter.from_pretrained(args.adapter_model_name_or_path)
else:
    logger.info("Initializing t2iadapter weights.")
    t2iadapter = T2IAdapter(
        in_channels=3,
        channels=(320, 640, 1280, 1280),
        num_res_blocks=2,
        downscale_factor=16,
        adapter_type="full_adapter_xl",
    )

优化器针对T2I-Adapter参数进行初始化:

py
params_to_optimize = t2iadapter.parameters()
optimizer = optimizer_class(
    params_to_optimize,
    lr=args.learning_rate,
    betas=(args.adam_beta1, args.adam_beta2),
    weight_decay=args.adam_weight_decay,
    eps=args.adam_epsilon,
)

最后,在训练循环中,适配器条件图像和文本嵌入被传递给UNet以预测噪声残差:

py
t2iadapter_image = batch["conditioning_pixel_values"].to(dtype=weight_dtype)
down_block_additional_residuals = t2iadapter(t2iadapter_image)
down_block_additional_residuals = [
    sample.to(dtype=weight_dtype) for sample in down_block_additional_residuals
]

model_pred = unet(
    inp_noisy_latents,
    timesteps,
    encoder_hidden_states=batch["prompt_ids"],
    added_cond_kwargs=batch["unet_added_conditions"],
    down_block_additional_residuals=down_block_additional_residuals,
).sample

如果你想了解更多关于训练循环的工作原理,请查看理解管道、模型和调度器教程,该教程分解了去噪过程的基本模式。

启动脚本

现在你已经准备好启动训练脚本了!🚀

在这个示例训练中,你将使用fusing/fill50k数据集。如果你愿意,也可以创建并使用自己的数据集(参见创建用于训练的数据集指南)。

将环境变量MODEL_DIR设置为Hub上的模型ID或本地模型的路径,并将OUTPUT_DIR设置为你希望保存模型的位置。

下载以下图像以条件化你的训练:

bash
wget https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/controlnet_training/conditioning_image_1.png
wget https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/controlnet_training/conditioning_image_2.png
bash
export MODEL_DIR="stabilityai/stable-diffusion-xl-base-1.0"
export OUTPUT_DIR="path to save model"

accelerate launch train_t2i_adapter_sdxl.py \
 --pretrained_model_name_or_path=$MODEL_DIR \
 --output_dir=$OUTPUT_DIR \
 --dataset_name=fusing/fill50k \
 --mixed_precision="fp16" \
 --resolution=1024 \
 --learning_rate=1e-5 \
 --max_train_steps=15000 \
 --validation_image "./conditioning_image_1.png" "./conditioning_image_2.png" \
 --validation_prompt "red circle with blue background" "cyan circle with brown floral background" \
 --validation_steps=100 \
 --train_batch_size=1 \
 --gradient_accumulation_steps=4 \
 --report_to="wandb" \
 --seed=42 \
 --push_to_hub

训练完成后,你可以使用你的 T2I-Adapter 进行推理:

py
from diffusers import StableDiffusionXLAdapterPipeline, T2IAdapter, EulerAncestralDiscreteSchedulerTest
from diffusers.utils import load_image
import torch

adapter = T2IAdapter.from_pretrained("path/to/adapter", torch_dtype=torch.float16)
pipeline = StableDiffusionXLAdapterPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", adapter=adapter, torch_dtype=torch.float16
)

pipeline.scheduler = EulerAncestralDiscreteSchedulerTest.from_config(pipe.scheduler.config)
pipeline.enable_xformers_memory_efficient_attention()
pipeline.enable_model_cpu_offload()

control_image = load_image("./conditioning_image_1.png")
prompt = "pale golden rod circle with old lace background"

generator = torch.manual_seed(0)
image = pipeline(
    prompt, image=control_image, generator=generator
).images[0]
image.save("./output.png")

下一步

恭喜你训练了一个 T2I-Adapter 模型!🎉 了解更多信息: