ピッコロ記念日なのでピッコロ大魔王を生成したかったけど LoRA が見つからなかったので結局 IP-Adapter の記事になった件
とりあえず、昨日の記事同様、タイトルはすごい長いラノベ風にできたのは良いとして、、、
前回の IP-Adapter の記事に引き続き diffusers v0.24.0 のリリースノート に沿って IP-Adapter を使ってみる回になります。
前回は、 IP-Adapter を差し込んで LCM LoRA を併用していました。
今回は、 ControlNet を併用する形になります。
ControlNet とは?
ControlNet とは、 追加の入力画像を使用して調整することで、出力画像を制御するモデルの一種で、制御に使用できる入力には様々なタイプがある とのことで、以下で調べていました。
IP-Adapter と ControlNet を併用する
diffusers v0.24.0 のリリースノート によると IP-Adapter と ControlNet の Depth を併用するサンプルのようです。
ControlNet の Depth 単体を試している記事は以下になります。
ControlNet (Depth) のときには image= プロパティに control_image (depth_image) を渡しており、
「プロンプト」 + 「コントロール画像」 になります。
IP-Adapter を用いることで入力が 「画像」 「プロンプト」 「コントロール画像」 の3つになります。
モデルのロード等 (ControlNet(Depth), StableDiffusion1.5, IP-Adapter)
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
import torch
# ControlNetモデルのロード (Depth)
controlnet = ControlNetModel.from_pretrained(
"lllyasviel/control_v11f1p_sd15_depth",
torch_dtype=torch.float16
)
# SD 系モデルのロード
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
controlnet=controlnet,
torch_dtype=torch.float16)
pipe.to("cuda")
# IP-Adapter のロード
pipe.load_ip_adapter(
"h94/IP-Adapter",
subfolder="models",
weight_name="ip-adapter_sd15.bin"
)
# enable memory savings
pipe.enable_vae_slicing()
pipe.enable_model_cpu_offload()
入力画像等のロード
from diffusers.utils import load_image # インプット画像のロード input_image_url = "https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/statue.png" input_image = load_image(input_image_url) # コントロール画像のロード control_image_url = "https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/depth.png" control_image = load_image(control_image_url)
パイプライン実行
import torch
generator = torch.Generator(device="cpu").manual_seed(33)
prompt = "best quality, high quality"
negative_prompt = "monochrome, lowres, bad anatomy, worst quality, low quality"
image = pipe(
prompt,
negative_prompt=negative_prompt,
image=control_image,
ip_adapter_image=input_image,
num_inference_steps=50,
generator=generator,
).images[0]
実行結果
from datetime import datetime
from zoneinfo import ZoneInfo
# Asia/Tokyo タイムゾーンの現在時刻を YYYYMMDDhhmmss 形式で得る
formattedNow = datetime.now(tz=ZoneInfo("Asia/Tokyo")).strftime("%Y%m%d%H%M%S")
# 実行結果
image.save(f"image_{formattedNow}_{generator.initial_seed()}.png")



まとめ
ControlNet のときは、pix2pix や inpaint のようなインプット画像を用いるものもありましたが、
ほぼ「コントロール画像」と「プロンプト」を用いて実行するものでした。
IP-Adapter を差し込むことで、更に「インプット画像」を追加することができることがわかりました。