@@ -36,70 +36,58 @@ python -u train_dreambooth.py \
36
36
--instance_data_dir=$INSTANCE_DIR \
37
37
--output_dir=$OUTPUT_DIR \
38
38
--instance_prompt=" a photo of sks dog" \
39
- --height=512 \
40
- --width=512 \
39
+ --resolution=512 \
41
40
--train_batch_size=1 \
42
41
--gradient_accumulation_steps=1 \
43
42
--learning_rate=5e-6 \
44
43
--lr_scheduler=" constant" \
45
44
--lr_warmup_steps=0 \
46
45
--max_train_steps=400
47
46
```
48
- 或
49
- ``` bash
50
- bash run_single.sh
51
- ```
52
- | ppdiffusers支持的模型名称 | huggingface对应的模型地址 | Tips备注 |
53
- | ---------------------------------------- | ---------------------------------------------------------- | -------------------------------------------------------------- |
54
- | CompVis/stable-diffusion-v1-4 | https://huggingface.co/CompVis/stable-diffusion-v1-4 | 原版SD模型,模型使用PNDM scheduler。 |
55
- | hakurei/waifu-diffusion | https://huggingface.co/hakurei/waifu-diffusion | Waifu v1-2的模型,模型使用了DDIM scheduler。 |
56
- | hakurei/waifu-diffusion-v1-3 | https://huggingface.co/hakurei/waifu-diffusion | Waifu v1-3的模型,模型使用了PNDM scheduler。 |
57
- | naclbit/trinart_stable_diffusion_v2_60k | https://huggingface.co/naclbit/trinart_stable_diffusion_v2 | trinart 经过60k步数训练得到的模型,模型使用了DDIM scheduler。 |
58
- | naclbit/trinart_stable_diffusion_v2_95k | https://huggingface.co/naclbit/trinart_stable_diffusion_v2 | trinart 经过95k步数训练得到的模型,模型使用了DDIM scheduler。 |
59
- | naclbit/trinart_stable_diffusion_v2_115k | https://huggingface.co/naclbit/trinart_stable_diffusion_v2 | trinart 经过115k步数训练得到的模型,模型使用了DDIM scheduler。 |
60
- | Deltaadams/Hentai-Diffusion | https://huggingface.co/Deltaadams/Hentai-Diffusion | Hentai模型,模型使用了PNDM scheduler。 |
61
- | IDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-v0.1 | https://huggingface.co/IDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-v0.1 | 中文StableDiffusion模型,模型使用了PNDM scheduler。 |
62
- | IDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-EN-v0.1 | https://huggingface.co/IDEA-CCNL/Taiyi-Stable-Diffusion-1B-Chinese-EN-v0.1 | 中文+英文双语言的StableDiffusion模型,模型使用了PNDM scheduler。 |
63
-
64
47
65
48
` train_dreambooth.py ` 代码可传入的参数解释如下:
66
49
> 主要修改的参数
67
- > * ` --pretrained_model_name_or_path ` : 所使用的Stable Diffusion模型权重名称或者本地下载的模型路径 ,目前支持了上表中的8种模型权重,我们可直接替换使用。
50
+ > * ` --pretrained_model_name_or_path ` : 所使用的 ` Stable Diffusion ` 模型权重名称或者本地下载的模型路径 ,目前支持了上表中的8种模型权重,我们可直接替换使用。
68
51
> * ` --instance_data_dir ` : 实例(物体)图片文件夹地址。
69
- > * ` --instance_prompt ` : 带有特定实例(物体)的提示词描述文本,例如『 a photo of sks dog』 ,其中dog代表实例(物体)。
52
+ > * ` --instance_prompt ` : 带有特定实例(物体)的提示词描述文本,例如` a photo of sks dog ` ,其中dog代表实例(物体)。
70
53
> * ` --class_data_dir ` : 类别(class)图片文件夹地址,主要作为先验知识。
71
- > * ` --class_prompt ` : 类别(class)提示词文本,该提示器要与实例(物体)是同一种类别,例如『 a photo of dog』 ,主要作为先验知识。
54
+ > * ` --class_prompt ` : 类别(class)提示词文本,该提示器要与实例(物体)是同一种类别,例如` a photo of dog ` ,主要作为先验知识。
72
55
> * ` --num_class_images ` : 事先需要从` class_prompt ` 中生成多少张图片,主要作为先验知识。
73
56
> * ` --prior_loss_weight ` : 先验` loss ` 占比权重。
74
57
> * ` --sample_batch_size ` : 生成` class_prompt ` 文本对应的图片所用的批次(batch size),注意,当GPU显卡显存较小的时候需要将这个默认值改成1。
75
58
> * ` --with_prior_preservation ` : 是否将生成的同类图片(先验知识)一同加入训练,当为` True ` 的时候,` class_prompt ` 、` class_data_dir ` 、` num_class_images ` 、` sample_batch_size ` 和` prior_loss_weight ` 才生效。
76
59
> * ` --num_train_epochs ` : 训练的轮数,默认值为` 1 ` 。
77
60
> * ` --max_train_steps ` : 最大的训练步数,当我们设置这个值后,它会重新计算所需的` num_train_epochs ` 轮数。
78
- > * ` --save_steps ` : 每间隔多少步` (global step步数) ` ,保存学习到的 ` pipe ` 。
79
- > * ` --gradient_accumulation_steps ` : 梯度累积的步数,用户可以指定梯度累积的步数,在梯度累积的step中 。减少多卡之间梯度的通信,减少更新的次数,扩大训练的batch_size 。
61
+ > * ` --checkpointing_steps ` : 每间隔多少步` (global step步数) ` ,保存模型权重 。
62
+ > * ` --gradient_accumulation_steps ` : 梯度累积的步数,用户可以指定梯度累积的步数,在梯度累积的 step 中 。减少多卡之间梯度的通信,减少更新的次数,扩大训练的 batch_size 。
80
63
> * ` --train_text_encoder ` : 是否一同训练文本编码器的部分,默认为` False ` 。
81
64
82
65
> 可以修改的参数
83
- > * ` --height ` : 输入给模型的图片` 高度 ` ,由于用户输入的并不是固定大小的图片,因此代码中会将原始大小的图片压缩成指定` 高度 ` 的图片,默认值为` 512 ` 。
84
- > * ` --width ` : 输入给模型的图片` 宽度 ` ,由于用户输入的并不是固定大小的图片,因此代码中会将原始大小的图片压缩成指定` 宽度 ` 的图片,默认值为` 512 ` 。
66
+ > * ` --height ` : 输入给模型的图片` 高度 ` ,由于用户输入的并不是固定大小的图片,因此代码中会将原始大小的图片压缩成指定` 高度 ` 的图片,默认值为` None ` 。
67
+ > * ` --width ` : 输入给模型的图片` 宽度 ` ,由于用户输入的并不是固定大小的图片,因此代码中会将原始大小的图片压缩成指定` 宽度 ` 的图片,默认值为` None ` 。
68
+ > * ` --resolution ` : 输入给模型图片的` 分辨率 ` ,当` 高度 ` 或` 宽度 ` 为` None ` 时,我们将会使用` resolution ` ,默认值为` 512 ` 。
85
69
> * ` --learning_rate ` : 学习率。
86
70
> * ` --scale_lr ` : 是否根据GPU数量,梯度累积步数,以及批量数对学习率进行缩放。缩放公式:` learning_rate * gradient_accumulation_steps * train_batch_size * num_processes ` 。
87
71
> * ` --lr_scheduler ` : 要使用的学习率调度策略。默认为 ` constant ` 。
88
- > * ` --lr_warmup_steps ` : 用于从 0 到 ` learning_rate ` 的线性 warmup 的步数。
72
+ > * ` --lr_warmup_steps ` : 用于从 0 到 ` learning_rate ` 的线性 ` warmup ` 的步数。
89
73
> * ` --train_batch_size ` : 训练时每张显卡所使用的` batch_size批量 ` ,当我们的显存较小的时候,需要将这个值设置的小一点。
90
74
> * ` --center_crop ` : 在调整图片宽和高之前是否将裁剪图像居中,默认值为` False ` 。
75
+ > * ` --random_flip ` : 是否对图片进行随机水平反转,默认值为` False ` 。
91
76
> * ` --gradient_checkpointing ` : 是否开启` gradient_checkpointing ` 功能,在一定程度上能够更显显存,但是会减慢训练速度。
92
77
> * ` --output_dir ` : 模型训练完所保存的路径,默认设置为` dreambooth-model ` 文件夹,建议用户每训练一个模型可以修改一下输出路径,防止先前已有的模型被覆盖了。
93
78
94
79
> 基本无需修改的参数
95
80
> * ` --seed ` : 随机种子,为了可以复现训练结果,Tips:当前paddle设置该随机种子后仍无法完美复现。
96
- > * ` --adam_beta1 ` : AdamW 优化器时的 beta1 超参数。默认为 ` 0.9 ` 。
97
- > * ` --adam_beta2 ` : AdamW 优化器时的 beta2 超参数。默认为 ` 0.999 ` 。
98
- > * ` --adam_weight_decay ` : AdamW 优化器时的 weight_decay 超参数。 默认为` 0.02 ` 。
99
- > * ` --adam_weight_decay ` : AdamW 优化器时的 epsilon 超参数。默认为 1e-8。
100
- > * ` --max_grad_norm ` : 最大梯度范数(用于梯度裁剪)。默认为 ` None ` 表示不使用。
81
+ > * ` --adam_beta1 ` : ` AdamW ` 优化器时的 ` beta1 ` 超参数。默认为 ` 0.9 ` 。
82
+ > * ` --adam_beta2 ` : ` AdamW ` 优化器时的 ` beta2 ` 超参数。默认为 ` 0.999 ` 。
83
+ > * ` --adam_weight_decay ` : ` AdamW ` 优化器时的 ` weight_decay ` 超参数。 默认为` 0.02 ` 。
84
+ > * ` --adam_weight_decay ` : ` AdamW ` 优化器时的 ` epsilon ` 超参数。默认为 ` 1e-8 ` 。
85
+ > * ` --max_grad_norm ` : 最大梯度范数(用于梯度裁剪)。默认为 ` -1 ` 表示不使用。
101
86
> * ` --logging_dir ` : Tensorboard 或 VisualDL 记录日志的地址,注意:该地址会与输出目录进行拼接,即,最终的日志地址为` <output_dir>/<logging_dir> ` 。
102
- > * ` --writer_type ` : 用于记录日志的工具,可选` ["tensorboard", "visualdl"] ` ,默认为` visualdl ` ,如果选用` tensorboard ` ,请使用命令安装` pip install tensorboardX ` 。
87
+ > * ` --report_to ` : 用于记录日志的工具,可选` ["tensorboard", "visualdl"] ` ,默认为` visualdl ` ,如果选用` tensorboard ` ,请使用命令安装` pip install tensorboardX ` 。
88
+ > * ` --push_to_hub ` : 是否将模型上传到 ` huggingface hub ` ,默认值为 ` False ` 。
89
+ > * ` --hub_token ` : 上传到 ` huggingface hub ` 所需要使用的 ` token ` ,如果我们已经登录了,那么我们就无需填写。
90
+ > * ` --hub_model_id ` : 上传到 ` huggingface hub ` 的模型库名称, 如果为 ` None ` 的话表示我们将使用 ` output_dir ` 的名称作为模型库名称。
103
91
104
92
105
93
#### 1.2.3 单机多卡训练
@@ -115,19 +103,14 @@ python -u -m paddle.distributed.launch --gpus "0,1,2,3" train_dreambooth.py \
115
103
--instance_data_dir=$INSTANCE_DIR \
116
104
--output_dir=$OUTPUT_DIR \
117
105
--instance_prompt=" a photo of sks dog" \
118
- --height=512 \
119
- --width=512 \
106
+ --resolution=512 \
120
107
--train_batch_size=1 \
121
108
--gradient_accumulation_steps=1 \
122
109
--learning_rate=5e-6 \
123
110
--lr_scheduler=" constant" \
124
111
--lr_warmup_steps=0 \
125
112
--max_train_steps=400
126
113
```
127
- 或
128
- ``` bash
129
- bash run_multi.sh
130
- ```
131
114
132
115
#### 1.2.4 预测生成图片
133
116
@@ -142,7 +125,7 @@ bash run_multi.sh
142
125
├── model_state.pdparams
143
126
├── config.json
144
127
├── text_encoder # text_encoder权重文件夹
145
- ├── model_config .json
128
+ ├── config .json
146
129
├── model_state.pdparams
147
130
├── unet # unet权重文件夹
148
131
├── model_state.pdparams
@@ -194,8 +177,7 @@ python -u train_dreambooth.py \
194
177
--with_prior_preservation --prior_loss_weight=1.0 \
195
178
--instance_prompt=" a photo of sks dog" \
196
179
--class_prompt=" a photo of dog" \
197
- --height=512 \
198
- --width=512 \
180
+ --resolution=512 \
199
181
--train_batch_size=1 \
200
182
--gradient_accumulation_steps=1 \
201
183
--learning_rate=5e-6 \
@@ -222,7 +204,79 @@ image.save("sks-dog-with-class.png")
222
204
</p >
223
205
224
206
207
+ # 使用 LoRA 和 DreamBooth 技术进行模型训练
208
+
209
+ [ LoRA: Low-Rank Adaptation of Large Language Models] ( https://arxiv.org/abs/2106.09685 ) 是微软研究员引入的一项新技术,主要用于处理大模型微调的问题。目前超过数十亿以上参数的具有强能力的大模型 (例如 GPT-3) 通常在为了适应其下游任务的微调中会呈现出巨大开销。LoRA 建议冻结预训练模型的权重并在每个 Transformer 块中注入可训练层 (秩-分解矩阵)。因为不需要为大多数模型权重计算梯度,所以大大减少了需要训练参数的数量并且降低了 GPU 的内存要求。研究人员发现,通过聚焦大模型的 Transformer 注意力块,使用 LoRA 进行的微调质量与全模型微调相当,同时速度更快且需要更少的计算。
210
+
211
+ 简而言之,LoRA允许通过向现有权重添加一对秩分解矩阵,并只训练这些新添加的权重来适应预训练的模型。这有几个优点:
212
+
213
+ - 保持预训练的权重不变,这样模型就不容易出现灾难性遗忘 [ catastrophic forgetting] ( https://www.pnas.org/doi/10.1073/pnas.1611835114 ) ;
214
+ - 秩分解矩阵的参数比原始模型少得多,这意味着训练的 LoRA 权重很容易移植;
215
+ - LoRA 注意力层允许通过一个 ` scale ` 参数来控制模型适应新训练图像的程度。
216
+
217
+ [ cloneofsimo] ( https://github.com/cloneofsimo ) 是第一个在 [ LoRA GitHub] ( https://github.com/cloneofsimo/lora ) 仓库中尝试使用 LoRA 训练 Stable Diffusion 的人。
218
+
219
+ ## 训练
220
+
221
+ ** ___ Note: 如果我们使用 [ stable-diffusion-2] ( https://huggingface.co/stabilityai/stable-diffusion-2 ) 进行训练,那么我们需要将 ` resolution ` 改成 768 .___ **
222
+
223
+ ``` bash
224
+ export MODEL_NAME=" runwayml/stable-diffusion-v1-5"
225
+ export INSTANCE_DIR=" path-to-instance-images"
226
+ export OUTPUT_DIR=" path-to-save-model"
227
+
228
+ python train_dreambooth_lora.py \
229
+ --pretrained_model_name_or_path=$MODEL_NAME \
230
+ --instance_data_dir=$INSTANCE_DIR \
231
+ --output_dir=$OUTPUT_DIR \
232
+ --instance_prompt=" a photo of sks dog" \
233
+ --resolution=512 \
234
+ --train_batch_size=1 \
235
+ --gradient_accumulation_steps=1 \
236
+ --checkpointing_steps=100 \
237
+ --learning_rate=1e-4 \
238
+ --report_to=" visualdl" \
239
+ --lr_scheduler=" constant" \
240
+ --lr_warmup_steps=0 \
241
+ --max_train_steps=500 \
242
+ --validation_prompt=" A photo of sks dog in a bucket" \
243
+ --validation_epochs=50 \
244
+ --seed=0
245
+ ```
246
+
247
+ ** ___ Note: 当我使用 LoRA 训练模型的时候,我们需要使用更大的学习率,因此我们这里使用 * 1e-4* 而不是 * 2e-6* .___ **
248
+
249
+ 最终经过微调后的 LoRA 权重,我们已经上传到了 [ junnyu/lora_dreambooth_dog_example] ( https://huggingface.co/junnyu/lora_dreambooth_dog_example ) . ** ___ Note: [ 最终的权重] ( https://huggingface.co/junnyu/lora_dreambooth_dog_example/blob/main/paddle_lora_weights.pdparams ) 只有 3 MB 的大小.___ **
250
+
251
+ ## 推理
252
+
253
+ 经过训练, LoRA 权重可以直接加载到原始的 pipeline 中。
254
+
255
+ 首先我们需要加载原始的 pipeline:
256
+
257
+ ``` python
258
+ from ppdiffusers import DiffusionPipeline, DPMSolverMultistepScheduler
259
+ import paddle
260
+
261
+ pipe = DiffusionPipeline.from_pretrained(" runwayml/stable-diffusion-v1-5" , paddle_dtype = paddle.float16)
262
+ pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
263
+ ```
264
+
265
+ 接下来, 我们需要使用 ` load_attn_procs ` 方法将 ` adapter layers ` 添加到 UNet 模型中。
266
+ ``` python
267
+ pipe.unet.load_attn_procs(" junnyu/lora_dreambooth_dog_example" , from_hf_hub = True )
268
+ ```
269
+
270
+ 最终, 我们可以使用模型进行推理预测.
271
+
272
+ ``` python
273
+ image = pipe(" A picture of a sks dog in a bucket" , num_inference_steps = 25 ).images[0 ]
274
+ image.save(" demo.png" )
275
+ ```
276
+ <p align =" center " >
277
+ <img src="https://user-images.githubusercontent.com/50394665/218384517-b89667f4-b5c9-4ecf-afcb-8b667c5532bb.jpg">
278
+ </p >
225
279
226
- ## 2 参考资料
280
+ # 参考资料
227
281
- https://github.com/huggingface/diffusers/tree/main/examples/dreambooth
228
282
- https://github.com/CompVis/stable-diffusion
0 commit comments