Buckets:

hf-doc-build/doc / diffusers /v0.43.0 /id /training /custom_diffusion.md
mishig's picture
|
download
raw
16.4 kB
# Custom Diffusion
[Custom Diffusion](https://huggingface.co/papers/2212.04488) adalah teknik pelatihan untuk mempersonalisasi model generasi gambar. Seperti Textual Inversion, DreamBooth, dan LoRA, Custom Diffusion hanya membutuhkan beberapa (~4-5) gambar contoh. Teknik ini bekerja dengan hanya melatih bobot pada lapisan cross-attention, dan menggunakan kata khusus untuk merepresentasikan konsep yang baru dipelajari. Custom Diffusion unik karena juga dapat mempelajari beberapa konsep secara bersamaan.
Jika Anda melatih pada GPU dengan vRAM terbatas, Anda sebaiknya mencoba mengaktifkan xFormers dengan `--enable_xformers_memory_efficient_attention` untuk pelatihan yang lebih cepat dengan kebutuhan vRAM yang lebih rendah (16GB). Untuk menghemat lebih banyak memori, tambahkan `--set_grads_to_none` pada argumen pelatihan untuk mengatur gradien menjadi `None` alih-alih nol (opsi ini dapat menyebabkan beberapa masalah, jadi jika Anda mengalaminya, coba hapus parameter ini).
Panduan ini akan membahas skrip [train_custom_diffusion.py](https://github.com/huggingface/diffusers/blob/main/examples/custom_diffusion/train_custom_diffusion.py) untuk membantu Anda lebih mengenalnya, serta bagaimana Anda dapat menyesuaikannya untuk kebutuhan Anda sendiri.
Sebelum menjalankan skrip, pastikan Anda menginstal pustaka dari sumber:
```bash
git clone https://github.com/huggingface/diffusers
cd diffusers
pip install .
```
Beralih ke folder contoh dengan skrip pelatihan dan instal dependensi yang diperlukan:
```bash
cd examples/custom_diffusion
pip install -r requirements.txt
pip install clip-retrieval
```
> [!TIP]
> ๐Ÿค— Accelerate adalah pustaka untuk membantu Anda melatih pada beberapa GPU/TPU atau dengan presisi campuran. Pustaka ini akan mengonfigurasi pengaturan pelatihan Anda secara otomatis berdasarkan perangkat keras dan lingkungan Anda. Lihat [Tour singkat](https://huggingface.co/docs/accelerate/quicktour) ๐Ÿค— Accelerate untuk mempelajari lebih lanjut.
Inisialisasi lingkungan ๐Ÿค— Accelerate:
```bash
accelerate config
```
Untuk menyiapkan lingkungan ๐Ÿค— Accelerate default tanpa memilih konfigurasi apa pun:
```bash
accelerate config default
```
Atau jika lingkungan Anda tidak mendukung shell interaktif, seperti notebook, Anda dapat menggunakan:
```py
from accelerate.utils import write_basic_config
write_basic_config()
```
Terakhir, jika Anda ingin melatih model pada dataset Anda sendiri, lihat panduan [Membuat dataset untuk pelatihan](create_dataset) untuk mempelajari cara membuat dataset yang berfungsi dengan skrip pelatihan.
> [!TIP]
> Bagian-bagian berikut menyoroti bagian dari skrip pelatihan yang penting untuk dipahami agar Anda dapat memodifikasinya, namun tidak membahas setiap aspek skrip secara detail. Jika Anda tertarik untuk mempelajari lebih lanjut, silakan membaca [skrip](https://github.com/huggingface/diffusers/blob/main/examples/custom_diffusion/train_custom_diffusion.py) tersebut dan beri tahu kami jika Anda memiliki pertanyaan atau kekhawatiran.
## Parameter skrip
Skrip pelatihan berisi semua parameter untuk membantu Anda menyesuaikan eksekusi pelatihan Anda. Parameter ini dapat ditemukan di fungsi [`parse_args()`](https://github.com/huggingface/diffusers/blob/64603389da01082055a901f2883c4810d1144edb/examples/custom_diffusion/train_custom_diffusion.py#L319). Fungsi ini dilengkapi dengan nilai default, tetapi Anda juga dapat mengatur nilai Anda sendiri dalam perintah pelatihan jika Anda mau.
Sebagai contoh, untuk mengubah resolusi gambar input:
```bash
accelerate launch train_custom_diffusion.py \
--resolution=256
```
Banyak parameter dasar dijelaskan dalam panduan pelatihan [DreamBooth](dreambooth#script-parameters), sehingga panduan ini berfokus pada parameter yang unik untuk Custom Diffusion:
- `--freeze_model`: membekukan parameter kunci dan nilai pada lapisan cross-attention; nilai defaultnya adalah `crossattn_kv`, tetapi Anda dapat mengaturnya menjadi `crossattn` untuk melatih semua parameter pada lapisan cross-attention
- `--concepts_list`: untuk mempelajari beberapa konsep, berikan path ke file JSON yang berisi konsep-konsep tersebut
- `--modifier_token`: kata khusus yang digunakan untuk merepresentasikan konsep yang dipelajari
- `--initializer_token`: kata khusus yang digunakan untuk menginisialisasi embedding dari `modifier_token`
### Prior preservation loss
Prior preservation loss adalah metode yang menggunakan sampel yang dihasilkan oleh model itu sendiri untuk membantunya belajar cara menghasilkan gambar yang lebih beragam. Karena gambar sampel yang dihasilkan ini termasuk dalam kelas yang sama dengan gambar yang Anda berikan, mereka membantu model mempertahankan apa yang telah dipelajarinya tentang kelas tersebut dan bagaimana ia dapat menggunakan pengetahuan yang sudah dimilikinya tentang kelas tersebut untuk membuat komposisi baru.
Banyak parameter untuk prior preservation loss dijelaskan dalam panduan pelatihan [DreamBooth](dreambooth#prior-preservation-loss).
### Regularisasi
Custom Diffusion mencakup pelatihan gambar target dengan set kecil gambar asli untuk mencegah overfitting. Seperti yang bisa Anda bayangkan, ini mudah dilakukan ketika Anda hanya melatih pada beberapa gambar! Unduh 200 gambar asli dengan `clip_retrieval`. `class_prompt` harus memiliki kategori yang sama dengan gambar target. Gambar-gambar ini disimpan di `class_data_dir`.
```bash
python retrieve.py --class_prompt cat --class_data_dir real_reg/samples_cat --num_class_images 200
```
Untuk mengaktifkan regularisasi, tambahkan parameter berikut:
- `--with_prior_preservation`: apakah akan menggunakan prior preservation loss
- `--prior_loss_weight`: mengontrol pengaruh prior preservation loss pada model
- `--real_prior`: apakah akan menggunakan kumpulan kecil gambar asli untuk mencegah overfitting
```bash
accelerate launch train_custom_diffusion.py \
--with_prior_preservation \
--prior_loss_weight=1.0 \
--class_data_dir="./real_reg/samples_cat" \
--class_prompt="cat" \
--real_prior=True \
```
## Skrip pelatihan
> [!TIP]
> Banyak kode dalam skrip pelatihan Custom Diffusion mirip dengan skrip [DreamBooth](dreambooth#training-script). Panduan ini justru berfokus pada kode yang relevan dengan Custom Diffusion.
Skrip pelatihan Custom Diffusion memiliki dua kelas dataset:
- [`CustomDiffusionDataset`](https://github.com/huggingface/diffusers/blob/64603389da01082055a901f2883c4810d1144edb/examples/custom_diffusion/train_custom_diffusion.py#L165): memproses prapenanganan gambar, gambar kelas, dan prompt untuk pelatihan
- [`PromptDataset`](https://github.com/huggingface/diffusers/blob/64603389da01082055a901f2883c4810d1144edb/examples/custom_diffusion/train_custom_diffusion.py#L148): menyiapkan prompt untuk menghasilkan gambar kelas
Selanjutnya, `modifier_token` [ditambahkan ke tokenizer](https://github.com/huggingface/diffusers/blob/64603389da01082055a901f2883c4810d1144edb/examples/custom_diffusion/train_custom_diffusion.py#L811), dikonversi menjadi id token, dan ukuran embedding token disesuaikan untuk mengakomodasi `modifier_token` baru. Kemudian, embedding `modifier_token` diinisialisasi dengan embedding dari `initializer_token`. Semua parameter dalam text encoder dibekukan, kecuali embedding token, karena inilah yang model coba pelajari untuk dikaitkan dengan konsep-konsep tersebut.
```py
params_to_freeze = itertools.chain(
text_encoder.text_model.encoder.parameters(),
text_encoder.text_model.final_layer_norm.parameters(),
text_encoder.text_model.embeddings.position_embedding.parameters(),
)
freeze_params(params_to_freeze)
```
Sekarang Anda perlu menambahkan [Custom Diffusion weights](https://github.com/huggingface/diffusers/blob/64603389da01082055a901f2883c4810d1144edb/examples/custom_diffusion/train_custom_diffusion.py#L911C3-L911C3) ke lapisan attention. Ini adalah langkah yang sangat penting untuk mendapatkan bentuk dan ukuran bobot attention yang benar, serta untuk mengatur jumlah processor attention yang tepat di setiap blok UNet.
```py
st = unet.state_dict()
for name, _ in unet.attn_processors.items():
cross_attention_dim = None if name.endswith("attn1.processor") else unet.config.cross_attention_dim
if name.startswith("mid_block"):
hidden_size = unet.config.block_out_channels[-1]
elif name.startswith("up_blocks"):
block_id = int(name[len("up_blocks.")])
hidden_size = list(reversed(unet.config.block_out_channels))[block_id]
elif name.startswith("down_blocks"):
block_id = int(name[len("down_blocks.")])
hidden_size = unet.config.block_out_channels[block_id]
layer_name = name.split(".processor")[0]
weights = {
"to_k_custom_diffusion.weight": st[layer_name + ".to_k.weight"],
"to_v_custom_diffusion.weight": st[layer_name + ".to_v.weight"],
}
if train_q_out:
weights["to_q_custom_diffusion.weight"] = st[layer_name + ".to_q.weight"]
weights["to_out_custom_diffusion.0.weight"] = st[layer_name + ".to_out.0.weight"]
weights["to_out_custom_diffusion.0.bias"] = st[layer_name + ".to_out.0.bias"]
if cross_attention_dim is not None:
custom_diffusion_attn_procs[name] = attention_class(
train_kv=train_kv,
train_q_out=train_q_out,
hidden_size=hidden_size,
cross_attention_dim=cross_attention_dim,
).to(unet.device)
custom_diffusion_attn_procs[name].load_state_dict(weights)
else:
custom_diffusion_attn_procs[name] = attention_class(
train_kv=False,
train_q_out=False,
hidden_size=hidden_size,
cross_attention_dim=cross_attention_dim,
)
del st
unet.set_attn_processor(custom_diffusion_attn_procs)
custom_diffusion_layers = AttnProcsLayers(unet.attn_processors)
```
[optimizer](https://github.com/huggingface/diffusers/blob/84cd9e8d01adb47f046b1ee449fc76a0c32dc4e2/examples/custom_diffusion/train_custom_diffusion.py#L982) diinisialisasi untuk memperbarui parameter lapisan cross-attention:
```py
optimizer = optimizer_class(
itertools.chain(text_encoder.get_input_embeddings().parameters(), custom_diffusion_layers.parameters())
if args.modifier_token is not None
else custom_diffusion_layers.parameters(),
lr=args.learning_rate,
betas=(args.adam_beta1, args.adam_beta2),
weight_decay=args.adam_weight_decay,
eps=args.adam_epsilon,
)
```
Dalam [loop pelatihan](https://github.com/huggingface/diffusers/blob/84cd9e8d01adb47f046b1ee449fc76a0c32dc4e2/examples/custom_diffusion/train_custom_diffusion.py#L1048), penting untuk hanya memperbarui embedding untuk konsep yang sedang Anda pelajari. Ini berarti mengatur gradien dari semua embedding token lainnya menjadi nol:
```py
if args.modifier_token is not None:
if accelerator.num_processes > 1:
grads_text_encoder = text_encoder.module.get_input_embeddings().weight.grad
else:
grads_text_encoder = text_encoder.get_input_embeddings().weight.grad
index_grads_to_zero = torch.arange(len(tokenizer)) != modifier_token_id[0]
for i in range(len(modifier_token_id[1:])):
index_grads_to_zero = index_grads_to_zero & (
torch.arange(len(tokenizer)) != modifier_token_id[i]
)
grads_text_encoder.data[index_grads_to_zero, :] = grads_text_encoder.data[
index_grads_to_zero, :
].fill_(0)
```
## Jalankan skrip
Setelah Anda melakukan semua perubahan atau merasa puas dengan konfigurasi default, Anda siap untuk menjalankan skrip pelatihan! ๐Ÿš€
Dalam panduan ini, Anda akan mengunduh dan menggunakan contoh [gambar kucing](https://www.cs.cmu.edu/~custom-diffusion/assets/data.zip) ini. Anda juga dapat membuat dan menggunakan dataset Anda sendiri jika diinginkan (lihat panduan [Membuat dataset untuk pelatihan](create_dataset)).
Setel variabel lingkungan `MODEL_NAME` ke id model di Hub atau path ke model lokal, `INSTANCE_DIR` ke path tempat Anda baru saja mengunduh gambar kucing, dan `OUTPUT_DIR` ke tempat Anda ingin menyimpan model. Anda akan menggunakan `<new1>` sebagai kata khusus untuk mengaitkan embedding yang baru dipelajari. Skrip ini membuat dan menyimpan checkpoint model serta file pytorch_custom_diffusion_weights.bin ke repositori Anda.
Untuk memantau kemajuan pelatihan dengan Weights and Biases, tambahkan parameter `--report_to=wandb` ke perintah pelatihan dan tentukan prompt validasi dengan `--validation_prompt`. Hal ini berguna untuk debugging dan menyimpan hasil antara.
> [!TIP]
> Jika Anda melatih pada wajah manusia, tim Custom Diffusion telah menemukan bahwa parameter berikut bekerja dengan baik:
>
> - `--learning_rate=5e-6` - `--max_train_steps` dapat berada di antara 1000 dan 2000 - `--freeze_model=crossattn` - gunakan minimal 15-20 gambar untuk pelatihan
```bash
export MODEL_NAME="CompVis/stable-diffusion-v1-4"
export OUTPUT_DIR="path-to-save-model"
export INSTANCE_DIR="./data/cat"
accelerate launch train_custom_diffusion.py \
--pretrained_model_name_or_path=$MODEL_NAME \
--instance_data_dir=$INSTANCE_DIR \
--output_dir=$OUTPUT_DIR \
--class_data_dir=./real_reg/samples_cat/ \
--with_prior_preservation \
--real_prior \
--prior_loss_weight=1.0 \
--class_prompt="cat" \
--num_class_images=200 \
--instance_prompt="photo of a <new1> cat" \
--resolution=512 \
--train_batch_size=2 \
--learning_rate=1e-5 \
--lr_warmup_steps=0 \
--max_train_steps=250 \
--scale_lr \
--hflip \
--modifier_token "<new1>" \
--validation_prompt="<new1> cat sitting in a bucket" \
--report_to="wandb" \
--push_to_hub
```
Custom Diffusion juga dapat mempelajari beberapa konsep jika Anda menyediakan file [JSON](https://github.com/adobe-research/custom-diffusion/blob/main/assets/concept_list.json) dengan beberapa detail tentang masing-masing konsep yang harus dipelajari.
Jalankan clip-retrieval untuk mengumpulkan beberapa gambar asli yang akan digunakan untuk regularisasi:
```bash
pip install clip-retrieval
python retrieve.py --class_prompt {} --class_data_dir {} --num_class_images 200
```
Lalu Anda dapat menjalankan skrip:
```bash
export MODEL_NAME="CompVis/stable-diffusion-v1-4"
export OUTPUT_DIR="path-to-save-model"
accelerate launch train_custom_diffusion.py \
--pretrained_model_name_or_path=$MODEL_NAME \
--output_dir=$OUTPUT_DIR \
--concepts_list=./concept_list.json \
--with_prior_preservation \
--real_prior \
--prior_loss_weight=1.0 \
--resolution=512 \
--train_batch_size=2 \
--learning_rate=1e-5 \
--lr_warmup_steps=0 \
--max_train_steps=500 \
--num_class_images=200 \
--scale_lr \
--hflip \
--modifier_token "<new1>+<new2>" \
--push_to_hub
```
Setelah pelatihan selesai, Anda dapat menggunakan model Custom Diffusion baru Anda untuk inferensi.
```py
import torch
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"CompVis/stable-diffusion-v1-4", dtype=torch.float16,
).to("cuda") # or "mps", "xpu", "cpu"
pipeline.unet.load_attn_procs("path-to-save-model", weight_name="pytorch_custom_diffusion_weights.bin")
pipeline.load_textual_inversion("path-to-save-model", weight_name="<new1>.bin")
image = pipeline(
"<new1> cat sitting in a bucket",
num_inference_steps=100,
guidance_scale=6.0,
eta=1.0,
).images[0]
image.save("cat.png")
```
```py
import torch
from huggingface_hub.repocard import RepoCard
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"CompVis/stable-diffusion-v1-4", dtype=torch.float16,
).to("cuda") # or "mps", "xpu", "cpu"
model_id = "sayakpaul/custom-diffusion-cat-wooden-pot"
pipeline.unet.load_attn_procs(model_id, weight_name="pytorch_custom_diffusion_weights.bin")
pipeline.load_textual_inversion(model_id, weight_name="<new1>.bin")
pipeline.load_textual_inversion(model_id, weight_name="<new2>.bin")
image = pipeline(
"the <new1> cat sculpture in the style of a <new2> wooden pot",
num_inference_steps=100,
guidance_scale=6.0,
eta=1.0,
).images[0]
image.save("multi-subject.png")
```
## Langkah selanjutnya
Selamat karena Anda telah melatih model dengan Custom Diffusion! ๐ŸŽ‰ Untuk mempelajari lebih lanjut:
- Baca artikel blog [Multi-Concept Customization of Text-to-Image Diffusion](https://www.cs.cmu.edu/~custom-diffusion/) untuk mempelajari lebih lanjut tentang hasil eksperimen dari tim Custom Diffusion.

Xet Storage Details

Size:
16.4 kB
ยท
Xet hash:
821fe617cce3d08c1312f056aad1607301f354795ae12a1bb8aca6270ba00fa2

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.