Buckets:

hf-doc-build/doc / diffusers /main /es /training /instructpix2pix.md
mishig's picture
|
download
raw
13.5 kB

InstructPix2Pix

InstructPix2Pix es un modelo de Stable Diffusion entrenado para editar imágenes a partir de instrucciones proporcionadas por humanos. Por ejemplo, tu indicación puede ser "turn the clouds rainy" y el modelo editará la imagen de entrada en consecuencia. Este modelo se condiciona en la indicación de texto (o instrucción de edición) y la imagen de entrada.

Esta guía explorará el script de entrenamiento train_instruct_pix2pix.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:

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:

cd examples/instruct_pix2pix
pip install -r requirements.txt

🤗 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 de 🤗 Accelerate para saber más.

Inicializa un entorno de 🤗 Accelerate:

accelerate config

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

accelerate config default

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

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 para aprender a crear un conjunto de datos que funcione con el script de entrenamiento.

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 e informarnos si tienes alguna pregunta o inquietud.

Parámetros del script

El script de entrenamiento tiene 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(). Se proporcionan valores predeterminados para la mayoría de los parámetros que funcionan bastante bien, pero también puedes establecer tus propios valores en el comando de entrenamiento si lo deseas.

Por ejemplo, para aumentar la resolución de la imagen de entrada:

accelerate launch train_instruct_pix2pix.py \
  --resolution=512 \

Muchos de los parámetros básicos e importantes se describen en la guía de entrenamiento de Texto a imagen, por lo que esta guía se centra solo en los parámetros relevantes para InstructPix2Pix:

  • --original_image_column: la imagen original antes de que se realicen las ediciones
  • --edited_image_column: la imagen después de que se realicen las ediciones
  • --edit_prompt_column: las instrucciones para editar la imagen
  • --conditioning_dropout_prob: la probabilidad de dropout para la imagen editada y los prompts de edición durante el entrenamiento, que habilita la guía libre de clasificador (CFG) para uno o ambos inputs de condicionamiento

Script de entrenamiento

El código de preprocesamiento del conjunto de datos y el bucle de entrenamiento se encuentran en la función main(). Aquí es donde realizarás los cambios en el script de entrenamiento para adaptarlo a tu caso de uso.

Al igual que con los parámetros del script, se proporciona un recorrido por el script de entrenamiento en la guía de entrenamiento Text-to-image. En su lugar, esta guía examina las partes del script relevantes para InstructPix2Pix.

El script comienza modificando el número de canales de entrada en la primera capa convolucional del UNet para tener en cuenta la imagen de condicionamiento adicional de InstructPix2Pix:

in_channels = 8
out_channels = unet.conv_in.out_channels
unet.register_to_config(in_channels=in_channels)

with torch.no_grad():
    new_conv_in = nn.Conv2d(
        in_channels, out_channels, unet.conv_in.kernel_size, unet.conv_in.stride, unet.conv_in.padding
    )
    new_conv_in.weight.zero_()
    new_conv_in.weight[:, :4, :, :].copy_(unet.conv_in.weight)
    unet.conv_in = new_conv_in

Estos parámetros de UNet se actualizan por el optimizador:

optimizer = optimizer_cls(
    unet.parameters(),
    lr=args.learning_rate,
    betas=(args.adam_beta1, args.adam_beta2),
    weight_decay=args.adam_weight_decay,
    eps=args.adam_epsilon,
)

A continuación, las imágenes editadas y las instrucciones de edición se preprocesan y se tokenizan. Es importante que se apliquen las mismas transformaciones de imagen a las imágenes originales y a las editadas.

def preprocess_train(examples):
    preprocessed_images = preprocess_images(examples)

    original_images, edited_images = preprocessed_images.chunk(2)
    original_images = original_images.reshape(-1, 3, args.resolution, args.resolution)
    edited_images = edited_images.reshape(-1, 3, args.resolution, args.resolution)

    examples["original_pixel_values"] = original_images
    examples["edited_pixel_values"] = edited_images

    captions = list(examples[edit_prompt_column])
    examples["input_ids"] = tokenize_captions(captions)
    return examples

Por último, en el bucle de entrenamiento, comienza codificando las imágenes editadas en el espacio latente:

latents = vae.encode(batch["edited_pixel_values"].to(weight_dtype)).latent_dist.sample()
latents = latents * vae.config.scaling_factor

Luego, el script aplica dropout a los embeddings de la imagen original y de la instrucción de edición para soportar CFG. Esto es lo que permite al modelo modular la influencia de la instrucción de edición y de la imagen original sobre la imagen editada.

encoder_hidden_states = text_encoder(batch["input_ids"])[0]
original_image_embeds = vae.encode(batch["original_pixel_values"].to(weight_dtype)).latent_dist.mode()

if args.conditioning_dropout_prob is not None:
    random_p = torch.rand(bsz, device=latents.device, generator=generator)
    prompt_mask = random_p < 2 * args.conditioning_dropout_prob
    prompt_mask = prompt_mask.reshape(bsz, 1, 1)
    null_conditioning = text_encoder(tokenize_captions([""]).to(accelerator.device))[0]
    encoder_hidden_states = torch.where(prompt_mask, null_conditioning, encoder_hidden_states)

    image_mask_dtype = original_image_embeds.dtype
    image_mask = 1 - (
        (random_p >= args.conditioning_dropout_prob).to(image_mask_dtype)
        * (random_p < 3 * args.conditioning_dropout_prob).to(image_mask_dtype)
    )
    image_mask = image_mask.reshape(bsz, 1, 1, 1)
    original_image_embeds = image_mask * original_image_embeds

¡Eso es prácticamente todo! Aparte de las diferencias descritas aquí, el resto del script es muy similar al script de entrenamiento Text-to-image, así que no dudes en consultarlo para obtener más detalles. Si quieres aprender más sobre cómo funciona el bucle de entrenamiento, consulta el tutorial Understanding pipelines, models and schedulers, que desglosa el patrón básico del proceso de desruido.

Ejecutar el script

Una vez que estés satisfecho con los cambios en tu script o si la configuración predeterminada te parece adecuada, ¡estás listo para lanzar el script de entrenamiento! 🚀

Esta guía utiliza el conjunto de datos fusing/instructpix2pix-1000-samples, que es una versión más pequeña del conjunto de datos original. También puedes crear y utilizar tu propio conjunto de datos si lo deseas (consulta la guía Crear un conjunto de datos para el entrenamiento).

Establezca la variable de entorno MODEL_NAME con el nombre del modelo (puede ser un id de modelo en el Hub o una ruta a un modelo local) y la variable DATASET_ID con el nombre del conjunto de datos en el Hub. El script crea y guarda todos los componentes (extractor de características, programador, codificador de texto, UNet, etc.) en una subcarpeta de su repositorio.

Para obtener mejores resultados, pruebe con ejecuciones de entrenamiento más largas y un conjunto de datos más grande. Solo hemos probado este script de entrenamiento con un conjunto de datos a menor escala.

Para monitorear el progreso del entrenamiento con Weights and Biases, añade el parámetro --report_to=wandb al comando de entrenamiento y especifica una imagen de validación con --val_image_url y un prompt de validación con --validation_prompt. Esto puede ser muy útil para depurar el modelo.

Si estás entrenando en más de una GPU, añade el parámetro --multi_gpu al comando accelerate launch.

accelerate launch --mixed_precision="fp16" train_instruct_pix2pix.py \
    --pretrained_model_name_or_path=$MODEL_NAME \
    --dataset_name=$DATASET_ID \
    --enable_xformers_memory_efficient_attention \
    --resolution=256 \
    --random_flip \
    --train_batch_size=4 \
    --gradient_accumulation_steps=4 \
    --gradient_checkpointing \
    --max_train_steps=15000 \
    --checkpointing_steps=5000 \
    --checkpoints_total_limit=1 \
    --learning_rate=5e-05 \
    --max_grad_norm=1 \
    --lr_warmup_steps=0 \
    --conditioning_dropout_prob=0.05 \
    --mixed_precision=fp16 \
    --seed=42 \
    --push_to_hub

Cuando el entrenamiento ha terminado, puedes usar tu nuevo InstructPix2Pix para la inferencia:

import PIL
import requests
import torch
from diffusers import StableDiffusionInstructPix2PixPipeline
from diffusers.utils import load_image

pipeline = StableDiffusionInstructPix2PixPipeline.from_pretrained("your_cool_model", dtype=torch.float16).to("cuda")  # or "mps", "xpu", "cpu"
generator = torch.Generator("cuda").manual_seed(0)

image = load_image("https://huggingface.co/datasets/sayakpaul/sample-datasets/resolve/main/test_pix2pix_4.png")
prompt = "add some ducks to the lake"
num_inference_steps = 20
image_guidance_scale = 1.5
guidance_scale = 10

edited_image = pipeline(
   prompt,
   image=image,
   num_inference_steps=num_inference_steps,
   image_guidance_scale=image_guidance_scale,
   guidance_scale=guidance_scale,
   generator=generator,
).images[0]
edited_image.save("edited_image.png")

Deberías experimentar con diferentes valores de num_inference_steps, image_guidance_scale y guidance_scale para ver cómo afectan a la velocidad y la calidad de la inferencia. Los parámetros de escala de guía son especialmente impactantes porque controlan cuánto afectan la imagen original y las instrucciones de edición a la imagen editada.

Stable Diffusion XL

Stable Diffusion XL (SDXL) es un potente modelo de texto a imagen que genera imágenes de alta resolución y añade un segundo codificador de texto a su arquitectura. Utilice el script train_instruct_pix2pix_sdxl.py para entrenar un modelo SDXL para que siga instrucciones de edición de imágenes.

El script de entrenamiento de SDXL se describe con más detalle en la guía de entrenamiento de SDXL.

Próximos pasos

¡Felicidades por entrenar tu propio modelo InstructPix2Pix! 🥳 Para aprender más sobre el modelo, puede ser útil:

Xet Storage Details

Size:
13.5 kB
·
Xet hash:
88ce1f2777b6d949946ac5c4991c0ffb4cf07db094bf2730293ea18f8f87c5e9

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