Diffusers documentation

OmniGen

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.42.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

OmniGen

OmniGen: Unified Image Generation de BAAI, por Shitao Xiao, Yueze Wang, Junjie Zhou, Huaying Yuan, Xingrun Xing, Ruiran Yan, Chaofan Li, Shuting Wang, Tiejun Huang, Zheng Liu.

El resumen del artículo es:

El surgimiento de los Modelos de Lenguaje de Gran Escala (LLM) ha unificado las tareas de generación de lenguaje y ha revolucionado la interacción humano-máquina. Sin embargo, en el ámbito de la generación de imágenes, un modelo unificado capaz de manejar diversas tareas dentro de un único marco sigue siendo en gran medida inexplorado. En este trabajo, presentamos OmniGen, un nuevo modelo de difusión para la generación unificada de imágenes. OmniGen se caracteriza por las siguientes características: 1) Unificación: OmniGen no solo demuestra capacidades de generación de texto a imagen, sino que también admite de forma inherente diversas tareas descendentes, como la edición de imágenes, la generación dirigida por sujeto y la generación condicional visual. 2) Simplicidad: La arquitectura de OmniGen está altamente simplificada, eliminando la necesidad de complementos adicionales. Además, en comparación con los modelos de difusión existentes, es más fácil de usar y puede completar tareas complejas de extremo a extremo mediante instrucciones, sin la necesidad de pasos intermedios adicionales, simplificando en gran medida el flujo de trabajo de generación de imágenes. 3) Transferencia de conocimiento: Gracias al aprendizaje en un formato unificado, OmniGen transfiere de manera efectiva el conocimiento entre diferentes tareas, gestiona tareas y dominios no vistos y exhibe capacidades novedosas. También exploramos las capacidades de razonamiento del modelo y las aplicaciones potenciales del mecanismo de cadena de pensamiento. Este trabajo representa el primer intento de un modelo de generación de imágenes de uso general, y publicaremos nuestros recursos en https://github.com/VectorSpaceLab/OmniGen para fomentar avances futuros.

Asegúrate de consultar la guía de Schedulers para aprender a explorar el equilibrio entre la velocidad y la calidad del scheduler, y consulta la sección reutilizar componentes entre pipelines para aprender a cargar eficientemente los mismos componentes en múltiples pipelines.

Este pipeline fue aportado por staoxiao. La base de código original se puede encontrar aquí. Los pesos originales se pueden encontrar en hf.co/shitao.

Cargar puntos de control de modelos

Los pesos del modelo pueden estar almacenados en subcarpetas separadas en el Hub o localmente, en cuyo caso, debe utilizar el método from_pretrained().

import torch
from diffusers import OmniGenPipeline

pipe = OmniGenPipeline.from_pretrained("Shitao/OmniGen-v1-diffusers", dtype=torch.bfloat16)

Texto a imagen

Para texto a imagen, pasa un prompt de texto. Por defecto, OmniGen genera una imagen de 1024x1024. Puedes intentar establecer los parámetros height y width para generar imágenes de diferentes tamaños.

import torch
from diffusers import OmniGenPipeline

pipe = OmniGenPipeline.from_pretrained(
    "Shitao/OmniGen-v1-diffusers",
    dtype=torch.bfloat16
)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

prompt = "Realistic photo. A young woman sits on a sofa, holding a book and facing the camera. She wears delicate silver hoop earrings adorned with tiny, sparkling diamonds that catch the light, with her long chestnut hair cascading over her shoulders. Her eyes are focused and gentle, framed by long, dark lashes. She is dressed in a cozy cream sweater, which complements her warm, inviting smile. Behind her, there is a table with a cup of water in a sleek, minimalist blue mug. The background is a serene indoor setting with soft natural light filtering through a window, adorned with tasteful art and flowers, creating a cozy and peaceful ambiance. 4K, HD."
image = pipe(
    prompt=prompt,
    height=1024,
    width=1024,
    guidance_scale=3,
    generator=torch.Generator(device="cpu").manual_seed(111),
).images[0]
image.save("output.png")
generated image

Edición de imagen

OmniGen admite entradas multimodales. Cuando la entrada incluye una imagen, es necesario añadir un marcador de posición <img><|image_1|></img> en el prompt de texto para representar la imagen. Se recomienda habilitar use_input_image_size_as_output para que la imagen editada mantenga el mismo tamaño que la imagen original.

import torch
from diffusers import OmniGenPipeline
from diffusers.utils import load_image 

pipe = OmniGenPipeline.from_pretrained(
    "Shitao/OmniGen-v1-diffusers",
    dtype=torch.bfloat16
)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

prompt="<img><|image_1|></img> Remove the woman's earrings. Replace the mug with a clear glass filled with sparkling iced cola."
input_images=[load_image("https://raw.githubusercontent.com/VectorSpaceLab/OmniGen/main/imgs/docs_img/t2i_woman_with_book.png")]
image = pipe(
    prompt=prompt, 
    input_images=input_images, 
    guidance_scale=2, 
    img_guidance_scale=1.6,
    use_input_image_size_as_output=True,
    generator=torch.Generator(device="cpu").manual_seed(222)
).images[0]
image.save("output.png")
imagen original
imagen editada

OmniGen cuenta con algunas funciones interesantes, como el razonamiento visual, como se muestra en el ejemplo siguiente.

prompt="If the woman is thirsty, what should she take? Find it in the image and highlight it in blue. <img><|image_1|></img>"
input_images=[load_image("https://raw.githubusercontent.com/VectorSpaceLab/OmniGen/main/imgs/docs_img/edit.png")]
image = pipe(
    prompt=prompt, 
    input_images=input_images, 
    guidance_scale=2, 
    img_guidance_scale=1.6,
    use_input_image_size_as_output=True,
    generator=torch.Generator(device="cpu").manual_seed(0)
).images[0]
image.save("output.png")
generated image

Generación controlable

OmniGen puede manejar varias tareas clásicas de visión por computadora. Como se muestra a continuación, OmniGen puede detectar esqueletos humanos en las imágenes de entrada, lo que puede usarse como condiciones de control para generar nuevas imágenes.

import torch
from diffusers import OmniGenPipeline
from diffusers.utils import load_image 

pipe = OmniGenPipeline.from_pretrained(
    "Shitao/OmniGen-v1-diffusers",
    dtype=torch.bfloat16
)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

prompt="Detect the skeleton of human in this image: <img><|image_1|></img>"
input_images=[load_image("https://raw.githubusercontent.com/VectorSpaceLab/OmniGen/main/imgs/docs_img/edit.png")]
image1 = pipe(
    prompt=prompt, 
    input_images=input_images, 
    guidance_scale=2, 
    img_guidance_scale=1.6,
    use_input_image_size_as_output=True,
    generator=torch.Generator(device="cpu").manual_seed(333)
).images[0]
image1.save("image1.png")

prompt="Generate a new photo using the following picture and text as conditions: <img><|image_1|></img>\n A young boy is sitting on a sofa in the library, holding a book. His hair is neatly combed, and a faint smile plays on his lips, with a few freckles scattered across his cheeks. The library is quiet, with rows of shelves filled with books stretching out behind him."
input_images=[load_image("https://raw.githubusercontent.com/VectorSpaceLab/OmniGen/main/imgs/docs_img/skeletal.png")]
image2 = pipe(
    prompt=prompt, 
    input_images=input_images, 
    guidance_scale=2, 
    img_guidance_scale=1.6,
    use_input_image_size_as_output=True,
    generator=torch.Generator(device="cpu").manual_seed(333)
).images[0]
image2.save("image2.png")
imagen original
esqueleto detectado
de esqueleto a imagen

OmniGen también puede utilizar directamente la información relevante de las imágenes de entrada para generar nuevas imágenes.

import torch
from diffusers import OmniGenPipeline
from diffusers.utils import load_image 

pipe = OmniGenPipeline.from_pretrained(
    "Shitao/OmniGen-v1-diffusers",
    dtype=torch.bfloat16
)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

prompt="Following the pose of this image <img><|image_1|></img>, generate a new photo: A young boy is sitting on a sofa in the library, holding a book. His hair is neatly combed, and a faint smile plays on his lips, with a few freckles scattered across his cheeks. The library is quiet, with rows of shelves filled with books stretching out behind him."
input_images=[load_image("https://raw.githubusercontent.com/VectorSpaceLab/OmniGen/main/imgs/docs_img/edit.png")]
image = pipe(
    prompt=prompt, 
    input_images=input_images, 
    guidance_scale=2, 
    img_guidance_scale=1.6,
    use_input_image_size_as_output=True,
    generator=torch.Generator(device="cpu").manual_seed(0)
).images[0]
image.save("output.png")
imagen generada

Preservación de ID y objetos

OmniGen puede generar varias imágenes basándose en las personas y los objetos de la imagen de entrada y admite la entrada de varias imágenes simultáneamente. Además, OmniGen puede extraer los objetos deseados de una imagen que contiene varios objetos en función de las instrucciones.

import torch
from diffusers import OmniGenPipeline
from diffusers.utils import load_image 

pipe = OmniGenPipeline.from_pretrained(
    "Shitao/OmniGen-v1-diffusers",
    dtype=torch.bfloat16
)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

prompt="A man and a woman are sitting at a classroom desk. The man is the man with yellow hair in <img><|image_1|></img>. The woman is the woman on the left of <img><|image_2|></img>"
input_image_1 = load_image("https://raw.githubusercontent.com/VectorSpaceLab/OmniGen/main/imgs/docs_img/3.png")
input_image_2 = load_image("https://raw.githubusercontent.com/VectorSpaceLab/OmniGen/main/imgs/docs_img/4.png")
input_images=[input_image_1, input_image_2]
image = pipe(
    prompt=prompt, 
    input_images=input_images, 
    height=1024,
    width=1024,
    guidance_scale=2.5, 
    img_guidance_scale=1.6,
    generator=torch.Generator(device="cpu").manual_seed(666)
).images[0]
image.save("output.png")
input_image_1
input_image_2
imagen generada
import torch
from diffusers import OmniGenPipeline
from diffusers.utils import load_image 

pipe = OmniGenPipeline.from_pretrained(
    "Shitao/OmniGen-v1-diffusers",
    dtype=torch.bfloat16
)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

prompt="A woman is walking down the street, wearing a white long-sleeve blouse with lace details on the sleeves, paired with a blue pleated skirt. The woman is <img><|image_1|></img>. The long-sleeve blouse and a pleated skirt are <img><|image_2|></img>."
input_image_1 = load_image("https://raw.githubusercontent.com/VectorSpaceLab/OmniGen/main/imgs/docs_img/emma.jpeg")
input_image_2 = load_image("https://raw.githubusercontent.com/VectorSpaceLab/OmniGen/main/imgs/docs_img/dress.jpg")
input_images=[input_image_1, input_image_2]
image = pipe(
    prompt=prompt, 
    input_images=input_images, 
    height=1024,
    width=1024,
    guidance_scale=2.5, 
    img_guidance_scale=1.6,
    generator=torch.Generator(device="cpu").manual_seed(666)
).images[0]
image.save("output.png")
imagen de persona
imagen de ropa
imagen generada

Optimización al usar varias imágenes

Para la tarea de texto a imagen, OmniGen requiere un coste mínimo de memoria y tiempo (9 GB de memoria y 31 s para una imagen de 1024x1024 en una GPU A800). Sin embargo, al utilizar imágenes de entrada, el coste computacional aumenta.

A continuación se presentan algunas directrices para ayudarle a reducir los costos computacionales al utilizar varias imágenes. Los experimentos se realizan en una GPU A800 con dos imágenes de entrada.

Como en otros pipelines, puedes reducir el uso de memoria descargando el modelo: pipe.enable_model_cpu_offload() o pipe.enable_sequential_cpu_offload(). En OmniGen, también puedes disminuir la sobrecarga computacional reduciendo max_input_image_size. El consumo de memoria para diferentes tamaños de imagen se muestra en la tabla siguiente:

MétodoUso de memoria
max_input_image_size=102440GB
max_input_image_size=51217GB
max_input_image_size=25614GB

OmniGenPipeline

clase diffusers.OmniGenPipeline

< >

( transformer: OmniGenTransformer2DModelscheduler: FlowMatchEulerDiscreteSchedulervae: AutoencoderKLtokenizer: LlamaTokenizer )

Parámetros

  • transformer (OmniGenTransformer2DModel) — Arquitectura de Transformer autoregresiva para OmniGen.
  • scheduler (FlowMatchEulerDiscreteScheduler) — Un scheduler para usar en combinación con transformer para desruidar los latentes de imagen codificados.
  • vae (AutoencoderKL) — Modelo de Variational Auto-Encoder (VAE) para codificar y decodificar imágenes a partir de y hacia representaciones latentes.
  • tokenizer (LlamaTokenizer) — Tokenizador de texto de la clase LlamaTokenizer.

El pipeline OmniGen para la generación de imágenes a partir de multimodal.

Referencia: https://huggingface.co/papers/2409.11340

__call__

< >

( prompt: str | list[str]input_images: typing.Union[PIL.Image.Image, numpy.ndarray, torch.Tensor, list[PIL.Image.Image], list[numpy.ndarray], list[torch.Tensor], list[typing.Union[PIL.Image.Image, numpy.ndarray, torch.Tensor, list[PIL.Image.Image], list[numpy.ndarray], list[torch.Tensor]]]] = Noneheight: int | None = Nonewidth: int | None = Nonenum_inference_steps: int = 50max_input_image_size: int = 1024timesteps: list = Noneguidance_scale: float = 2.5img_guidance_scale: float = 1.6use_input_image_size_as_output: bool = Falsenum_images_per_prompt: int | None = 1generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = Nonelatents: typing.Optional[torch.Tensor] = Noneoutput_type: str | None = 'pil'return_dict: bool = Truecallback_on_step_end: typing.Optional[typing.Callable[[int, int], NoneType]] = Nonecallback_on_step_end_tensor_inputs: list = ['latents'] ) → ImagePipelineOutput or tuple

Parámetros

  • prompt (str o list[str], opcional) — El prompt o prompts para guiar la generación de la imagen. Si la entrada incluye imágenes, es necesario añadir marcadores de posición <img><|image_i|></img> en el prompt para indicar la posición de la i-ésima imagen.
  • input_images (PipelineImageInput o list[PipelineImageInput], opcional) — La lista de imágenes de entrada. Reemplazaremos el ”<|image_i|>” en el prompt con la i-ésima imagen de la lista.
  • height (int, opcional, por defecto self.unet.config.sample_size * self.vae_scale_factor) — La altura en píxeles de la imagen generada. Por defecto, se establece en 1024 para obtener los mejores resultados.
  • width (int, opcional, valor predeterminado self.unet.config.sample_size * self.vae_scale_factor) — El ancho en píxeles de la imagen generada. Por defecto, se establece en 1024 para obtener los mejores resultados.
  • num_inference_steps (int, opcional, valor predeterminado 50) — El número de pasos de desruido. Más pasos de desruido suelen conducir a una imagen de mayor calidad a costa de una inferencia más lenta.
  • max_input_image_size (int, opcional, valor predeterminado 1024) — el tamaño máximo de la imagen de entrada, que se utilizará para recortar la imagen de entrada al tamaño máximo
  • timesteps (list[int], opcional) — Pasos de tiempo personalizados para usar en el proceso de desruido con programadores que admiten un argumento timesteps en su método set_timesteps. Si no se define, se usará el comportamiento predeterminado cuando se pase num_inference_steps. Debe estar en orden descendente.
  • guidance_scale (float, opcional, valor predeterminado 2.5) — Escala de guía tal como se define en Classifier-Free Diffusion Guidance. guidance_scale se define como w de la ecuación 2 de Imagen Paper. La escala de guía se habilita al establecer guidance_scale > 1. Una escala de guía más alta fomenta la generación de imágenes estrechamente vinculadas al prompt de texto, generalmente a costa de una menor calidad de imagen.
  • img_guidance_scale (float, opcional, valor predeterminado 1.6) — Definido como la ecuación 3 en Instrucpix2pix.
  • use_input_image_size_as_output (bool, predeterminado en False) — si se debe usar el tamaño de la imagen de entrada como el tamaño de la imagen de salida, lo cual puede usarse para una sola imagen de entrada, p. ej., en una tarea de edición de imágenes
  • num_images_per_prompt (int, opcional, valor predeterminado 1) — El número de imágenes que se generarán por indicación.
  • generator (torch.Generator o list[torch.Generator], opcional) — Un generador o una lista de generadores de torch para hacer la generación determinista.
  • latents (torch.Tensor, opcional) — Latentes ruidosos pregenerados, muestreados de una distribución gaussiana, que se usarán como entradas para la generación de imágenes. Se pueden utilizar para ajustar la misma generación con diferentes prompts. Si no se proporcionan, se generará un tensor de latentes mediante muestreo usando el generator aleatorio suministrado.
  • output_type (str, opcional, valor predeterminado "pil") — El formato de salida de la imagen generada. Elija entre PIL: PIL.Image.Image o np.array.
  • return_dict (bool, opcional, valor predeterminado True) — Indica si se debe devolver un ~pipelines.flux.FluxPipelineOutput en lugar de una tupla simple.
  • callback_on_step_end (Callable, opcional) — Una función que se llama al final de cada paso de desruido durante la inferencia. La función se llama con los siguientes argumentos: callback_on_step_end(self: DiffusionPipeline, step: int, timestep: int, callback_kwargs: Dict). callback_kwargs incluirá una lista de todos los tensores especificados por callback_on_step_end_tensor_inputs.
  • callback_on_step_end_tensor_inputs (list, opcional) — La lista de entradas de tensor para la función callback_on_step_end. Los tensores especificados en la lista se pasarán como argumento callback_kwargs. Solo podrás incluir variables listadas en el atributo ._callback_tensor_inputs de tu clase de pipeline.

Devuelve

ImagePipelineOutput o tuple

ImagePipelineOutput si return_dict es True, en caso contrario, una tuple. Al devolver una tupla, el primer elemento es una lista con las imágenes generadas.

Función invocada al llamar a la pipeline para la generación.

Ejemplos:

>>> import torch
>>> from diffusers import OmniGenPipeline

>>> pipe = OmniGenPipeline.from_pretrained("Shitao/OmniGen-v1-diffusers", torch_dtype=torch.bfloat16)
>>> pipe.to("cuda")

>>> prompt = "A cat holding a sign that says hello world"
>>> # Depending on the variant being used, the pipeline call will slightly vary.
>>> # Refer to the pipeline documentation for more details.
>>> image = pipe(prompt, num_inference_steps=50, guidance_scale=2.5).images[0]
>>> image.save("output.png")

Devuelve: ImagePipelineOutput o tuple: Si return_dict es True, se devuelve ImagePipelineOutput; en caso contrario, se devuelve una tuple cuyo primer elemento es una lista con las imágenes generadas.

encode_input_images

< >

( input_pixel_values: listdevice: typing.Optional[torch.device] = Nonedtype: typing.Optional[torch.dtype] = None )

Parámetros

  • input_pixel_values — píxeles normalizados de las imágenes de entrada
  • device —

obtener la representación continua de las imágenes de entrada mediante VAE

Devuelve: torch.Tensor

Update on GitHub