Buckets:

hf-doc-build/doc / diffusers /main /fr /training /custom_diffusion.md
mishig's picture
|
download
raw
17.3 kB
# Custom Diffusion
[Custom Diffusion](https://huggingface.co/papers/2212.04488) est une technique d’entraînement pour personnaliser les modèles de génération d’images. Tout comme Textual Inversion, DreamBooth et LoRA, Custom Diffusion n’exige que quelques (~4-5) images d’exemple. Cette technique fonctionne en n’entraînant que les poids des couches d’attention croisée, et elle utilise un mot spécial pour représenter le nouvel apprentissage du concept. Custom Diffusion est unique car il peut également apprendre plusieurs concepts simultanément.
Si vous entraînez sur un GPU avec une vRAM limitée, vous devriez essayer d’activer xFormers avec `--enable_xformers_memory_efficient_attention` pour un entraînement plus rapide avec des besoins en vRAM réduits (16 Go). Pour économiser encore plus de mémoire, ajoutez `--set_grads_to_none` dans l’argument d’entraînement pour définir les gradients sur `None` au lieu de zéro (cette option peut causer certains problèmes, donc si vous en rencontrez, essayez de retirer ce paramètre).
Ce guide examine le script [train_custom_diffusion.py](https://github.com/huggingface/diffusers/blob/main/examples/custom_diffusion/train_custom_diffusion.py) afin de vous familiariser avec celui-ci et de vous montrer comment l’adapter à votre propre cas d’usage.
Avant d'exécuter le script, assurez-vous d'installer la bibliothèque à partir du code source :
```bash
git clone https://github.com/huggingface/diffusers
cd diffusers
pip install .
```
Accédez au dossier d'exemple contenant le script d'entraînement et installez les dépendances requises :
```bash
cd examples/custom_diffusion
pip install -r requirements.txt
pip install clip-retrieval
```
> [!TIP]
> 🤗 Accelerate est une bibliothèque qui vous aide à entraîner sur plusieurs GPU/TPU ou avec une précision mixte. Elle configure automatiquement votre configuration d'entraînement en fonction de votre matériel et de votre environnement. Consultez le [tour rapide](https://huggingface.co/docs/accelerate/quicktour) de 🤗 Accelerate pour en savoir plus.
Initialiser un environnement 🤗 Accelerate :
```bash
accelerate config
```
Pour configurer un environnement 🤗 Accelerate par défaut sans choisir de configuration :
```bash
accelerate config default
```
Sinon, si votre environnement ne prend pas en charge un shell interactif, comme un notebook, vous pouvez utiliser :
```py
from accelerate.utils import write_basic_config
write_basic_config()
```
Enfin, si vous souhaitez entraîner un modèle sur votre propre jeu de données, consultez le guide [Create a dataset for training](create_dataset) pour apprendre à créer un jeu de données compatible avec le script d'entraînement.
> [!TIP]
> Les sections suivantes mettent en évidence les parties du script d'entraînement importantes pour comprendre comment le modifier, mais elles ne couvrent pas tous les aspects du script en détail. Si vous souhaitez en savoir plus, n'hésitez pas à lire le [script](https://github.com/huggingface/diffusers/blob/main/examples/custom_diffusion/train_custom_diffusion.py) et à nous faire part de vos questions ou préoccupations.
## Paramètres du script
Le script d’entraînement contient tous les paramètres pour vous aider à personnaliser votre session d’entraînement. Ils se trouvent dans la fonction [`parse_args()`](https://github.com/huggingface/diffusers/blob/64603389da01082055a901f2883c4810d1144edb/examples/custom_diffusion/train_custom_diffusion.py#L319). La fonction est fournie avec des valeurs par défaut, mais vous pouvez également définir vos propres valeurs dans la commande d’entraînement si vous le souhaitez.
Par exemple, pour changer la résolution de l'image d'entrée :
```bash
accelerate launch train_custom_diffusion.py \
--resolution=256
```
De nombreux paramètres de base sont décrits dans le guide d’entraînement [DreamBooth](dreambooth#script-parameters), ce guide se concentre donc sur les paramètres spécifiques à Custom Diffusion :
- `--freeze_model` : fige les paramètres de clé et de valeur dans la couche d'attention croisée ; la valeur par défaut est `crossattn_kv`, mais vous pouvez la définir sur `crossattn` pour entraîner tous les paramètres de la couche d'attention croisée
- `--concepts_list` : pour apprendre plusieurs concepts, fournissez un chemin vers un fichier JSON contenant les concepts
- `--modifier_token` : un mot spécial utilisé pour représenter le concept appris
- `--initializer_token` : un mot spécial utilisé pour initialiser les embeddings du `modifier_token`
### Perte de préservation des antécédents
La perte de préservation des a priori est une méthode qui utilise les échantillons générés par le modèle lui-même pour l'aider à apprendre à générer des images plus variées. Étant donné que ces images générées appartiennent à la même classe que les images que vous avez fournies, elles aident le modèle à conserver ce qu'il a appris sur la classe et à exploiter ses connaissances existantes sur la classe pour créer de nouvelles compositions.
De nombreux paramètres de la perte de préservation antérieure sont décrits dans le guide d'entraînement [DreamBooth](dreambooth#prior-preservation-loss).
### Régularisation
Custom Diffusion inclut l’entraînement des images cibles avec un petit ensemble d’images réelles afin de prévenir le surapprentissage. Comme vous pouvez l’imaginer, cela peut être facile à faire lorsque vous n’entraînez que sur quelques images ! Téléchargez 200 images réelles avec `clip_retrieval`. Le `class_prompt` doit être de la même catégorie que les images cibles. Ces images sont stockées dans `class_data_dir`.
```bash
python retrieve.py --class_prompt cat --class_data_dir real_reg/samples_cat --num_class_images 200
```
Pour activer la régularisation, ajoutez les paramètres suivants :
- `--with_prior_preservation` : indique s'il faut utiliser la perte de préservation a priori
- `--prior_loss_weight` : contrôle l'influence de la perte de préservation du prior sur le modèle
- `--real_prior` : indique s'il faut utiliser un petit ensemble d'images réelles pour éviter le surapprentissage
```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 \
```
## Script d'entraînement
> [!TIP]
> Une grande partie du code du script d’entraînement Custom Diffusion est similaire à celui du script [DreamBooth](dreambooth#training-script). Ce guide se concentre donc sur le code spécifique à Custom Diffusion.
Le script d'entraînement Custom Diffusion comporte deux classes de jeu de données :
- [`CustomDiffusionDataset`](https://github.com/huggingface/diffusers/blob/64603389da01082055a901f2883c4810d1144edb/examples/custom_diffusion/train_custom_diffusion.py#L165) : prétraite les images, les images de classe et les prompts pour l'entraînement
- [`PromptDataset`](https://github.com/huggingface/diffusers/blob/64603389da01082055a901f2883c4810d1144edb/examples/custom_diffusion/train_custom_diffusion.py#L148) : prépare les prompts pour générer les images de classes
Ensuite, le `modifier_token` est [ajouté au tokenizer](https://github.com/huggingface/diffusers/blob/64603389da01082055a901f2883c4810d1144edb/examples/custom_diffusion/train_custom_diffusion.py#L811), converti en identifiants de jetons, et les plongements de jetons sont redimensionnés pour prendre en compte le nouveau `modifier_token`. Les plongements du `modifier_token` sont ensuite initialisés avec les plongements du `initializer_token`. Tous les paramètres de l'encodeur de texte sont figés, à l'exception des plongements de jetons, car c'est ce que le modèle cherche à apprendre pour l'associer aux concepts.
```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)
```
Vous devez maintenant ajouter les [Custom Diffusion weights](https://github.com/huggingface/diffusers/blob/64603389da01082055a901f2883c4810d1144edb/examples/custom_diffusion/train_custom_diffusion.py#L911C3-L911C3) aux couches d'attention. C'est une étape essentielle pour obtenir la forme et la taille correctes des poids d'attention, ainsi que pour définir le nombre approprié de processeurs d'attention dans chaque bloc 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)
```
L'[optimizer](https://github.com/huggingface/diffusers/blob/84cd9e8d01adb47f046b1ee449fc76a0c32dc4e2/examples/custom_diffusion/train_custom_diffusion.py#L982) est initialisé pour mettre à jour les paramètres de la couche d'attention croisée :
```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,
)
```
Dans la [boucle d'entraînement](https://github.com/huggingface/diffusers/blob/84cd9e8d01adb47f046b1ee449fc76a0c32dc4e2/examples/custom_diffusion/train_custom_diffusion.py#L1048), il est important de ne mettre à jour que les embeddings du concept que vous essayez d'apprendre. Cela implique de mettre à zéro les gradients de tous les autres embeddings de jetons :
```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)
```
## Lancer le script
Une fois que vous avez apporté toutes vos modifications ou que vous êtes satisfait de la configuration par défaut, vous êtes prêt à lancer le script d’entraînement ! 🚀
Dans ce guide, vous téléchargerez et utiliserez ces [images de chats](https://www.cs.cmu.edu/~custom-diffusion/assets/data.zip) d'exemple. Vous pouvez également créer et utiliser votre propre jeu de données si vous le souhaitez (voir le guide [Créer un jeu de données pour l'entraînement](create_dataset)).
Définissez la variable d’environnement `MODEL_NAME` sur un identifiant de modèle du Hub ou un chemin vers un modèle local, `INSTANCE_DIR` sur le chemin où vous venez de télécharger les images de chats, et `OUTPUT_DIR` sur l’endroit où vous souhaitez enregistrer le modèle. Vous utiliserez `<new1>` comme mot spécial pour lier les embeddings nouvellement appris. Le script crée et enregistre des points de contrôle du modèle ainsi qu’un fichier pytorch_custom_diffusion_weights.bin dans votre dépôt.
Pour suivre la progression de l’entraînement avec Weights and Biases, ajoutez le paramètre `--report_to=wandb` à la commande d’entraînement et spécifiez un prompt de validation avec `--validation_prompt`. Cela est utile pour le débogage et la sauvegarde de résultats intermédiaires.
> [!TIP]
> Si vous entraînez sur des visages humains, l’équipe Custom Diffusion a constaté que les paramètres suivants fonctionnent bien :
>
> - `--learning_rate=5e-6` - `--max_train_steps` peut être compris entre 1000 et 2000 - `--freeze_model=crossattn` - utilisez au moins 15 à 20 images pour l'entraînement
```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 peut également apprendre plusieurs concepts si vous fournissez un fichier [JSON](https://github.com/adobe-research/custom-diffusion/blob/main/assets/concept_list.json) contenant quelques détails sur chaque concept à apprendre.
Exécutez clip-retrieval pour collecter de vraies images à utiliser pour la régularisation :
```bash
pip install clip-retrieval
python retrieve.py --class_prompt {} --class_data_dir {} --num_class_images 200
```
Vous pouvez ensuite lancer le script :
```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
```
Une fois l’entraînement terminé, vous pouvez utiliser votre nouveau modèle Custom Diffusion pour l’inférence.
```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")
```
## Étapes suivantes
Félicitations pour avoir entraîné un modèle avec Custom Diffusion ! 🎉 Pour en savoir plus :
- Lisez le billet de blog [Multi-Concept Customization of Text-to-Image Diffusion](https://www.cs.cmu.edu/~custom-diffusion/) pour en savoir plus sur les résultats expérimentaux de l'équipe Custom Diffusion.

Xet Storage Details

Size:
17.3 kB
·
Xet hash:
16ca63d7915db5c7780b263f0c7f4e4ee5e0b54fb2910997b6dc059282cad00d

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