Diffusers documentation

Image vers image

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

Image vers image

Image-to-image est similaire à text-to-image, mais en plus d’un prompt, vous pouvez également passer une image initiale comme point de départ pour le processus de diffusion. L’image initiale est encodée dans l’espace latent et du bruit y est ajouté. Ensuite, le modèle de diffusion latent prend un prompt et l’image latente bruitée, prédit le bruit ajouté, et retire le bruit prédit de l’image latente initiale pour obtenir la nouvelle image latente. Enfin, un décodeur décode la nouvelle image latente pour la reconvertir en image.

Avec 🤗 Diffusers, c’est aussi simple que 1-2-3 :

  1. Chargez un point de contrôle dans la classe AutoPipelineForImage2Image ; ce pipeline gère automatiquement le chargement de la classe de pipeline correcte en fonction du point de contrôle :
import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import load_image, make_image_grid

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "kandinsky-community/kandinsky-2-2-decoder", dtype=torch.float16, use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

Vous remarquerez tout au long du guide que nous utilisons enable_model_cpu_offload() et enable_xformers_memory_efficient_attention() pour économiser de la mémoire et augmenter la vitesse d’inférence. Si vous utilisez PyTorch 2.0, vous n’avez pas besoin d’appeler enable_xformers_memory_efficient_attention() sur votre pipeline, car il utilisera déjà le scaled-dot product attention natif de PyTorch 2.0.

  1. Charger une image à passer au pipeline :
init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/cat.png")
  1. Passez un prompt et une image au pipeline pour générer une image :
prompt = "cat wizard, gandalf, lord of the rings, detailed, fantasy, cute, adorable, Pixar, Disney, 8k"
image = pipeline(prompt, image=init_image).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
image initiale
image générée

Modèles populaires

Les modèles image-à-image les plus populaires sont Stable Diffusion v1.5, Stable Diffusion XL (SDXL) et Kandinsky 2.2. Les résultats des modèles Stable Diffusion et Kandinsky varient en raison de leurs différences d'architecture et de processus d'entraînement ; vous pouvez généralement vous attendre à ce que SDXL produise des images de meilleure qualité que Stable Diffusion v1.5. Passons rapidement en revue comment utiliser chacun de ces modèles et comparons leurs résultats.

Stable Diffusion v1.5

Stable Diffusion v1.5 est un modèle de diffusion latente initialisé à partir d'un point de contrôle antérieur, puis affiné pendant 595K étapes sur des images de 512x512. Pour utiliser ce pipeline pour la conversion d'image en image, vous devez préparer une image initiale à transmettre au pipeline. Vous pouvez ensuite passer un prompt et l'image au pipeline pour générer une nouvelle image :

import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16", use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"

# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
image initiale
image générée

Stable Diffusion XL (SDXL)

SDXL est une version plus puissante du modèle Stable Diffusion. Il utilise un modèle de base plus volumineux ainsi qu'un modèle de raffinement supplémentaire pour améliorer la qualité de la sortie du modèle de base. Consultez le guide SDXL pour un tutoriel plus détaillé sur l'utilisation de ce modèle et sur les autres techniques qu'il emploie pour générer des images de haute qualité.

import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-refiner-1.0", dtype=torch.float16, variant="fp16", use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-sdxl-init.png"
init_image = load_image(url)

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"

# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image, strength=0.5).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
image initiale
image générée

Kandinsky 2.2

Le modèle Kandinsky diffère des modèles Stable Diffusion car il utilise un modèle de prior d'image pour créer des embeddings d'image. Ces embeddings aident à créer un meilleur alignement entre le texte et les images, permettant au modèle de diffusion latente de générer de meilleures images.

La façon la plus simple d'utiliser Kandinsky 2.2 est :

import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "kandinsky-community/kandinsky-2-2-decoder", dtype=torch.float16, use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"

# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
image initiale
image générée

Configurer les paramètres du pipeline

Plusieurs paramètres importants peuvent être configurés dans le pipeline, et ils influenceront le processus de génération d’images ainsi que la qualité des images. Examinons de plus près ce que font ces paramètres et comment leur modification affecte la sortie.

Force

strength est l’un des paramètres les plus importants à prendre en compte et il aura un impact considérable sur l’image générée. Il détermine dans quelle mesure l’image générée ressemble à l’image initiale. En d’autres termes :

  • 📈 une valeur de strength plus élevée accorde au modèle davantage de « créativité » pour générer une image différente de l'image initiale ; une valeur de strength de 1.0 signifie que l'image initiale est plus ou moins ignorée
  • 📉 une valeur de strength plus faible signifie que l'image générée est plus similaire à l'image initiale

Les paramètres strength et num_inference_steps sont liés car strength détermine le nombre d'étapes de bruit à ajouter. Par exemple, si num_inference_steps est 50 et strength est 0,8, cela signifie ajouter 40 (50 * 0,8) étapes de bruit à l'image initiale, puis effectuer 40 étapes de débruitage pour obtenir l'image nouvellement générée.

import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16", use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"

# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image, strength=0.8).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
strength = 0.4
strength = 0.6
strength = 1.0

Échelle de guidage

Le paramètre guidance_scale permet de contrôler le degré d’alignement entre l’image générée et le prompt texte. Une valeur plus élevée de guidance_scale signifie que l’image générée est plus fidèle au prompt, tandis qu’une valeur plus basse de guidance_scale laisse davantage de liberté à l’image générée pour s’écarter du prompt.

Vous pouvez combiner guidance_scale et strength pour un contrôle encore plus précis sur l’expressivité du modèle. Par exemple, associez une valeur élevée de strength + guidance_scale pour une créativité maximale, ou utilisez une combinaison de strength faible et de guidance_scale faible pour générer une image qui ressemble à l’image initiale sans être aussi strictement liée au prompt.

import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16", use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"

# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image, guidance_scale=8.0).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
guidance_scale = 0.1
guidance_scale = 5.0
guidance_scale = 10.0

Prompt négatif

Un prompt négatif conditionne le modèle afin de ne pas inclure certains éléments dans une image, et il peut être utilisé pour améliorer la qualité de l’image ou la modifier. Par exemple, vous pouvez améliorer la qualité de l’image en incluant des prompts négatifs tels que « poor details » ou « blurry » pour encourager le modèle à générer une image de meilleure qualité. Vous pouvez également modifier une image en spécifiant les éléments à exclure.

import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-refiner-1.0", dtype=torch.float16, variant="fp16", use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
negative_prompt = "ugly, deformed, disfigured, poor details, bad anatomy"

# pass prompt and image to pipeline
image = pipeline(prompt, negative_prompt=negative_prompt, image=init_image).images[0]
make_image_grid([init_image, image], rows=1, cols=2)
negative_prompt = "ugly, deformed, disfigured, poor details, bad anatomy"
negative_prompt = "jungle"

Pipelines d'image à image en chaîne

Il existe d'autres façons intéressantes d'utiliser un pipeline image-versus-image, au-delà de la simple génération d'une image (bien que cela soit déjà assez impressionnant). Vous pouvez aller plus loin en le chaînant avec d'autres pipelines.

Texte-vers-image-vers-image

Enchaîner un pipeline de texte vers image et un pipeline d'image vers image permet de générer une image à partir d'un texte, puis d'utiliser l'image générée comme image initiale pour le pipeline d'image vers image. Cela est utile si vous souhaitez générer une image entièrement à partir de zéro. Par exemple, enchaînons un modèle Stable Diffusion et un modèle Kandinsky.

Commencez par générer une image avec le pipeline texte-vers-image :

from diffusers import AutoPipelineForText2Image, AutoPipelineForImage2Image
import torch
from diffusers.utils import make_image_grid

pipeline = AutoPipelineForText2Image.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16", use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

text2image = pipeline("Astronaut in a jungle, cold color palette, muted colors, detailed, 8k").images[0]
text2image

Vous pouvez maintenant passer cette image générée au pipeline image-vers-image :

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "kandinsky-community/kandinsky-2-2-decoder", dtype=torch.float16, use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

image2image = pipeline("Astronaut in a jungle, cold color palette, muted colors, detailed, 8k", image=text2image).images[0]
make_image_grid([text2image, image2image], rows=1, cols=2)

Image-vers-image-vers-image

Vous pouvez également enchaîner plusieurs pipelines image-à-image pour créer des images plus intéressantes. Cela peut être utile pour effectuer un transfert de style itératif sur une image, générer de courts GIF, restaurer les couleurs d’une image ou restaurer des zones manquantes d’une image.

Commencez par générer une image :

import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16", use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"

# pass prompt and image to pipeline
image = pipeline(prompt, image=init_image, output_type="latent").images[0]

Il est important de spécifier output_type="latent" dans le pipeline afin de conserver toutes les sorties dans l'espace latent et d'éviter une étape de décodage-encodage inutile. Cela ne fonctionne que si les pipelines enchaînés utilisent le même VAE.

Transmettez la sortie latente de ce pipeline au pipeline suivant pour générer une image dans un style de bande dessinée :

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "ogkalu/Comic-Diffusion", dtype=torch.float16
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# need to include the token "charliebo artstyle" in the prompt to use this checkpoint
image = pipeline("Astronaut in a jungle, charliebo artstyle", image=image, output_type="latent").images[0]

Répétez une dernière fois pour générer l'image finale dans un style pixel art :

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "kohbanye/pixel-art-style", dtype=torch.float16
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# need to include the token "pixelartstyle" in the prompt to use this checkpoint
image = pipeline("Astronaut in a jungle, pixelartstyle", image=image).images[0]
make_image_grid([init_image, image], rows=1, cols=2)

De l'image à l'upscaler vers la super-résolution

Une autre façon de chaîner votre pipeline image-à-image est d’utiliser un pipeline d’upscaler et de super-résolution pour augmenter considérablement le niveau de détail d’une image.

Commencez par un pipeline image-vers-image :

import torch
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import make_image_grid, load_image

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16", use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"

# pass prompt and image to pipeline
image_1 = pipeline(prompt, image=init_image, output_type="latent").images[0]

Il est important de spécifier output_type="latent" dans le pipeline afin de conserver toutes les sorties dans l'espace latent et d'éviter une étape de décodage-encodage inutile. Cela ne fonctionne que si les pipelines enchaînés utilisent le même VAE.

Enchaînez-le avec un pipeline d’upscaler pour augmenter la résolution de l’image :

from diffusers import StableDiffusionLatentUpscalePipeline

upscaler = StableDiffusionLatentUpscalePipeline.from_pretrained(
    "stabilityai/sd-x2-latent-upscaler", dtype=torch.float16, use_safetensors=True
)
upscaler.enable_model_cpu_offload()
upscaler.enable_xformers_memory_efficient_attention()

image_2 = upscaler(prompt, image=image_1).images[0]

Enfin, enchaînez-le avec un pipeline de super-résolution pour améliorer encore la résolution :

from diffusers import StableDiffusionUpscalePipeline

super_res = StableDiffusionUpscalePipeline.from_pretrained(
    "stabilityai/stable-diffusion-x4-upscaler", dtype=torch.float16, variant="fp16", use_safetensors=True
)
super_res.enable_model_cpu_offload()
super_res.enable_xformers_memory_efficient_attention()

image_3 = super_res(prompt, image=image_2).images[0]
make_image_grid([init_image, image_3.resize((512, 512))], rows=1, cols=2)

Contrôler la génération d'images

Générer une image qui correspond exactement à vos attentes peut s’avérer difficile, ce qui explique l’utilité des techniques et des modèles de génération contrôlée. Bien que vous puissiez utiliser negative_prompt pour contrôler partiellement la génération d’images, des méthodes plus robustes existent, comme le pondération des prompts et les ControlNets.

Pondération des prompts

Le pondération des prompts (prompt weighting) permet de mettre à l'échelle la représentation de chaque concept dans un prompt. Par exemple, dans un prompt comme « Astronaut in a jungle, cold color palette, muted colors, detailed, 8k », vous pouvez choisir d'augmenter ou de diminuer les embeddings de « astronaut » et « jungle ». La bibliothèque Compel fournit une syntaxe simple pour ajuster les poids des prompts et générer les embeddings. Vous pouvez apprendre à créer les embeddings dans le guide Prompt weighting.

AutoPipelineForImage2Image possède un paramètre prompt_embeds (et negative_prompt_embeds si vous utilisez un prompt négatif) dans lequel vous pouvez passer les embeddings, ce qui remplace le paramètre prompt.

from diffusers import AutoPipelineForImage2Image
import torch

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16", use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

image = pipeline(prompt_embeds=prompt_embeds, # generated from Compel
    negative_prompt_embeds=negative_prompt_embeds, # generated from Compel
    image=init_image,
).images[0]

ControlNet

Les ControlNets offrent une méthode plus flexible et précise pour contrôler la génération d’images, car vous pouvez utiliser une image de conditionnement supplémentaire. L’image de conditionnement peut être une image canny, une carte de profondeur, une segmentation d’image, voire des gribouillis ! Quel que soit le type d’image de conditionnement choisi, le ControlNet génère une image qui préserve les informations qu’elle contient.

Par exemple, conditionnons une image avec une carte de profondeur afin de conserver les informations spatiales de l'image.

from diffusers.utils import load_image, make_image_grid

# prepare image
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png"
init_image = load_image(url)
init_image = init_image.resize((958, 960)) # resize to depth image dimensions
depth_image = load_image("https://huggingface.co/lllyasviel/control_v11f1p_sd15_depth/resolve/main/images/control.png")
make_image_grid([init_image, depth_image], rows=1, cols=2)

Charger un modèle ControlNet conditionné sur des cartes de profondeur et le AutoPipelineForImage2Image :

from diffusers import ControlNetModel, AutoPipelineForImage2Image
import torch

controlnet = ControlNetModel.from_pretrained("lllyasviel/control_v11f1p_sd15_depth", dtype=torch.float16, variant="fp16", use_safetensors=True)
pipeline = AutoPipelineForImage2Image.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5", controlnet=controlnet, dtype=torch.float16, variant="fp16", use_safetensors=True
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

Générez maintenant une nouvelle image conditionnée par la carte de profondeur, l'image initiale et le prompt :

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image_control_net = pipeline(prompt, image=init_image, control_image=depth_image).images[0]
make_image_grid([init_image, depth_image, image_control_net], rows=1, cols=3)
image initiale
image de profondeur
Image ControlNet

Appliquons un nouveau style à l’image générée par le ControlNet en le chaînant avec un pipeline image-vers-image :

pipeline = AutoPipelineForImage2Image.from_pretrained(
    "nitrosocke/elden-ring-diffusion", dtype=torch.float16,
)
pipeline.enable_model_cpu_offload()
# remove following line if xFormers is not installed or you have PyTorch 2.0 or higher installed
pipeline.enable_xformers_memory_efficient_attention()

prompt = "elden ring style astronaut in a jungle" # include the token "elden ring style" in the prompt
negative_prompt = "ugly, deformed, disfigured, poor details, bad anatomy"

image_elden_ring = pipeline(prompt, negative_prompt=negative_prompt, image=image_control_net, strength=0.45, guidance_scale=10.5).images[0]
make_image_grid([init_image, depth_image, image_control_net, image_elden_ring], rows=2, cols=2)

Optimiser

L’exécution des modèles de diffusion est coûteuse et gourmande en calcul, mais avec quelques astuces d’optimisation, il est tout à fait possible de les faire tourner sur des GPU grand public et des offres gratuites. Par exemple, vous pouvez utiliser une forme d’attention plus économe en mémoire, comme l’attention à produit scalaire mis à l’échelle de PyTorch 2.0 ou xFormers (vous pouvez utiliser l’un ou l’autre, mais il n’est pas nécessaire d’utiliser les deux). Vous pouvez également décharger le modèle sur le GPU pendant que les autres composants du pipeline attendent sur le CPU.

+ pipeline.enable_model_cpu_offload()
+ pipeline.enable_xformers_memory_efficient_attention()

Avec torch.compile, vous pouvez encore augmenter la vitesse de votre inférence en l’appliquant à votre UNet :

pipeline.unet = torch.compile(pipeline.unet, mode="reduce-overhead", fullgraph=True)

Pour en savoir plus, consultez les guides Réduire l'utilisation de la mémoire et Accélérer l'inférence.

Update on GitHub