1-Intro
之前 快速搞了 Ip-Adapter 的 demo 和其他原理: 17-ip-adapter && ip-adapter-plus basic
Ip-Adapter 是一个 Image Prompt Adapter, 可以把 Image Prompt 适配到任何的扩散模型, 实现图像提示功能, 而无需对底层模型进行任何的更改.
此外, 这个适配器可以与 同一基础模型微调的其他模型一起重用 , 注意 是 BaseModel 相同的话就可以. 尤其提到了 可以很好的和 ControlNet 集成工作.
训练了一个独立的 cross-Attention 去学习图片的特征. 而不是使用相同的交叉注意力层来处理文本和图像特征, 这样这个模型可以更多的学习 专属于图片维度 的特征.
- 使用了解耦的交叉注意力机制 ;
- 图像特征有专门的处理层 ;
1)-为什么 ControlNet 适合和 IP-Adapter 一起工作?
controlNet 确实是通过 特征融合 的方式在 U-Net 的各个层级通过 Zero Convolution方式 注入控制信号 ;
- 在
UNet的主干网络中添加条件分支, 这些分支学习从 控制图像 ,例如pose,edge,depth中提取的特征 ; - 直接在特征层面进行 融合 ;
在 sd 的领域中, 卷积 UNet 是主干架构,适合学习图片的细节,纹理,而 UNet 每一层引入的 transformer blocks 去学习整体的风格一致 和细节把控 ;
类似的思路:
- 从效果上看:
controlNet可以控制生成图像的精确结构,Ip-Adapter可以提供参考图像的风格和细节 ; - 从代码上看:
controlNet工作在feature层面上引入Zero Convolution, 而Ip-Adapter工作在CrossAttention层面 ;
2-t2i
下面的例子:
文生图的引导能力:
- 通过
ip_adapter_image引入了一张图作为风格指导,负责整个餐厅的布局 ; - 通过 文本增加了一张图片 增加了额外的内容 ;
from diffusers import AutoPipelineForText2Image
from diffusers.utils import load_image
import torch
pipeline = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16).to("cuda")
pipeline.load_ip_adapter("h94/IP-Adapter", subfolder="sdxl_models", weight_name="ip-adapter_sdxl.bin")
pipeline.set_ip_adapter_scale(0.6)
image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_adapter_diner.png")
generator = torch.Generator(device="cpu").manual_seed(0)
images = 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",
num_inference_steps=100,
generator=generator,
).images
images[0]原图:

3-i2i
Ip-Adapter 也可以用来作为图片引导, 生成一个同时类似于原始图像和图像提示的新图像.
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import load_image
import torch
pipeline = AutoPipelineForImage2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16).to("cuda")
pipeline.load_ip_adapter("h94/IP-Adapter", subfolder="sdxl_models", weight_name="ip-adapter_sdxl.bin")
pipeline.set_ip_adapter_scale(0.6)
image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_adapter_bear_1.png")
ip_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_adapter_bear_2.png")
generator = torch.Generator(device="cpu").manual_seed(4)
images = pipeline(
prompt="best quality, high quality",
image=image,
ip_adapter_image=ip_image,
generator=generator,
strength=0.6,
).images
images[0]4-inpainting
局部重绘的能力, Ip-Adapter 也非常适合重绘的工作, 因为可以让你更明确 需要重绘成什么样子的东西.
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image
import torch
pipeline = AutoPipelineForInpainting.from_pretrained("diffusers/stable-diffusion-xl-1.0-inpainting-0.1", torch_dtype=torch.float16).to("cuda")
pipeline.load_ip_adapter("h94/IP-Adapter", subfolder="sdxl_models", weight_name="ip-adapter_sdxl.bin")
pipeline.set_ip_adapter_scale(0.6)mask_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_adapter_mask.png")
image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_adapter_bear_1.png")
ip_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_adapter_gummy.png")
generator = torch.Generator(device="cpu").manual_seed(4)
images = pipeline(
prompt="a cute gummy bear waving",
image=image,
mask_image=mask_image,
ip_adapter_image=ip_image,
generator=generator,
num_inference_steps=100,
).images
images[0]mask_image: 指定需要修复的区域 ;image: 原始需要修复的图像 ;ip_image: 提供参考样式的图像.
images = pipeline(
prompt="a cute gummy bear waving",
image=image,
mask_image=mask_image,
ip_adapter_image=ip_image,
generator=generator,
num_inference_steps=100,
)prompt: 文本描述 目标生成内容 ;generator: 固定随机种子以保证可重复性 ;num_inference_steps: 100步推理以确保质量 ;
5-generated image
IP-Adapter 在视频生成的作用:
- 提供更精确的视觉引导
- 增强文本提示的效果
- 实现风格和内容的精确控制
下面的代码使用视频生成模型, AnimatedDiff 来实现.
import torch
from diffusers import AnimateDiffPipeline, DDIMScheduler, MotionAdapter
from diffusers.utils import export_to_gif
from diffusers.utils import load_image
adapter = MotionAdapter.from_pretrained("guoyww/animatediff-motion-adapter-v1-5-2", torch_dtype=torch.float16)
pipeline = AnimateDiffPipeline.from_pretrained("emilianJR/epiCRealism", motion_adapter=adapter, torch_dtype=torch.float16)
scheduler = DDIMScheduler.from_pretrained(
"emilianJR/epiCRealism",
subfolder="scheduler",
clip_sample=False,
timestep_spacing="linspace",
beta_schedule="linear",
steps_offset=1,
)
pipeline.scheduler = scheduler
pipeline.enable_vae_slicing()
pipeline.load_ip_adapter("h94/IP-Adapter", subfolder="models", weight_name="ip-adapter_sd15.bin")
pipeline.enable_model_cpu_offload()ip_adapter_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_adapter_inpaint.png")
output = pipeline(
prompt="A cute gummy bear waving",
negative_prompt="bad quality, worse quality, low resolution",
ip_adapter_image=ip_adapter_image,
num_frames=16,
guidance_scale=7.5,
num_inference_steps=50,
generator=torch.Generator(device="cpu").manual_seed(0),
)
frames = output.frames[0]
export_to_gif(frames, "gummy_bear.gif")