# T2I-Adapter

[T2I-Adapter](https://hf.co/papers/2302.08453) est un modèle d’adaptateur léger qui fournit une image de conditionnement supplémentaire (line art, canny, sketch, depth, pose) pour mieux contrôler la génération d’images. Il est similaire à un ControlNet, mais beaucoup plus petit (~77M paramètres et ~300Mo de taille de fichier) car il n’insère des poids que dans le UNet, au lieu de le copier et de l’entraîner.

Le T2I-Adapter n'est disponible que pour l'entraînement avec le modèle Stable Diffusion XL (SDXL).

Ce guide examine le script d’entraînement [train_t2i_adapter_sdxl.py](https://github.com/huggingface/diffusers/blob/main/examples/t2i_adapter/train_t2i_adapter_sdxl.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 .
```

Puis accédez au dossier d'exemple contenant le script d'entraînement et installez les dépendances requises pour le script que vous utilisez :

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

> [!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/t2i_adapter/train_t2i_adapter_sdxl.py) et à nous faire part de vos questions ou préoccupations.

## Paramètres du script

Le script d’entraînement fournit de nombreux paramètres pour vous aider à personnaliser votre session d’entraînement. Tous les paramètres et leurs descriptions se trouvent dans la fonction [`parse_args()`](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L233). Elle fournit des valeurs par défaut pour chaque paramètre, telles que la taille du lot d’entraînement et le taux d’apprentissage, mais vous pouvez également définir vos propres valeurs dans la commande d’entraînement si vous le souhaitez.

Par exemple, pour activer l'accumulation de gradients, ajoutez le paramètre `--gradient_accumulation_steps` à la commande d'entraînement :

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

De nombreux paramètres de base et importants sont décrits dans le guide d’entraînement [Text-to-image](text2image#script-parameters), ce guide se concentre donc uniquement sur les paramètres T2I-Adapter pertinents :

- `--pretrained_vae_model_name_or_path` : chemin vers un VAE pré-entraîné ; le VAE de SDXL est connu pour souffrir d'instabilité numérique, ce paramètre vous permet donc de spécifier un [VAE](https://huggingface.co/madebyollin/sdxl-vae-fp16-fix) plus performant
- `--crops_coords_top_left_h` et `--crops_coords_top_left_w` : coordonnées de hauteur et de largeur à inclure dans les embeddings de coordonnées de recadrage de SDXL
- `--conditioning_image_column` : la colonne des images de conditionnement dans le jeu de données
- `--proportion_empty_prompts` : la proportion de prompts d'image à remplacer par des chaînes vides

## Script d'entraînement

Comme pour les paramètres du script, un parcours détaillé du script d’entraînement est fourni dans le guide d’entraînement [Text-to-image](text2image#training-script). En revanche, ce guide se concentre sur les parties du script spécifiques à T2I-Adapter.

Le script d'entraînement commence par préparer le jeu de données. Cela inclut le [tokenization](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L674) du prompt et l'[application de transformations](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L714) aux images et aux images de conditionnement.

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

Dans la fonction [`main()`](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L770), le T2I-Adapter est soit chargé à partir d'un adaptateur pré-entraîné, soit initialisé aléatoirement :

```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",
    )
```

L'[optimizer](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L952) est initialisé pour les paramètres de 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,
)
```

Enfin, dans la [boucle d’entraînement](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L1086), l’image de conditionnement de l’adaptateur et les embeddings de texte sont transmis au UNet pour prédire le résidu de bruit :

```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
```

Si vous souhaitez en savoir plus sur le fonctionnement de la boucle d’entraînement, consultez le tutoriel [Comprendre les pipelines, les modèles et les planificateurs](../using-diffusers/write_own_pipeline), qui détaille le schéma de base du processus de débruitage.

## Lancer le script

Vous êtes maintenant prêt à lancer le script d'entraînement ! 🚀

Pour cet exemple d’entraînement, vous utiliserez le jeu de données [fusing/fill50k](https://huggingface.co/datasets/fusing/fill50k). 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_DIR` sur un identifiant de modèle du Hub ou un chemin vers un modèle local, et `OUTPUT_DIR` sur l’emplacement où vous souhaitez enregistrer le modèle.

Téléchargez les images suivantes pour conditionner votre entraînement avec :

```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
```

> [!TIP]
> Pour suivre la progression de l'entraînement avec Weights & Biases, ajoutez le paramètre `--report_to=wandb` à la commande d'entraînement. Vous devez également ajouter `--validation_image`, `--validation_prompt` et `--validation_steps` à la commande d'entraînement pour suivre les résultats. Cela peut s'avérer très utile pour déboguer le modèle et consulter les résultats intermédiaires.

```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
```

Une fois l’entraînement terminé, vous pouvez utiliser votre T2I-Adapter pour l’inférence :

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

adapter = T2IAdapter.from_pretrained("path/to/adapter", dtype=torch.float16)
pipeline = StableDiffusionXLAdapterPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", adapter=adapter, 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")
```

## Étapes suivantes

Félicitations pour l'entraînement d'un modèle T2I-Adapter ! 🎉 Pour en savoir plus :

- Lisez le billet de blog [Efficient Controllable Generation for SDXL with T2I-Adapters](https://huggingface.co/blog/t2i-sdxl-adapters) pour en savoir plus sur les résultats expérimentaux de l'équipe T2I-Adapter.

