# T2I-Adapter

[T2I-Adapter](https://hf.co/papers/2302.08453) es un modelo de adaptador ligero que proporciona una imagen de entrada de condicionamiento adicional (line art, canny, sketch, depth, pose) para controlar mejor la generación de imágenes. Es similar a un ControlNet, pero es mucho más pequeño (~77M parámetros y ~300MB de tamaño de archivo) porque solo inserta pesos en el UNet en lugar de copiarlo y entrenarlo.

El T2I-Adapter solo está disponible para entrenar con el modelo Stable Diffusion XL (SDXL).

Esta guía explorará el script de entrenamiento [train_t2i_adapter_sdxl.py](https://github.com/huggingface/diffusers/blob/main/examples/t2i_adapter/train_t2i_adapter_sdxl.py) para que se familiarice con él y para que pueda adaptarlo a su propio caso de uso.

Antes de ejecutar el script, asegúrate de instalar la biblioteca desde el código fuente:

```bash
git clone https://github.com/huggingface/diffusers
cd diffusers
pip install .
```

Luego, navegue a la carpeta de ejemplo que contiene el script de entrenamiento e instale las dependencias requeridas para el script que está utilizando:

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

> [!TIP]
> 🤗 Accelerate es una biblioteca para ayudarte a entrenar en varias GPUs/TPUs o con precisión mixta. Configura automáticamente tu configuración de entrenamiento en función de tu hardware y entorno. Echa un vistazo al [Quick tour](https://huggingface.co/docs/accelerate/quicktour) de 🤗 Accelerate para saber más.

Inicializa un entorno de 🤗 Accelerate:

```bash
accelerate config
```

Para configurar un entorno predeterminado de 🤗 Accelerate sin elegir ninguna configuración:

```bash
accelerate config default
```

O si su entorno no admite una shell interactiva, como un notebook, puede usar:

```py
from accelerate.utils import write_basic_config

write_basic_config()
```

Por último, si deseas entrenar un modelo con tu propio conjunto de datos, consulta la guía [Crear un conjunto de datos para el entrenamiento](create_dataset) para aprender a crear un conjunto de datos que funcione con el script de entrenamiento.

> [!TIP]
> Las siguientes secciones resaltan las partes del script de entrenamiento que son importantes para entender cómo modificarlo, pero no abordan todos los aspectos del script en detalle. Si te interesa aprender más, no dudes en leer el [script](https://github.com/huggingface/diffusers/blob/main/examples/t2i_adapter/train_t2i_adapter_sdxl.py) e informarnos si tienes alguna pregunta o inquietud.

## Parámetros del script

El script de entrenamiento proporciona muchos parámetros para ayudarte a personalizar tu ejecución de entrenamiento. Todos los parámetros y sus descripciones se encuentran en la función [`parse_args()`](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L233). Proporciona valores predeterminados para cada parámetro, como el tamaño del lote de entrenamiento y la tasa de aprendizaje, pero también puedes establecer tus propios valores en el comando de entrenamiento si lo deseas.

Por ejemplo, para activar la acumulación de gradientes, añade el parámetro `--gradient_accumulation_steps` al comando de entrenamiento:

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

Muchos de los parámetros básicos e importantes se describen en la guía de entrenamiento de [Texto a imagen](text2image#script-parameters), por lo que esta guía se centra únicamente en los parámetros relevantes de T2I-Adapter:

- `--pretrained_vae_model_name_or_path`: ruta a un VAE preentrenado; se sabe que el VAE de SDXL sufre de inestabilidad numérica, por lo que este parámetro le permite especificar un [VAE](https://huggingface.co/madebyollin/sdxl-vae-fp16-fix) mejor
- `--crops_coords_top_left_h` y `--crops_coords_top_left_w`: coordenadas de altura y ancho para incluir en los embeddings de coordenadas de recorte de SDXL
- `--conditioning_image_column`: la columna de las imágenes de condicionamiento en el conjunto de datos
- `--proportion_empty_prompts`: la proporción de prompts de imagen que se reemplazarán con cadenas vacías

## Script de entrenamiento

Al igual que con los parámetros del script, se proporciona un recorrido por el script de entrenamiento en la guía de entrenamiento [Texto a imagen](text2image#training-script). En su lugar, esta guía examina las partes del script relevantes para T2I-Adapter.

El script de entrenamiento comienza preparando el conjunto de datos. Esto incluye [tokenizar](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L674) el prompt y [aplicar transformaciones](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L714) a las imágenes y a las imágenes de condicionamiento.

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

Dentro de la función [`main()`](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L770), el T2I-Adapter se carga desde un adaptador preentrenado o se inicializa aleatoriamente:

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

El [optimizer](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L952) se inicializa para los parámetros 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,
)
```

Por último, en el [bucle de entrenamiento](https://github.com/huggingface/diffusers/blob/aab6de22c33cc01fb7bc81c0807d6109e2c998c9/examples/t2i_adapter/train_t2i_adapter_sdxl.py#L1086), la imagen de condicionamiento del adaptador y los embeddings de texto se pasan a la UNet para predecir el residuo de ruido:

```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 quieres saber más sobre cómo funciona el bucle de entrenamiento, consulta el tutorial [Understanding pipelines, models and schedulers](../using-diffusers/write_own_pipeline), que desglosa el patrón básico del proceso de desruido.

## Ejecutar el script

¡Ahora estás listo para lanzar el script de entrenamiento! 🚀

Para este ejemplo de entrenamiento, usarás el conjunto de datos [fusing/fill50k](https://huggingface.co/datasets/fusing/fill50k). También puedes crear y usar tu propio conjunto de datos si lo deseas (consulta la guía [Create a dataset for training](create_dataset)).

Establezca la variable de entorno `MODEL_DIR` en un id de modelo del Hub o en una ruta a un modelo local y `OUTPUT_DIR` en el lugar donde desea guardar el modelo.

Descarga las siguientes imágenes para condicionar tu entrenamiento con:

```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]
> Para monitorear el progreso del entrenamiento con Weights & Biases, añade el parámetro `--report_to=wandb` al comando de entrenamiento. También debes añadir `--validation_image`, `--validation_prompt` y `--validation_steps` al comando de entrenamiento para llevar un registro de los resultados. Esto puede ser muy útil para depurar el modelo y ver resultados intermedios.

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

Una vez completado el entrenamiento, puedes usar tu T2I-Adapter para la inferencia:

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

## Próximos pasos

¡Felicidades por entrenar un modelo T2I-Adapter! 🎉 Para saber más:

- Lee la publicación de blog [Generación eficiente y controlable para SDXL con T2I-Adapters](https://huggingface.co/blog/t2i-sdxl-adapters) para conocer más detalles sobre los resultados experimentales del equipo de T2I-Adapter.

