Diffusers documentation

IP-Adapter

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

IP-Adapter

IP-Adapter는 텍스트 프롬프트를 유지하면서 참조 이미지를 사용하여 사전 학습된 diffusion 모델의 생성 방향을 제어합니다. 이 방법은 베이스 모델을 동결하고 작은 규모의 이미지 cross-attention 레이어를 추가하므로, fine-tuning 없이 사진의 대상이나 스타일을 일치시키는 데 실용적입니다.

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-Adapters는 Flux와 Stable Diffusion 3를 비롯한 다양한 모델에서 사용할 수 있습니다. 이 가이드의 예제는 Stable Diffusion과 Stable Diffusion XL를 사용합니다.

set_ip_adapter_scale()를 사용하여 IP-Adapter가 생성을 얼마나 강하게 유도하는지 제어할 수 있습니다. 1.0은 어댑터를 최대 강도로 적용하며, 0.5는 일반적으로 텍스트 프롬프트와 이미지 프롬프트의 균형을 맞춥니다.

IP-Adapter를 일반적인 작업에 적용하는 예제를 아래에 보여줍니다.

텍스트-이미지
이미지-이미지
인페인팅
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
생성된 이미지

Checkpoint 변형

참조 이미지의 세부 정보가 가장 중요한 경우 Load Plus를 로드하세요. CLIP 이미지 임베딩 대신 InsightFace의 ID 임베딩이 필요한 경우 Load 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 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,
)

base model, scheduler 및 다음 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()

이미지와 특정 스타일을 적용할 이미지들이 포함된 폴더를 로드합니다.

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
생성된 이미지

구조적 제어

구조적 제어를 위해, 깊이 맵, 엣지 맵, 자세 추정 등을 조건으로 사용하는 ControlNet과 IP-Adapter를 결합하세요.

아래 예시에서는 깊이 맵에 조건부인 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 이미지를 파이프라인에 전달합니다.

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(layout)과 up block_0(style)에서 이를 켜는 방법을 보여줍니다.

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
스타일 이미지
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)
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