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 在保留文本提示的同时,利用参考图像来引导预训练的扩散模型。它冻结基础模型,并添加一组小型的图像交叉注意力层,因此无需微调即可实现与照片中特定主体或风格的匹配,具有实际可操作性。

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

IP-Adapter 检查点通常约为 100MB,因为它们存储的是适配器权重,而非完整模型。请先加载基础流水线,然后使用 load_ip_adapter() 加载适配器。

IP-Adapter 可用于许多模型,例如 Flux 和 Stable Diffusion 3 等。本指南中的示例使用 Stable Diffusion 和 Stable Diffusion XL。

使用 set_ip_adapter_scale() 来控制 IP-Adapter 对生成过程的引导强度。1.0 表示以全强度应用适配器;0.5 通常能在文本提示词和图像提示词之间取得平衡。

以下示例展示了 IP-Adapter 在常见任务中的应用。

文本到图像
图像到图像
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)

将图像传入 ip_adapter_image,并配合文本提示词,即可生成图像。

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
IP-Adapter 图像
generated image
生成的图像

检查点变体

当参考图像的详细信息最为重要时,请加载 Plus。当您需要 InsightFace 身份嵌入而非 CLIP 图像嵌入时,请加载 FaceID。

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"
)

图像嵌入

prepare_ip_adapter_image_embeds() 将 IP-Adapter 图像编码为可保存和复用的嵌入。只需预先计算一次,而无需在每次运行流水线时都重新加载并编码相同的图像。

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")

通过向 ip_adapter_image_embeds 参数传入值来重新加载图像嵌入。由于生成图像嵌入不再需要图像编码器,请将 image_encoder_folder 设置为 None。

您还可以从 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]

掩码

二进制掩码(Binary masking)允许将 IP-Adapter 图像分配到输出图像的特定区域,因此适用于组合多个 IP-Adapter 图像。每个 IP-Adapter 图像都需要一个二进制掩码。

加载 IPAdapterMaskProcessor 以预处理图像掩码。为了获得最佳效果,请提供输出 height 和 width,以确保不同宽高比的掩码被调整到合适的大小。如果输入掩码的宽高比已经与生成图像的宽高比一致,则无需设置 height 和 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
掩码 1
mask 2
mask 2

以列表形式同时提供 IP-Adapter 图像及其对应的缩放系数。将预处理后的掩码传入管道中的 cross_attention_kwargs。

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
IP-Adapter 图像 1
IP-Adapter image 2
IP-Adapter 图像 2
Generated image with mask
使用掩码生成
Generated image without mask
未使用掩码生成

配方

当单张参考图像不够用时,可以将 IP-Adapter 与其他适配器或流水线结合使用,例如多个适配器、ControlNet、InstantStyle 或 few-step LCM。

多个 IP-Adapter

组合多个 IP-Adapter 以生成风格更多样的图像。例如,你可以使用 IP-Adapter Face 生成一致的面孔和角色,并使用 IP-Adapter Plus 以特定风格生成这些面孔。

使用 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,
)

加载基础模型、调度器以及以下 IP-Adapter。

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()

加载一张图像以及一个包含特定风格图像的文件夹,以应用该风格。

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
人脸图像
Style images
风格图像

将风格图像和人脸图像以列表形式传入 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
生成的图像

结构控制

在结构控制方面,可以将 IP-Adapter 与 ControlNet 结合使用,并以深度图、边缘图、姿态估计等作为条件。

以下示例加载了一个以深度图为条件的 ControlNetModel 检查点,并将其与 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"
)

将深度图和 IP-Adapter 图像传入 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
IP-Adapter 图像
Depth map
深度图
Generated image
生成的图像

样式和布局控制

如需控制风格和布局,请将 IP-Adapter 与 InstantStyle 结合使用。InstantStyle 将 风格(颜色、纹理、整体感觉)与 内容 分离,并仅在风格特定的块中应用风格,从而保持内容区域完整。这能带来更强的风格一致性和更清晰的布局控制。

使用 set_ip_adapter_scale() 仅在选定的层中激活 IP-Adapter。下面的示例在模型的 down block_2(布局)和 up block_0(风格)中将其开启。

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)

加载风格图像并生成图像。

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 图像
Generated image
生成的图像

下图比较了 InstantStyle 的仅风格激活(仅 block_0)与在所有层中启用 IP-Adapter 的效果。在所有层中启用通常会更强烈地遵循图像提示,并可能降低多样性。如果您希望保留 InstantStyle 的布局保持特性,建议优先选择仅风格激活。

您无需在 scale 字典中指定所有层。未包含的层会被设置为 0,这意味着 IP-Adapter 处于禁用状态。

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)
仅样式(up block_0)
Generated image (all layers)
所有层

即时生成

将 IP-Adapter 与 LCM LoRA 结合,实现少步生成。

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
生成的图像
Update on GitHub