Ejecutando IF con difusores 馃Ж en un Google Colab de nivel gratuito

Ejecutando IF con difusores en Google Colab gratis.

TL;DR: Mostramos c贸mo ejecutar uno de los modelos de texto a imagen de c贸digo abierto m谩s potentes, IF, en un Google Colab de nivel gratuito con 馃Ж difusores.

Tambi茅n puedes explorar las capacidades del modelo directamente en el Espacio de Hugging Face.

Imagen comprimida del repositorio oficial de IF en GitHub.

Introducci贸n

IF es un modelo de generaci贸n de im谩genes a partir de texto basado en p铆xeles y fue lanzado a fines de abril de 2023 por DeepFloyd. La arquitectura del modelo est谩 fuertemente inspirada en Imagen, propiedad de Google y no accesible al p煤blico.

IF tiene dos ventajas distintas en comparaci贸n con los modelos existentes de texto a imagen como Stable Diffusion:

  • El modelo opera directamente en “espacio de p铆xeles” (es decir, en im谩genes sin comprimir) en lugar de ejecutar el proceso de eliminaci贸n de ruido en el espacio latente, como hace Stable Diffusion.
  • El modelo se entrena en salidas de T5-XXL, un codificador de texto m谩s potente que CLIP, utilizado por Stable Diffusion como codificador de texto.

Como resultado, IF es mejor para generar im谩genes con detalles de alta frecuencia (por ejemplo, rostros y manos humanas) y es el primer modelo de generaci贸n de im谩genes de c贸digo abierto que puede generar im谩genes de manera confiable con texto.

La desventaja de operar en el espacio de p铆xeles y utilizar un codificador de texto m谩s potente es que IF tiene una cantidad significativamente mayor de par谩metros. T5, el UNet de texto a imagen de IF y el UNet de escalado de IF tienen 4.5B, 4.3B y 1.2B de par谩metros, respectivamente. En comparaci贸n, el codificador de texto y el UNet de Stable Diffusion 2.1 tienen solo 400M y 900M de par谩metros, respectivamente.

No obstante, es posible ejecutar IF en hardware para consumidores si se optimiza el modelo para un uso de memoria reducido. Mostraremos c贸mo hacer esto con 馃Ж difusores en esta publicaci贸n del blog.

En 1.), explicamos c贸mo utilizar IF para la generaci贸n de im谩genes a partir de texto, y en 2.) y 3.), repasamos las capacidades de variaci贸n de imagen y relleno de imagen de IF.

馃挕 Nota: Estamos sacrificando ganancias en memoria por ganancias en velocidad aqu铆 para poder ejecutar IF en un Google Colab de nivel gratuito. Si tienes acceso a GPUs de alta gama como una A100, recomendamos dejar todos los componentes del modelo en la GPU para obtener la m谩xima velocidad, como se hace en la demostraci贸n oficial de IF.

馃挕 Nota: Algunas de las im谩genes m谩s grandes se han comprimido para cargar m谩s r谩pido en el formato del blog. 隆Cuando uses el modelo oficial, deber铆an tener una calidad a煤n mejor!

隆Vamos a sumergirnos 馃殌!

Capacidades de generaci贸n de texto de IF

Tabla de contenidos

  • Aceptaci贸n de la licencia
  • Optimizaci贸n de IF para ejecutarse en hardware con restricciones de memoria
  • Recursos disponibles
  • Instalaci贸n de dependencias
  • Generaci贸n de im谩genes a partir de texto
  • Variaci贸n de imagen
  • Relleno de imagen

Aceptaci贸n de la licencia

Antes de poder utilizar IF, debes aceptar sus condiciones de uso. Para hacerlo:

    1. Aseg煤rate de tener una cuenta de Hugging Face y haber iniciado sesi贸n
    1. Acepta la licencia en la tarjeta de modelo de DeepFloyd/IF-I-XL-v1.0. Aceptar la licencia en la tarjeta del modelo de la etapa I aceptar谩 autom谩ticamente para los otros modelos de IF.
    1. Aseg煤rate de haber iniciado sesi贸n localmente. Instala huggingface_hub
pip install huggingface_hub --upgrade

ejecuta la funci贸n de inicio de sesi贸n en una consola de Python

from huggingface_hub import login

login()

y ingresa tu token de acceso de Hugging Face Hub.

Optimizaci贸n de IF para ejecutarse en hardware con restricciones de memoria

El aprendizaje autom谩tico de 煤ltima generaci贸n no deber铆a estar solo en manos de unos pocos 茅lites. Democratizar el aprendizaje autom谩tico significa poner modelos disponibles para ejecutarse en algo m谩s que el hardware m谩s avanzado y mejor.

La comunidad de aprendizaje profundo ha creado herramientas de clase mundial para ejecutar modelos intensivos en recursos en hardware de consumo:

  • 馃 accelerate proporciona utilidades para trabajar con modelos grandes.
  • bitsandbytes pone a disposici贸n la cuantificaci贸n de 8 bits para todos los modelos de PyTorch.
  • 馃 safetensors no solo asegura que se ejecute el c贸digo guardado, sino que tambi茅n acelera significativamente el tiempo de carga de modelos grandes.

Diffusers integra de forma transparente las bibliotecas anteriores para permitir una API sencilla al optimizar modelos grandes.

La versi贸n gratuita de Google Colab tiene restricciones tanto en la CPU RAM (13 GB de RAM) como en la GPU VRAM (15 GB de RAM para T4), lo que dificulta la ejecuci贸n del modelo completo de m谩s de 10 mil millones.

Veamos el tama帽o de los componentes del modelo IF en precisi贸n float32 completa:

  • T5-XXL Text Encoder: 20 GB
  • Stage 1 UNet: 17.2 GB
  • Stage 2 Super Resolution UNet: 2.5 GB
  • Stage 3 Super Resolution Model: 3.4 GB

No hay forma de ejecutar el modelo en float32 ya que los pesos de T5 y Stage 1 UNet son cada uno m谩s grandes que la RAM de la CPU disponible.

En float16, los tama帽os de los componentes son 11 GB, 8.6 GB y 1.25 GB para T5, Stage1 y Stage2 UNets, respectivamente, lo cual es factible para la GPU, pero a煤n nos encontramos con errores de desbordamiento de memoria de la CPU al cargar el T5 (alguna CPU est谩 ocupada por otros procesos).

Por lo tanto, reducimos a煤n m谩s la precisi贸n de T5 utilizando la cuantificaci贸n de 8 bits de bitsandbytes, lo que permite guardar el punto de control de T5 con tan solo 8 GB.

Ahora que cada componente encaja individualmente tanto en la memoria de la CPU como en la de la GPU, debemos asegurarnos de que los componentes tengan toda la memoria de la CPU y la GPU para s铆 mismos cuando sea necesario.

Diffusers admite la carga modular de componentes individuales, es decir, podemos cargar el codificador de texto sin cargar la UNet. Esta carga modular garantizar谩 que solo carguemos el componente que necesitamos en un paso dado en el flujo de trabajo para evitar agotar la RAM de la CPU y la VRAM de la GPU disponibles.

Prob茅moslo 馃殌

Recursos disponibles

La versi贸n gratuita de Google Colab viene con aproximadamente 13 GB de RAM de la CPU:

!grep MemTotal /proc/meminfo

MemTotal:       13297192 kB

Y una NVIDIA T4 con 15 GB de VRAM:

!nvidia-smi

Sun Apr 23 23:14:19 2023       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.85.12    Driver Version: 525.85.12    CUDA Version: 12.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla T4            Off  | 00000000:00:04.0 Off |                    0 |
| N/A   72C    P0    32W /  70W |   1335MiB / 15360MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                                
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+

Instalar dependencias

Algunas optimizaciones pueden requerir versiones actualizadas de las dependencias. Si tienes problemas, por favor verifica y actualiza las versiones.

! pip install --upgrade \
  diffusers~=0.16 \
  transformers~=4.28 \
  safetensors~=0.3 \
  sentencepiece~=0.1 \
  accelerate~=0.18 \
  bitsandbytes~=0.38 \
  torch~=2.0 -q

1. Generaci贸n de texto a imagen

Recorreremos paso a paso la generaci贸n de texto a imagen con IF utilizando Diffusers. Explicaremos brevemente las APIs y las optimizaciones, pero se pueden encontrar explicaciones m谩s detalladas en la documentaci贸n oficial de Diffusers, Transformers, Accelerate y bitsandbytes.

1.1 Cargar el codificador de texto

Cargaremos T5 utilizando una cuantizaci贸n de 8 bits. Transformers admite directamente bitsandbytes a trav茅s de la bandera load_in_8bit.

La bandera variant="8bit" descargar谩 pesos pre-cuantizados.

Tambi茅n usaremos la bandera device_map para permitir que transformers transfiera capas del modelo a la CPU o al disco. Transformers big modeling admite mapas de dispositivos arbitrarios, que se pueden utilizar para cargar par谩metros del modelo por separado directamente en los dispositivos disponibles. Pasar "auto" crear谩 autom谩ticamente un mapa de dispositivos. Consulta la documentaci贸n de transformers para obtener m谩s informaci贸n.

from transformers import T5EncoderModel

text_encoder = T5EncoderModel.from_pretrained(
    "DeepFloyd/IF-I-XL-v1.0",
    subfolder="text_encoder", 
    device_map="auto", 
    load_in_8bit=True, 
    variant="8bit"
)

1.2 Crear embeddings de texto

La API de Diffusers para acceder a modelos de difusi贸n es la clase DiffusionPipeline y sus subclases. Cada instancia de DiffusionPipeline es un conjunto completamente autocontenido de m茅todos y modelos para ejecutar redes de difusi贸n. Podemos anular los modelos que utiliza pasando instancias alternativas como argumentos de palabra clave a from_pretrained.

En este caso, pasamos None para el argumento unet, por lo que no se cargar谩 ninguna UNet. Esto nos permite ejecutar la parte de incrustaci贸n de texto del proceso de difusi贸n sin cargar la UNet en la memoria.

from diffusers import DiffusionPipeline

pipe = DiffusionPipeline.from_pretrained(
    "DeepFloyd/IF-I-XL-v1.0", 
    text_encoder=text_encoder, # pasamos el codificador de texto de 8 bits previamente instanciado
    unet=None, 
    device_map="auto"
)

IF tambi茅n viene con un pipeline de super resoluci贸n. Guardaremos los embeddings de la consulta para poder pasarlos directamente al pipeline de super resoluci贸n m谩s adelante. Esto permitir谩 que el pipeline de super resoluci贸n se cargue sin un codificador de texto.

En lugar de que un astronauta simplemente monte un caballo, 隆tambi茅n le daremos un cartel!

Definamos una consulta adecuada:

prompt = "una fotograf铆a de un astronauta montando un caballo sosteniendo un cartel que dice Pixel en el espacio"

y ejecut茅moslo a trav茅s del modelo T5 cuantizado de 8 bits:

prompt_embeds, negative_embeds = pipe.encode_prompt(prompt)

1.3 Liberar memoria

Una vez que se hayan creado los embeddings de la consulta, ya no necesitaremos el codificador de texto. Sin embargo, todav铆a est谩 en la memoria de la GPU. Necesitamos eliminarlo para poder cargar la UNet.

No es trivial liberar la memoria de PyTorch. Debemos recolectar basura de los objetos de Python que apuntan a la memoria asignada real en la GPU.

Primero, utiliza la palabra clave de Python del para eliminar todos los objetos de Python que hacen referencia a la memoria asignada en la GPU.

del text_encoder
del pipe

Eliminar el objeto de Python no es suficiente para liberar la memoria de la GPU. La recolecci贸n de basura es cuando se libera la memoria de la GPU.

Adem谩s, llamaremos a torch.cuda.empty_cache(). Este m茅todo no es estrictamente necesario, ya que la memoria cach茅 de CUDA se liberar谩 inmediatamente para asignaciones posteriores. Vaciar la cach茅 nos permite verificar en la interfaz de Colab que la memoria est谩 disponible.

Usaremos una funci贸n auxiliar flush() para vaciar la memoria.

import gc
import torch

def flush():
    gc.collect()
    torch.cuda.empty_cache()

y ejecut茅moslo

flush()

1.4 Etapa 1: El proceso principal de difusi贸n

Con nuestra memoria de GPU ahora disponible, podemos volver a cargar el DiffusionPipeline solo con el UNet para ejecutar el proceso de difusi贸n principal.

Las banderas variant y torch_dtype se utilizan por los difusores para descargar y cargar los pesos en formato de punto flotante de 16 bits.

pipe = DiffusionPipeline.from_pretrained(
    "DeepFloyd/IF-I-XL-v1.0", 
    text_encoder=None, 
    variant="fp16", 
    torch_dtype=torch.float16, 
    device_map="auto"
)

A menudo, pasamos directamente la indicaci贸n de texto a DiffusionPipeline.__call__. Sin embargo, previamente calculamos nuestras incrustaciones de texto que podemos pasar en su lugar.

IF tambi茅n viene con un proceso de difusi贸n de s煤per resoluci贸n. Configurando output_type="pt" se devolver谩n tensores de PyTorch en bruto en lugar de una imagen PIL. De esta manera, podemos mantener los tensores de PyTorch en la GPU y pasarlos directamente al pipeline de s煤per resoluci贸n de la etapa 2.

Definamos un generador aleatorio y ejecutemos el proceso de difusi贸n de la etapa 1.

generator = torch.Generator().manual_seed(1)
image = pipe(
    prompt_embeds=prompt_embeds,
    negative_prompt_embeds=negative_embeds, 
    output_type="pt",
    generator=generator,
).images

Conviertamos manualmente los tensores en bruto a PIL y echemos un vistazo al resultado final. La salida de la etapa 1 es una imagen de 64×64.

from diffusers.utils import pt_to_pil

pil_image = pt_to_pil(image)
pipe.watermarker.apply_watermark(pil_image, pipe.unet.config.sample_size)

pil_image[0]

Y de nuevo, eliminamos el puntero de Python y liberamos la memoria de la CPU y la GPU:

del pipe
flush()

1.5 Etapa 2: Super Resoluci贸n de 64×64 a 256×256

IF viene con un proceso de difusi贸n separado para el aumento de resoluci贸n.

Ejecutamos cada proceso de difusi贸n con un pipeline separado.

El pipeline de s煤per resoluci贸n puede cargarse con un codificador de texto si es necesario. Sin embargo, normalmente tendremos incrustaciones de texto precalculadas del primer pipeline de IF. Si es as铆, cargue el pipeline sin el codificador de texto.

Creamos el pipeline

pipe = DiffusionPipeline.from_pretrained(
    "DeepFloyd/IF-II-L-v1.0", 
    text_encoder=None, # sin uso de codificador de texto => 隆ahorro de memoria!
    variant="fp16", 
    torch_dtype=torch.float16, 
    device_map="auto"
)

y lo ejecutamos, reutilizando las incrustaciones de texto precalculadas

image = pipe(
    image=image, 
    prompt_embeds=prompt_embeds, 
    negative_prompt_embeds=negative_embeds, 
    output_type="pt",
    generator=generator,
).images

Nuevamente, podemos inspeccionar los resultados intermedios.

pil_image = pt_to_pil(image)
pipe.watermarker.apply_watermark(pil_image, pipe.unet.config.sample_size)

pil_image[0]

Y de nuevo, eliminamos el puntero de Python y liberamos la memoria

del pipe
flush()

1.6 Etapa 3: Super Resoluci贸n de 256×256 a 1024×1024

El segundo modelo de s煤per resoluci贸n para IF es el Upscaler x4 de Stability AI previamente lanzado.

Creemos el pipeline y c谩rguelo directamente en la GPU con device_map="auto".

pipe = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-x4-upscaler", 
    torch_dtype=torch.float16, 
    device_map="auto"
)

馃Ж diffusers permite componer f谩cilmente modelos de difusi贸n desarrollados independientemente, ya que los pipelines se pueden encadenar. Aqu铆 simplemente podemos tomar la salida anterior de tensor de PyTorch y pasarla al pipeline de la etapa 3 como image=image.

馃挕 Nota: El x4 Upscaler no utiliza T5 y tiene su propio codificador de texto. Por lo tanto, no podemos usar los embeddings de la solicitud previamente creados y en su lugar debemos pasar la solicitud original.

pil_image = pipe(prompt, generator=generator, image=image).images

A diferencia de los pipelines IF, la marca de agua IF no se agregar谩 autom谩ticamente a las salidas del pipeline de escalado x4 de difusi贸n estable.

En su lugar, podemos aplicar manualmente la marca de agua.

from diffusers.pipelines.deepfloyd_if import IFWatermarker

watermarker = IFWatermarker.from_pretrained("DeepFloyd/IF-I-XL-v1.0", subfolder="watermarker")
watermarker.apply_watermark(pil_image, pipe.unet.config.sample_size)

Ver imagen de salida

pil_image[0]

隆Et voil脿! Una hermosa imagen de 1024×1024 en un Google Colab de nivel gratuito.

Hemos mostrado c贸mo 馃Ж diffusers facilita la descomposici贸n y carga modular de modelos de difusi贸n intensivos en recursos.

馃挕 Nota: No recomendamos utilizar la configuraci贸n anterior en producci贸n. La cuantizaci贸n de 8 bits, la desasignaci贸n manual de los pesos del modelo y la descarga en disco sacrifican memoria por tiempo (es decir, velocidad de inferencia). Esto puede ser especialmente notable si se reutiliza el pipeline de difusi贸n. En producci贸n, recomendamos utilizar una A100 de 40 GB con todos los componentes del modelo dejados en la GPU. Consulte la demo oficial de IF.

2. Variaci贸n de imagen

Los mismos checkpoints de IF tambi茅n se pueden utilizar para la variaci贸n de imagen guiada por texto y el rellenado. El proceso de difusi贸n central es el mismo que la generaci贸n de texto a imagen, excepto que la imagen inicial con ruido se crea a partir de la imagen que se va a variar o rellenar.

Para ejecutar la variaci贸n de imagen, cargue los mismos checkpoints con IFImg2ImgPipeline.from_pretrained() y IFImg2ImgSuperResolution.from_pretrained().

隆Las APIs de optimizaci贸n de memoria son todas las mismas!

Liberemos la memoria de la secci贸n anterior.

del pipe
flush()

Para la variaci贸n de imagen, comenzamos con una imagen inicial que queremos adaptar.

Para esta secci贸n, adaptaremos el famoso meme “Slaps Roof of Car”. Descargu茅moslo de internet.

import requests

url = "https://i.kym-cdn.com/entries/icons/original/000/026/561/car.jpg"
response = requests.get(url)

y cargu茅moslo en una imagen PIL

from PIL import Image
from io import BytesIO

original_image = Image.open(BytesIO(response.content)).convert("RGB")
original_image = original_image.resize((768, 512))
original_image

El pipeline de variaci贸n de imagen acepta tanto im谩genes PIL como tensores en bruto. Consulte las cadenas de documentaci贸n para obtener m谩s informaci贸n detallada sobre las entradas esperadas, aqu铆 .

2.1 Codificador de texto

La variaci贸n de imagen est谩 guiada por texto, por lo que podemos definir una solicitud y codificarla con el codificador de texto de T5.

Nuevamente, cargamos el codificador de texto en una precisi贸n de 8 bits.

from transformers import T5EncoderModel

text_encoder = T5EncoderModel.from_pretrained(
    "DeepFloyd/IF-I-XL-v1.0",
    subfolder="text_encoder",
    device_map="auto",
    load_in_8bit=True,
    variant="8bit"
)

Para la variaci贸n de imagen, cargamos el checkpoint con IFImg2ImgPipeline. Al usar DiffusionPipeline.from_pretrained(...), los checkpoints se cargan en su pipeline predeterminado. El pipeline predeterminado para el IF es el pipeline de texto a imagen IFPipeline. Cuando se cargan checkpoints con un pipeline que no es el predeterminado, el pipeline debe especificarse expl铆citamente.

from diffusers import IFImg2ImgPipeline

pipe = IFImg2ImgPipeline.from_pretrained(
    "DeepFloyd/IF-I-XL-v1.0",
    text_encoder=text_encoder,
    unet=None,
    device_map="auto"
)

Vamos a convertir a nuestro vendedor en un personaje de anime.

prompt = "estilo de anime"

Como antes, creamos los embeddings de texto con T5

prompt_embeds, negative_embeds = pipe.encode_prompt(prompt)

y liberamos la memoria de la GPU y la CPU.

Primero, eliminamos los punteros de Python

del text_encoder
del pipe

y luego liberamos la memoria

flush()

2.2 Etapa 1: El proceso de difusi贸n principal

A continuaci贸n, cargamos solo los pesos de la etapa 1 de UNet en el objeto de la canalizaci贸n, como lo hicimos en la secci贸n anterior.

pipe = IFImg2ImgPipeline.from_pretrained(
    "DeepFloyd/IF-I-XL-v1.0", 
    text_encoder=None, 
    variant="fp16", 
    torch_dtype=torch.float16, 
    device_map="auto"
)

La canalizaci贸n de variaci贸n de imagen requiere tanto la imagen original como los embeddings de texto.

Opcionalmente, podemos usar el argumento strength para configurar la cantidad de variaci贸n. strength controla directamente la cantidad de ruido agregado. Mayor strength significa m谩s ruido, lo que significa m谩s variaci贸n.

generator = torch.Generator().manual_seed(0)
image = pipe(
    image=original_image,
    prompt_embeds=prompt_embeds,
    negative_prompt_embeds=negative_embeds, 
    output_type="pt",
    generator=generator,
).images

Veamos de nuevo el intermedio 64×64.

pil_image = pt_to_pil(image)
pipe.watermarker.apply_watermark(pil_image, pipe.unet.config.sample_size)

pil_image[0]

隆Se ve bien! Podemos liberar la memoria y volver a escalar la imagen.

del pipe
flush()

2.3 Etapa 2: Super Resoluci贸n

Para la super resoluci贸n, cargamos el punto de control con IFImg2ImgSuperResolutionPipeline y el mismo punto de control que antes.

from diffusers import IFImg2ImgSuperResolutionPipeline

pipe = IFImg2ImgSuperResolutionPipeline.from_pretrained(
    "DeepFloyd/IF-II-L-v1.0", 
    text_encoder=None, 
    variant="fp16", 
    torch_dtype=torch.float16, 
    device_map="auto"
)

馃挕 Nota: La canalizaci贸n de super resoluci贸n de variaci贸n de imagen requiere la imagen generada y la imagen original.

Tambi茅n puedes usar el escalador de difusi贸n estable x4 en esta imagen. Si茅ntete libre de probarlo usando los fragmentos de c贸digo en la secci贸n 1.6.

image = pipe(
    image=image,
    original_image=original_image,
    prompt_embeds=prompt_embeds,
    negative_prompt_embeds=negative_embeds, 
    generator=generator,
).images[0]
image

隆Genial! Liberemos la memoria y veamos las canalizaciones de rellenado finales.

del pipe
flush()

3. Rellenado

La canalizaci贸n de rellenado de IF es similar a la variaci贸n de imagen, excepto que solo se desenruida una 谩rea selecta de la imagen.

Especificamos el 谩rea a rellenar con una m谩scara de imagen.

Vamos a mostrar las incre铆bles capacidades de “generaci贸n de letras” de IF. Podemos reemplazar este texto de letrero con un eslogan diferente.

Primero, descarguemos la imagen

import requests

url = "https://i.imgflip.com/5j6x75.jpg"
response = requests.get(url)

y convirt谩mosla en una imagen de PIL

from PIL import Image
from io import BytesIO

original_image = Image.open(BytesIO(response.content)).convert("RGB")
original_image = original_image.resize((512, 768))
original_image

Vamos a enmascarar la se帽al para poder reemplazar su texto.

Para mayor comodidad, hemos generado previamente la m谩scara y la hemos cargado en un conjunto de datos de HF.

Vamos a descargarla.

from huggingface_hub import hf_hub_download

mask_image = hf_hub_download("diffusers/docs-images", repo_type="dataset", filename="if/sign_man_mask.png")
mask_image = Image.open(mask_image)

mask_image

馃挕 Nota : Tambi茅n puedes crear m谩scaras manualmente creando una imagen en escala de grises.

from PIL import Image
import numpy as np

height = 64
width = 64

example_mask = np.zeros((height, width), dtype=np.int8)

# Establece los p铆xeles enmascarados en 255
example_mask[20:30, 30:40] = 255

# Aseg煤rate de crear la imagen en modo 'L'
# que significa un solo canal en escala de grises
example_mask = Image.fromarray(example_mask, mode='L')

example_mask

Ahora podemos comenzar el proceso de relleno de espacios en blanco 馃帹馃枌

3.1. Codificador de Texto

Nuevamente, primero cargamos el codificador de texto

from transformers import T5EncoderModel

text_encoder = T5EncoderModel.from_pretrained(
    "DeepFloyd/IF-I-XL-v1.0",
    subfolder="text_encoder", 
    device_map="auto", 
    load_in_8bit=True, 
    variant="8bit"
)

Esta vez, inicializamos la tuber铆a de relleno de espacios en blanco IFInpaintingPipeline con los pesos del codificador de texto.

from diffusers import IFInpaintingPipeline

pipe = IFInpaintingPipeline.from_pretrained(
    "DeepFloyd/IF-I-XL-v1.0", 
    text_encoder=text_encoder, 
    unet=None, 
    device_map="auto"
)

Listo, hagamos que el hombre promocione m谩s capas en su lugar.

prompt = 'el texto, "solo agrega m谩s capas"'

Una vez definido el texto, podemos crear los embeddings del texto de entrada

prompt_embeds, negative_embeds = pipe.encode_prompt(prompt)

Al igual que antes, liberamos la memoria

del text_encoder
del pipe
flush()

3.2 Etapa 1: El proceso principal de difusi贸n

Al igual que antes, ahora cargamos la tuber铆a de la etapa 1 solo con la UNet.

pipe = IFInpaintingPipeline.from_pretrained(
    "DeepFloyd/IF-I-XL-v1.0", 
    text_encoder=None, 
    variant="fp16", 
    torch_dtype=torch.float16, 
    device_map="auto"
)

Ahora, necesitamos pasar la imagen de entrada, la imagen de la m谩scara y los embeddings del texto de entrada.

image = pipe(
    image=original_image,
    mask_image=mask_image,
    prompt_embeds=prompt_embeds,
    negative_prompt_embeds=negative_embeds, 
    output_type="pt",
    generator=generator,
).images

Echemos un vistazo a la salida intermedia.

pil_image = pt_to_pil(image)
pipe.watermarker.apply_watermark(pil_image, pipe.unet.config.sample_size)

pil_image[0]

隆Se ve bien! El texto es bastante consistente.

Liberemos la memoria para poder ajustar la escala de la imagen

del pipe
flush()

3.3 Etapa 2: Super Resoluci贸n

Para la super resoluci贸n, carga el punto de control con IFInpaintingSuperResolutionPipeline.

from diffusers import IFInpaintingSuperResolutionPipeline

pipe = IFInpaintingSuperResolutionPipeline.from_pretrained(
    "DeepFloyd/IF-II-L-v1.0", 
    text_encoder=None, 
    variant="fp16", 
    torch_dtype=torch.float16, 
    device_map="auto"
)

El pipeline de super resoluci贸n de inpainting requiere la imagen generada, la imagen original, la imagen de la m谩scara y los embeddings de la consulta.

Vamos a realizar una 煤ltima ejecuci贸n de denoising.

image = pipe(
    image=image,
    original_image=original_image,
    mask_image=mask_image,
    prompt_embeds=prompt_embeds,
    negative_prompt_embeds=negative_embeds, 
    generator=generator,
).images[0]
image

隆Genial, el modelo gener贸 texto sin cometer ni un solo error de ortograf铆a!

Conclusi贸n

IF en precisi贸n de punto flotante de 32 bits utiliza un total de 40 GB de pesos. Mostramos c贸mo, utilizando solo modelos y bibliotecas de c贸digo abierto, IF se puede ejecutar en una instancia gratuita de Google Colab.

El ecosistema de ML se beneficia enormemente del intercambio de herramientas y modelos abiertos. En este cuaderno, se utilizaron modelos de DeepFloyd, StabilityAI y Google. Las bibliotecas utilizadas, como Diffusers, Transformers, Accelerate y bitsandbytes, se benefician de innumerables contribuyentes de diferentes organizaciones.

Un agradecimiento enorme al equipo de DeepFloyd por la creaci贸n y la liberaci贸n de IF, y por contribuir a la democratizaci贸n del buen aprendizaje autom谩tico 馃.

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Ciencia de Datos

La gu铆a de campo de datos sint茅ticos

Si quieres trabajar con datos, 驴cu谩les son tus opciones? Aqu铆 tienes una respuesta lo m谩s general posible podr铆as obt...

Inteligencia Artificial

AI Surge El CEO de Stability AI predice p茅rdidas de empleo para los desarrolladores indios en un plazo de 2 a帽os

A medida que la revoluci贸n de la IA se desarrolla, el mundo presencia tanto los posibles beneficios como las preocupa...

Inteligencia Artificial

驴Qu茅 es MLOps?' El resultado de la traducci贸n es

MLOps es un conjunto de m茅todos y t茅cnicas para implementar y mantener modelos de aprendizaje autom谩tico (ML) en prod...