Skip to content

Latest commit

 

History

History

t2i-adapter

T2I-Adapter

T2I-Adapter 是一种通过添加额外条件来控制扩散模型的神经网络结构。它通过将T2I(Text2Image)模型的内部知识与外部控制信号进行对齐,并依据不同的条件来训练多种适配器(Adapter),可以实现丰富和精细的控制及编辑能力。

安装依赖

在运行这部分代码前,我们需要安装develop分支的ppdiffusers库:

cd ppdiffusers
python setup.py install

此外我们还需要安装相关依赖:

pip install -r requirements.txt

训练与推理

Adapter模型训练

下面我们将以pose2image任务(即姿态控制)为例,介绍如何训练相应的Adapter模型。

数据准备

请自行按照adapter/data_preprocess.py的数据处理逻辑准备好数据,并且将文件放置于/data目录,数据中需包含原图像、控制文本、控制图像等信息。

Tips: 我们可以选择下载demo数据并替换掉/data目录

  • 下载demo数据wget https://paddlenlp.bj.bcebos.com/models/community/westfish/t2i-adapter/openpose_data_demo.tar.gz,然后解压该数据tar -zxvf openpose_data_demo.tar.gz

单机单卡训练

export FLAGS_conv_workspace_size_limit=4096
python -u train_t2i_adapter_trainer.py \
    --do_train \
    --output_dir ./sd15_openpose \
    --per_device_train_batch_size 4 \
    --gradient_accumulation_steps 1 \
    --learning_rate 1e-5 \
    --weight_decay 0.02 \
    --lr_scheduler_type "constant" \
    --warmup_steps 0 \
    --max_steps 50000 \
    --logging_steps 1 \
    --image_logging_steps 500 \
    --save_steps 50 \
    --save_total_limit 1000 \
    --seed 4096 \
    --dataloader_num_workers 0 \
    --pretrained_model_name_or_path runwayml/stable-diffusion-v1-5 \
    --max_grad_norm -1 \
    --file_list ./data/train.openpose.filelist \
    --recompute False --use_ema False \
    --control_type raw \
    --data_format img2img \
    --use_paddle_conv_init False \
    --overwrite_output_dir \
    --timestep_sample_schedule cubic

train_t2i_adapter_trainer.py关键传入的参数解释如下:

  • --pretrained_model_name_or_path: 加载预训练SD模型的名称或本地路径,如runwayml/stable-diffusion-v1-5pretrained_model_name_or_path的优先级高于vae_name_or_path, text_encoder_name_or_pathunet_name_or_path
  • --per_device_train_batch_size: 训练时每张显卡所使用的batch_size批量,当我们的显存较小的时候,需要将这个值设置的小一点。
  • --gradient_accumulation_steps: 梯度累积的步数,用户可以指定梯度累积的步数,以期在梯度累积的step中减少多卡之间梯度的通信量,减少更新的次数,扩大训练的batch_size。
  • --learning_rate: 学习率。
  • --weight_decay: AdamW优化器的weight_decay
  • --max_steps: 最大的训练步数。
  • --save_steps: 每间隔多少步(global step步数),保存模型。
  • --save_total_limit: 最多保存多少个模型。
  • --lr_scheduler_type: 要使用的学习率调度策略。默认为 constant
  • --warmup_steps: 用于从 0 到 learning_rate 的线性 warmup 的步数。
  • --image_logging_steps: 每隔多少步,log训练过程中的图片,默认为1000步,注意image_logging_steps需要是logging_steps的整数倍。
  • --logging_steps: logging日志的步数,默认为50步。
  • --output_dir: 模型保存路径。
  • --seed: 随机种子,为了可以复现训练结果,Tips:当前paddle设置该随机种子后仍无法完美复现。
  • --dataloader_num_workers: Dataloader所使用的num_workers参数。
  • --file_path: 训练数据文件夹所在的地址,上述例子我们使用了fill50k目录。
  • --num_inference_steps: 推理预测时候使用的步数。
  • --model_max_length: tokenizer中的model_max_length参数,超过该长度将会被截断。
  • --tokenizer_name: 我们需要使用的tokenizer_name,我们可以使用英文的分词器bert-base-uncased,也可以使用中文的分词器ernie-1.0
  • --use_ema: 是否对unet使用ema,默认为False
  • --max_grad_norm: 梯度剪裁的最大norm值,-1表示不使用梯度裁剪策略。
  • --use_paddle_conv_init: 是否使用paddle的卷积初始化策略,默认值为 False,否则将采用Uniform卷积初始化策略。
  • --recompute: 是否开启重计算,(bool, 可选, 默认为 False),在开启后我们可以增大batch_size
  • --fp16: 是否使用 fp16 混合精度训练而不是 fp32 训练。(bool, 可选, 默认为 False)
  • --fp16_opt_level: 混合精度训练模式,可为O1O2模式,默认O1模式,默认O1. 只在fp16选项开启时候生效。
  • --is_ldmbert: 是否使用ldmbert作为text_encoder,默认为False,即使用 clip text_encoder
  • --overwrite_output_dir: 加入该参数之后,将覆盖之前的模型保存路径,不会自动恢复训练。
  • --pretrained_adapter_name_or_path: 加载预训练Adapter模型的名称或本地路径,默认为None,此时将随机初始化模型参数。
  • --timestep_sample_schedule: 训练期间时间步采样策略的类型,从[linear, cosine, cubic]中选择,默认为linear

单机多卡训练 (多机多卡训练,仅需在 paddle.distributed.launch 后加个 --ips IP1,IP2,IP3,IP4)

export FLAGS_conv_workspace_size_limit=4096
python -u -m paddle.distributed.launch --gpus "0,1,2,3,4,5,6,7" train_t2i_adapter_trainer.py \
    --do_train \
    --output_dir ./sd15_openpose \
    --per_device_train_batch_size 4 \
    --gradient_accumulation_steps 1 \
    --learning_rate 1e-5 \
    --weight_decay 0.02 \
    --lr_scheduler_type "constant" \
    --warmup_steps 0 \
    --max_steps 50000 \
    --logging_steps 1 \
    --image_logging_steps 500 \
    --save_steps 50 \
    --save_total_limit 1000 \
    --seed 4096 \
    --dataloader_num_workers 0 \
    --pretrained_model_name_or_path runwayml/stable-diffusion-v1-5 \
    --max_grad_norm -1 \
    --file_list ./data/train.openpose.filelist \
    --recompute False --use_ema False \
    --control_type raw \
    --data_format img2img \
    --use_paddle_conv_init False \
    --overwrite_output_dir

模型推理

简易推理

待模型训练完毕,会在output_dir保存训练好的模型权重,我们可以使用如下的代码进行推理。

from ppdiffusers import StableDiffusionAdapterPipeline, T2IAdapter
from ppdiffusers.utils import load_image
adapter = T2IAdapter.from_pretrained("./sd15_openpose/checkpoint-12000/adapter")
pipe = StableDiffusionAdapterPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", adapter = adapter, safety_checker=None)
pose_image = load_image("https://paddlenlp.bj.bcebos.com/models/community/westfish/t2i-adapter/test/man-openpose.png")
img = pipe(prompt="a beautiful girl", image=pose_image, guidance_scale=9, num_inference_steps=50).images[0]
img.save("demo.png")

测试集推理

我们可以使用如下命令针对相应的测试集(需符合adapter/data_preprocess.py的数据处理逻辑)进行测试。

python generate.py \
    --adapter_model_name_or_path westfish/sd-v1-4-adapter-openpose \
    --sd_model_name_or_path lllyasviel/sd-controlnet-openpose \
    --save_path your/output/path \
    --num_inference_steps 50 \
    --scheduler_type ddim \
    --height=512 \
    --width=512 \
    --device gpu \
    --max_generation_limits 1000 \
    --use_text_cond True \
    --generate_control_image_processor_type openpose \
    --file data/test.openpose.filelist \
    --generate_data_format img2img \

generate.py关键传入的参数解释如下:

  • --use_controlnet: 是否采用ControlNet来进行条件控制,默认为False,即默认使用Adapter来进行条件控制。
  • --adapter_model_name_or_path: Adapter采用的的的模型名称或地址。
  • --sd_model_name_or_path: Stable Diffusion采用的的的模型名称或地址。
  • --file: 需要测试的数据。
  • --batch_size: 生成图片所使用的batch_size。
  • --save_path: 生成的图片所要保存的路径。
  • --guidance_scales: guidance_scales值,默认为[3 5 7]。
  • --num_inference_steps: 推理预测时候使用的步数。
  • --scheduler_type: 采样器的类型,支持ddim, pndm, euler-ancestlms
  • --height: 生成图片的高,默认为512。
  • --width: 生成图片的宽,默认为512。
  • --seed: 随机种子。
  • --device: 使用的设备,可以是gpu, cpu, gpu:0, gpu:1等。
  • --max_generation_limits: 每次最多生成的个数。
  • --use_text_cond: 是否使用数据集中自带的文本提示词,默认为True
  • --use_default_neg_text_cond: 是否使用默认的负提示词,默认为True
  • --generate_control_image_processor_type: 控制生成的类型,可选择cannyopenpose
  • --generate_data_format: 数据控制类型,当generate_control_image_processor_typecanny是设置为default,其他情况下设置为img2img