ジャコ Lab

プログラミング関連のメモ帳的ブログです

IP-Adapter の基本形(General Tasks)を使ってみる

huggingface.co

この記事では、ドキュメントに含まれる General Tasks を進めていこうと思いましたが、ほとんどのサンプルコードが SDXL 向けの IP-Adapter となっていて、 IP-Adapter をロードを実行中にセッションがクラッシュしてしまうことがわかりました。

メモリ不足。。。

悲しみです。
IP-Adapter で SDXL 系を動かすことは今の状態では叶わなぬ願いかもしれないです。

唯一 AnimateDiff x IP-Adapter のサンプルコードだけ SD1.5 系統だったため、クラッシュせずに実行ができましたので、この記事ではその1つだけを進めていきます。

General Tasks - Video を進める

このパターンでは AnimateDiffMotionAdapter を差し込みつつ、
IP-Adapter も追加で差し込むアプローチになります。

モデルのロード等(MotionAdapter, AnimateDiffPipeline, IP-Adapter)

import torch
from diffusers import MotionAdapter, AnimateDiffPipeline, DDIMScheduler

# MotionAdapter をロードする
adapter = MotionAdapter.from_pretrained(
    "guoyww/animatediff-motion-adapter-v1-5-2",
    torch_dtype=torch.float16
)

# AnimateDiffPipeline で「emilianJR/epiCRealism」をロードする
pipe = AnimateDiffPipeline.from_pretrained(
    "emilianJR/epiCRealism",
    motion_adapter=adapter,
    torch_dtype=torch.float16
).to("cuda")

# スケジューラを設定する(DDIMScheduler)
pipe.scheduler = DDIMScheduler.from_config(
    pipe.scheduler.config,
    clip_sample=False,
    timestep_spacing="linspace",
    beta_schedule="linear",
    steps_offset=1,
)

# IP-Adapter をロードする
pipe.load_ip_adapter(
    "h94/IP-Adapter",
    subfolder="models",
    weight_name="ip-adapter_sd15.bin"
)

# Memory Savings
pipe.enable_vae_slicing()
pipe.enable_model_cpu_offload()

IP-Adapter に使用する画像をロードする

from diffusers.utils import load_image

# IP-Adapter に使用する画像をロードする
ip_adapter_image_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_adapter_inpaint.png"
ip_adapter_image = load_image(ip_adapter_image_url)

パイプラインを実行する

import torch

# シードの設定
generator = torch.Generator(device="cpu").manual_seed(0)

# プロンプト実行
prompt="A cute gummy bear waving"
negative_prompt="bad quality, worse quality, low resolution"
frames = pipe(
    prompt,
    negative_prompt=negative_prompt,
    ip_adapter_image=ip_adapter_image,
    num_frames=16,
    guidance_scale=7.5,
    num_inference_steps=50,
    generator=generator,
).frames[0]

実行結果

from datetime import datetime
from zoneinfo import ZoneInfo
from diffusers.utils import export_to_gif

# Asia/Tokyo タイムゾーンの現在時刻を YYYYMMDDhhmmss 形式で得る
formattedNow = datetime.now(tz=ZoneInfo("Asia/Tokyo")).strftime("%Y%m%d%H%M%S")

# 実行結果
export_to_gif(frames, f"animation_{formattedNow}_{generator.initial_seed()}.gif")

IP-Adapter に利用する画像AnimateDiff で出力した画像
(左) IP-Adapter 用画像 | (右) AnimateDiff で出力した動画

まとめ

次回は、SDXL系の部分を全部 SD1.5系に置き換えてやってみることにします。