Diffusers documentation

T2I-Adapter

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

T2I-Adapter

T2I-Adapter 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 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 :

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 :

cd examples/t2i_adapter
pip install -r requirements.txt

🤗 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 de 🤗 Accelerate pour en savoir plus.

Initialiser un environnement 🤗 Accelerate :

accelerate config

Pour configurer un environnement 🤗 Accelerate par défaut sans choisir de configuration :

accelerate config default

Sinon, si votre environnement ne prend pas en charge un shell interactif, comme un notebook, vous pouvez utiliser :

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 pour apprendre à créer un jeu de données compatible avec le script d'entraînement.

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 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(). 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 :

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, 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 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. 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 du prompt et l'application de transformations aux images et aux images de conditionnement.

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

Dans la fonction main(), le T2I-Adapter est soit chargé à partir d'un adaptateur pré-entraîné, soit initialisé aléatoirement :

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 est initialisé pour les paramètres de T2I-Adapter :

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, l’image de conditionnement de l’adaptateur et les embeddings de texte sont transmis au UNet pour prédire le résidu de bruit :

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, 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. 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).

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 :

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

Pour suivre la progression de l’entraînement avec Weights & Biases, ajoutez le paramètre --report_to=wandb à la commande d’entraînement. Vous devrez également ajouter --validation_image, --validation_prompt et --validation_steps à la commande d’entraînement afin de 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.

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 :

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 :

Update on GitHub