Diffusers documentation

IP-Adapter

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

IP-Adapter

IP-Adapter dirige un modelo de difusión preentrenado con una imagen de referencia mientras se mantiene un prompt de texto. Congela el modelo base y añade un pequeño conjunto de capas de atención cruzada de imagen, lo que lo hace práctico para coincidir con un sujeto o estilo de una foto sin necesidad de fine-tuning.

text prompt                         reference image
    |                                     |
 text encoder                        image encoder
    |                                     |
    v                                     v
 text cross-attn  (frozen)          IP-Adapter cross-attn
    \                                     /
     \                                   /
      +-------->  denoiser  <-----------+
                  (frozen base)

Los puntos de control de IP-Adapter suelen ser de ~100MB porque almacenan los pesos del adaptador, no un modelo completo. Carga primero un pipeline base y luego carga el adaptador con load_ip_adapter().

Los IP-Adapters están disponibles para muchos modelos, como Flux y Stable Diffusion 3, entre otros. Los ejemplos de esta guía utilizan Stable Diffusion y Stable Diffusion XL.

Use set_ip_adapter_scale() para controlar la intensidad con la que el IP-Adapter dirige la generación. 1.0 aplica el adaptador a plena intensidad; 0.5 suele equilibrar los prompts de texto e imagen.

Los ejemplos a continuación muestran IP-Adapter en tareas comunes.

texto a imagen
image-to-image
inpainting
video
import torch
from diffusers import AutoPipelineForText2Image
from diffusers.utils import load_image

pipeline = AutoPipelineForText2Image.from_pretrained(
  "stabilityai/stable-diffusion-xl-base-1.0",
  dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_ip_adapter(
  "h94/IP-Adapter",
  subfolder="sdxl_models",
  weight_name="ip-adapter_sdxl.bin"
)
pipeline.set_ip_adapter_scale(0.8)

Pase una imagen a ip_adapter_image junto con un prompt de texto para generar una imagen.

image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_adapter_diner.png")
pipeline(
    prompt="a polar bear sitting in a chair drinking a milkshake",
    ip_adapter_image=image,
    negative_prompt="deformed, ugly, wrong proportion, low res, bad anatomy, worst quality, low quality",
).images[0]
IP-Adapter image
Imagen de IP-Adapter
generated image
imagen generada

Variantes de puntos de control

Carga Plus cuando el detalle de la imagen de referencia sea lo más importante. Carga FaceID cuando necesites embeddings de identidad de InsightFace en lugar de embeddings de imagen de CLIP.

IP-Adapter Plus
IP-Adapter FaceID
import torch
from transformers import CLIPVisionModelWithProjection
from diffusers import AutoPipelineForText2Image

image_encoder = CLIPVisionModelWithProjection.from_pretrained(
    "h94/IP-Adapter",
    subfolder="models/image_encoder",
    dtype=torch.float16
)

pipeline = AutoPipelineForText2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    image_encoder=image_encoder,
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"

pipeline.load_ip_adapter(
  "h94/IP-Adapter",
  subfolder="sdxl_models",
  weight_name="ip-adapter-plus_sdxl_vit-h.safetensors"
)

Embeddings de imágenes

prepare_ip_adapter_image_embeds() codifica las imágenes de IP-Adapter en embeddings que puedes guardar y reutilizar. Precomputa una vez en lugar de cargar y codificar las mismas imágenes cada vez que ejecutas el pipeline.

import torch
from diffusers import AutoPipelineForText2Image
from diffusers.utils import load_image

pipeline = AutoPipelineForText2Image.from_pretrained(
  "stabilityai/stable-diffusion-xl-base-1.0",
  dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_ip_adapter(
  "h94/IP-Adapter",
  subfolder="sdxl_models",
  weight_name="ip-adapter_sdxl.bin"
)

image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_adapter_bear_1.png")
image_embeds = pipeline.prepare_ip_adapter_image_embeds(
    ip_adapter_image=image,
    ip_adapter_image_embeds=None,
    device="cuda",
    num_images_per_prompt=1,
    do_classifier_free_guidance=True,
)

torch.save(image_embeds, "image_embeds.ipadpt")

Recarga los embeddings de imagen pasándolos al parámetro ip_adapter_image_embeds. Establece image_encoder_folder en None porque ya no necesitas el codificador de imágenes para generar los embeddings de imagen.

También puedes cargar incrustaciones de imágenes de otras fuentes, como ComfyUI.

pipeline = AutoPipelineForText2Image.from_pretrained(
  "stabilityai/stable-diffusion-xl-base-1.0",
  dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_ip_adapter(
  "h94/IP-Adapter",
  subfolder="sdxl_models",
  image_encoder_folder=None,
  weight_name="ip-adapter_sdxl.bin"
)
pipeline.set_ip_adapter_scale(0.8)
image_embeds = torch.load("image_embeds.ipadpt")
pipeline(
    prompt="a polar bear sitting in a chair drinking a milkshake",
    ip_adapter_image_embeds=image_embeds,
    negative_prompt="deformed, ugly, wrong proportion, low res, bad anatomy, worst quality, low quality",
    num_inference_steps=100,
).images[0]

Enmascarado

La enmascaración binaria permite asignar una imagen de IP-Adapter a un área específica de la imagen de salida, lo que resulta útil para componer varias imágenes de IP-Adapter. Cada imagen de IP-Adapter requiere una máscara binaria.

Cargue el IPAdapterMaskProcessor para preprocesar las máscaras de imagen. Para obtener los mejores resultados, proporcione la height y el width de salida para asegurarse de que las máscaras con diferentes relaciones de aspecto tengan el tamaño adecuado. Si las máscaras de entrada ya coinciden con la relación de aspecto de la imagen generada, no necesita establecer la height y el width.

import torch
from diffusers import AutoPipelineForText2Image
from diffusers.image_processor import IPAdapterMaskProcessor
from diffusers.utils import load_image

pipeline = AutoPipelineForText2Image.from_pretrained(
  "stabilityai/stable-diffusion-xl-base-1.0",
  dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"

mask1 = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_mask_mask1.png")
mask2 = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_mask_mask2.png")

processor = IPAdapterMaskProcessor()
masks = processor.preprocess([mask1, mask2], height=1024, width=1024)
mask 1
máscara 1
mask 2
máscara 2

Proporcione tanto las imágenes de IP-Adapter como sus escalas en forma de lista. Pase las máscaras preprocesadas a cross_attention_kwargs en el pipeline.

face_image1 = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_mask_girl1.png")
face_image2 = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_mask_girl2.png")

pipeline.load_ip_adapter(
  "h94/IP-Adapter",
  subfolder="sdxl_models",
  weight_name=["ip-adapter-plus-face_sdxl_vit-h.safetensors"]
)
pipeline.set_ip_adapter_scale([[0.7, 0.7]])

ip_images = [[face_image1, face_image2]]
masks = [masks.reshape(1, masks.shape[0], masks.shape[2], masks.shape[3])]

pipeline(
  prompt="2 girls",
  ip_adapter_image=ip_images,
  negative_prompt="monochrome, lowres, bad anatomy, worst quality, low quality",
  cross_attention_kwargs={"ip_adapter_masks": masks}
).images[0]
IP-Adapter image 1
Imagen 1 de IP-Adapter
IP-Adapter image 2
Imagen 2 de IP-Adapter
Generated image with mask
generado con máscara
Generated image without mask
generado sin máscara

Recetas

Combine IP-Adapter con otros adaptadores o pipelines, como múltiples adaptadores, ControlNet, InstantStyle o LCM de pocos pasos, cuando una sola imagen de referencia no sea suficiente.

Varios IP-Adapters

Combine varios IP-Adapters para generar imágenes en estilos más diversos. Por ejemplo, puede usar IP-Adapter Face para generar rostros y personajes consistentes e IP-Adapter Plus para generar esos rostros en estilos específicos.

Cargue un codificador de imágenes con CLIPVisionModelWithProjection.

import torch
from diffusers import AutoPipelineForText2Image, DDIMScheduler
from transformers import CLIPVisionModelWithProjection
from diffusers.utils import load_image

image_encoder = CLIPVisionModelWithProjection.from_pretrained(
    "h94/IP-Adapter",
    subfolder="models/image_encoder",
    dtype=torch.float16,
)

Cargue un modelo base, un programador y los siguientes IP-Adapters.

pipeline = AutoPipelineForText2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16,
    image_encoder=image_encoder,
)
pipeline.scheduler = DDIMScheduler.from_config(pipeline.scheduler.config)
pipeline.load_ip_adapter(
  "h94/IP-Adapter",
  subfolder="sdxl_models",
  weight_name=["ip-adapter-plus_sdxl_vit-h.safetensors", "ip-adapter-plus-face_sdxl_vit-h.safetensors"]
)
pipeline.set_ip_adapter_scale([0.7, 0.3])
# enable_model_cpu_offload to reduce memory usage
pipeline.enable_model_cpu_offload()

Cargue una imagen y una carpeta que contenga imágenes de un estilo determinado para aplicar.

face_image = load_image("https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/women_input.png")
style_folder = "https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/style_ziggy"
style_images = [load_image(f"{style_folder}/img{i}.png") for i in range(10)]
Face image
imagen de rostro
Style images
imágenes de estilo

Pasa las imágenes de estilo y rostro como una lista a ip_adapter_image.

generator = torch.Generator(device="cpu").manual_seed(0)

pipeline(
    prompt="wonderwoman",
    ip_adapter_image=[style_images, face_image],
    negative_prompt="monochrome, lowres, bad anatomy, worst quality, low quality",
).images[0]
Generated image
imagen generada

Control estructural

Para el control estructural, combine IP-Adapter con ControlNet condicionado en mapas de profundidad, mapas de bordes, estimaciones de pose y más.

El ejemplo siguiente carga un checkpoint de ControlNetModel condicionado en mapas de profundidad y lo combina con un IP-Adapter.

import torch
from diffusers.utils import load_image
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel

controlnet = ControlNetModel.from_pretrained(
  "lllyasviel/control_v11f1p_sd15_depth",
  dtype=torch.float16
)

pipeline = StableDiffusionControlNetPipeline.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5",
    controlnet=controlnet,
    dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_ip_adapter(
  "h94/IP-Adapter",
  subfolder="models",
  weight_name="ip-adapter_sd15.bin"
)

Pasa el mapa de profundidad y la imagen de IP-Adapter a la pipeline.

depth_map = load_image("https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/depth.png")
ip_adapter_image = load_image("https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/statue.png")
pipeline(
  prompt="best quality, high quality",
  image=depth_map,
  ip_adapter_image=ip_adapter_image,
  negative_prompt="monochrome, lowres, bad anatomy, worst quality, low quality",
).images[0]
IP-Adapter image
Imagen de IP-Adapter
Depth map
mapa de profundidad
Generated image
imagen generada

Control de estilo y diseño

Para controlar el estilo y el diseño, combine IP-Adapter con InstantStyle. InstantStyle separa el estilo (color, textura, sensación general) del contenido y aplica el estilo solo en los bloques específicos de estilo, de modo que las áreas de contenido se mantengan intactas. Esto proporciona una mayor consistencia de estilo y un control más claro del diseño.

Active el IP-Adapter solo en capas seleccionadas con set_ip_adapter_scale(). El ejemplo de abajo lo activa en el bloque block_2 descendente (layout) y el bloque block_0 ascendente (style) del modelo.

import torch
from diffusers import AutoPipelineForText2Image
from diffusers.utils import load_image

pipeline = AutoPipelineForText2Image.from_pretrained(
  "stabilityai/stable-diffusion-xl-base-1.0",
  dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_ip_adapter(
  "h94/IP-Adapter",
  subfolder="sdxl_models",
  weight_name="ip-adapter_sdxl.bin"
)

scale = {
    "down": {"block_2": [0.0, 1.0]},
    "up": {"block_0": [0.0, 1.0, 0.0]},
}
pipeline.set_ip_adapter_scale(scale)

Cargue la imagen de estilo y genere una imagen.

style_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/0052a70beed5bf71b92610a43a52df6d286cd5f3/diffusers/rabbit.jpg")

pipeline(
    prompt="a cat, masterpiece, best quality, high quality",
    ip_adapter_image=style_image,
    negative_prompt="text, watermark, lowres, low quality, worst quality, deformed, glitch, low contrast, noisy, saturation, blurry",
    guidance_scale=5,
).images[0]
Style image
style image
Generated image
imagen generada

Las figuras siguientes comparan la activación solo de estilo de InstantStyle (hasta block_0) con la activación del IP-Adapter en todas las capas. El modo de todas las capas suele seguir el prompt de imagen con más fuerza y puede reducir la diversidad. Prefiera la escala solo de estilo cuando desee el comportamiento de InstantStyle que preserva el diseño.

No es necesario especificar todas las capas en el diccionario scale. Las capas que no se incluyan se establecen en 0, lo que significa que el IP-Adapter está deshabilitado.

scale = {
    "up": {"block_0": [0.0, 1.0, 0.0]},
}
pipeline.set_ip_adapter_scale(scale)

pipeline(
    prompt="a cat, masterpiece, best quality, high quality",
    ip_adapter_image=style_image,
    negative_prompt="text, watermark, lowres, low quality, worst quality, deformed, glitch, low contrast, noisy, saturation, blurry",
    guidance_scale=5,
).images[0]
Generated image (style only)
solo estilo (bloque_0 superior)
Generated image (all layers)
todas las capas

Generación instantánea

Combina IP-Adapter con un LoRA de LCM para la generación en pocos pasos.

import torch
from diffusers import DiffusionPipeline, LCMScheduler
from diffusers.utils import load_image

pipeline = DiffusionPipeline.from_pretrained(
  "sd-dreambooth-library/herge-style",
  dtype=torch.float16
)
pipeline.load_ip_adapter(
  "h94/IP-Adapter",
  subfolder="models",
  weight_name="ip-adapter_sd15.bin"
)
pipeline.load_lora_weights("latent-consistency/lcm-lora-sdv1-5")
pipeline.scheduler = LCMScheduler.from_config(pipeline.scheduler.config)
pipeline.enable_model_cpu_offload()

pipeline.set_ip_adapter_scale(0.4)
ip_adapter_image = load_image("https://user-images.githubusercontent.com/24734142/266492875-2d50d223-8475-44f0-a7c6-08b51cb53572.png")
pipeline(
    prompt="herge_style woman in armor, best quality, high quality",
    ip_adapter_image=ip_adapter_image,
    num_inference_steps=4,
    guidance_scale=1,
).images[0]
Generated image
imagen generada
Update on GitHub