ジャコ Lab

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

IP-Adapter FaceID がエラーになってドキュメント通りに実行できなかった件

前回までの記事では h94/IP-Adapter というリポジトリ顔モデル (ip-adapter-full-face_sd15) を使用していました。

前回までの記事たち

本日は Hugging Face のドキュメント を少し進め、
h94/IP-Adapter-FaceID というリポジトリip-adapter-faceid_sd15 を使おうとしましたがエラーになってしまいました。

よって、本日の記事では、トラブルシューティング的な感じで進めていきます。


追記:

こちらの記事で無事解決

今回実行したかったコード

今回実行したかったコードは IP-Adapter FaceID モデル を使用したコードです。

To use IP-Adapter FaceID models, first extract face embeddings with insightface. Then pass the list of tensors to the pipeline as ip_adapter_image_embeds.

ということで、 IP-Adapter FaceIDinsightface を使って顔を抽出し、 ip_adapter_image_embedes() を使う流れのようです。

なお以下のような記載がありましたので、非商用でしか使えないようです。

As InsightFace pretrained models are available for non-commercial research purposes, IP-Adapter-FaceID models are released exclusively for research purposes and are not intended for commercial use.
InsightFace の事前トレーニング済みモデルは非営利の研究目的で利用できるため、IP アダプター - FaceID モデルは研究目的のみにリリースされており、商業利用を目的としていません。

以下は、ドキュメントのスクリプトを未整形のままペタッとしたものです。

import torch
from diffusers import StableDiffusionPipeline, DDIMScheduler
from diffusers.utils import load_image
from insightface.app import FaceAnalysis

pipeline = StableDiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    torch_dtype=torch.float16,
).to("cuda")
pipeline.scheduler = DDIMScheduler.from_config(pipeline.scheduler.config)
pipeline.load_ip_adapter("h94/IP-Adapter-FaceID", subfolder=None, weight_name="ip-adapter-faceid_sd15.bin", image_encoder_folder=None)
pipeline.set_ip_adapter_scale(0.6)

image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/ip_mask_girl1.png")

ref_images_embeds = []
app = FaceAnalysis(name="buffalo_l", providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
image = cv2.cvtColor(np.asarray(image), cv2.COLOR_BGR2RGB)
faces = app.get(image)
image = torch.from_numpy(faces[0].normed_embedding)
ref_images_embeds.append(image.unsqueeze(0))
ref_images_embeds = torch.stack(ref_images_embeds, dim=0).unsqueeze(0)
neg_ref_images_embeds = torch.zeros_like(ref_images_embeds)
id_embeds = torch.cat([neg_ref_images_embeds, ref_images_embeds]).to(dtype=torch.float16, device="cuda")

generator = torch.Generator(device="cpu").manual_seed(42)

images = pipeline(
    prompt="A photo of a girl",
    ip_adapter_image_embeds=[id_embeds], 
    negative_prompt="monochrome, lowres, bad anatomy, worst quality, low quality", 
    num_inference_steps=20, num_images_per_prompt=1,
    generator=generator
).images

エラー1

ModuleNotFoundError: No module named 'insightface'
今回のスクリプトでは insightfaceというモジュールが必要っぽい

対処法

pip install に insightface を追加する

- !pip install -U diffusers["torch"] transformers accelerate peft controlnet_aux
+ !pip install -U diffusers["torch"] transformers accelerate peft controlnet_aux insightface

エラー2

ModuleNotFoundError: No module named 'onnxruntime'
今度はinsightfaceの中でonnxruntimeが怒られたっぽい

どうやら insightface の依存モジュールとして onnxruntime が必要のようです。

対処法

pip install に onnxruntime を追加する

- !pip install -U diffusers["torch"] transformers accelerate peft controlnet_aux insightface
+ !pip install -U diffusers["torch"] transformers accelerate peft controlnet_aux onnxruntime insightface

エラー3

KeyError: 'latents'
/usr/local/lib/python3.10/dist-packages/diffusers/loaders/unet.py in _convert_ip_adapter_attn_to_diffusers(self, state_dicts, low_cpu_mem_usage)
    854                     else:
    855                         # IP-Adapter Plus
--> 856                         num_image_text_embeds += [state_dict["image_proj"]["latents"].shape[1]]
    857 
    858                 with init_context():
む。。。モジュール系のエラーじゃない。。。

確かに IP-Adapter Plus のロード方法は別セクションで学べ。と記載されていた気がします。

Learn how to load an IP-Adapter in the Load adapters guide, and make sure you check out the IP-Adapter Plus section which requires manually loading the image encoder.
「アダプターのロード」ガイドで IP アダプターをロードする方法を学び、イメージ エンコーダーを手動でロードする必要がある IP アダプター プラスのセクションを必ず確認してください。

FaceID Plus じゃないんだけどなぁ。。。

そのリンク先がこちら↓

huggingface.co

とりあえず最小構成にしてやってみたが。。。

変わらずエラー
import torch
from diffusers import StableDiffusionPipeline
from transformers import CLIPVisionModelWithProjection

image_encoder = CLIPVisionModelWithProjection.from_pretrained(
    "laion/CLIP-ViT-H-14-laion2B-s32B-b79K",
    torch_dtype=torch.float16,
)

pipeline = StableDiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    torch_dtype=torch.float16,
    image_encoder=image_encoder,
).to("cuda")

pipeline.load_ip_adapter(
    "h94/IP-Adapter-FaceID",
    subfolder=None,
    weight_name="ip-adapter-faceid_sd15.bin",
    image_encoder_folder=None
)
KeyError: 'latents'

なんならドキュメント通り IP-Adapter FaceID Plus にしてもエラー

import torch
from diffusers import StableDiffusionPipeline
from transformers import CLIPVisionModelWithProjection

image_encoder = CLIPVisionModelWithProjection.from_pretrained(
    "laion/CLIP-ViT-H-14-laion2B-s32B-b79K",
    torch_dtype=torch.float16,
)

pipeline = StableDiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    torch_dtype=torch.float16,
    image_encoder=image_encoder,
).to("cuda")

pipeline.load_ip_adapter(
    "h94/IP-Adapter-FaceID",
    subfolder=None,
    weight_name="ip-adapter-faceid-plus_sd15.bin" # ここを変えました。
)
これは、、、ドキュメント制作時は動いていたけどバージョンアップで動かなくなった系では。。。?
KeyError: 'latents'

まとめ

悲しみ

以下のような Issue を見つけたので次回もう少し追ってみます。

github.com

なお、自分が試している環境の diffusers は v0.27.2 でした。

$ pip list | grep diffusers
diffusers                        0.27.2

追記

こちらの記事で無事解決