LoRAなしで同じ顔を再現してみる ~ 画像生成AI実験メモ ⑩

これまで、Stable Diffusionの画像生成環境を使って、いろいろと遊んできましたが、ちょっと原点に振り返ってみようと思います。

というのも、

まず、Stable Diffusion(AUTOMATIC1111)の環境を作って、とりあず何か画像を生成してみる。

次に、プロンプトをいろいろと試して、ブログのアシスタント的に登場してもらう人物の生成をやってみる。

で、このときに生成した人物(の顔)を、例えばポーズ違い、衣装違いなど、他のシチュエーションで再現したい、と頑張ってみる。

と、進んだわけですが、やっぱり、プロンプトだけでは難しい、限界があるということで、LoRAを作ってみたんですね。これは、ある意味順当な流れではあるんですが、kohya_ssの環境構築や、各種パラメータの設定など、ちょっと敷居が高いのも事実。このテーマで書く前に、実際に別PCで数ヶ月触れていたから簡単に書いてしまったところはあるので、今回は「本当にLoRAが必要だったの?」という検証をしてみたいと思います。

本記事に掲載している人物画像は、すべて生成AIにより作成したものであり、特定の実在人物をモデルにしたものではありません。

IP-Adapterとは?

結論から言うと、「プロンプトだけ」では、先の記事に結果を書いたように、数百枚を無駄に生成して、かつ、その中から、これという1枚をピックアップするだけの意欲と時間のある方なら、どうにかなるかもしれませんが、現実的には厳しいです。

が、ちょっと使えそうな拡張機能があることを知ったんです。

それが、IP-Adapter です。

OpenPoseが元画像から人体の姿勢や関節の位置を、Depthが奥行きや立体構造を、Cannyが輪郭や境界線をそれぞれ元画像から取得して新たな画像を生成するのに対して、IP-Adapterは、「画像に含まれる視覚的特徴」を利用するのだとか。

画像から抽出した特徴を生成処理に与えることが出来る、ということらしく、上手く活用すれば、元画像の顔の特徴を新たな画像生成に活かせるのでは?ということです。

ControlNetに含まれる機能なんですが、実は使ったことがありません。なので、どんなものなのか楽しみでもあります。

では、実際に使ってみましょう。

IP-Adapterの導入

先ほども書いた通り、ControlNetに含まれる機能なので、OpenPoseやDepthを導入していれば、既にインストール済みとなります。

まだ、という方はこちらをご覧ください。

どうも、(もちろん、悪い話ではないのですが)各機能が独自にバージョンアップを進めて、機能間の整合が取れなくなっているものもあるようです。そのため、一部機能のバージョンを意図的に下げたりして導入したのでかなり面倒に見えてしまうかもしれないですね。ただ、これも、日々変化しているので、何事も無くインストールが完了するかもしれません。

ControlNetが用意できたところで、次に、IP-Adapter用のモデルをダウンロードする必要があります。

例によって、Hugging Face を使用しますので、以下のリポジトリを参照してください。今回は、SDXLでの使用をベースに話を進めたいと思います。

https://huggingface.co/h94/IP-Adapter

ここの、「Files and Versions」タブにあるファイル一覧から、「📁sdxl_models」をクリックし、ip-adapter_sdxl_vit-h.safetensors のDownloadアイコン(↓)を押します。

ダウンロードしたファイルを下記のフォルダに格納します。

ControlNetを開くと、Control Typeの中に、IP-Adapterの文字が見えると思います。

まずは、これを選択します。

Preprocessorには、ip-adapter-autoが自動で選択されるかと思いますので、Modelには、ip-adapter_sdxl_vit-hを選択します。上記通りダウンロードしたファイルを格納した後でも候補に出てこなければ、右にあるリフレッシュアイコンをクリックすれば、選択候補に現れます。

IP-Adapterを使ってみる

まずは、そもそもIP-Adapterがどれくらい有効なのかを知るために、人物画ではなく、物体で試してみたいと思います。

作成する画像は、木製のテーブルに置かれた1個のマグカップ。

・Model:sd_xl_base_1.0.safetensors
・Sampler:DPM++ 2M
・Schedule type:Karras
・Sampring steps:28
・CFG Scale:6.5
・Seed:-1
・サイズ(Width x Height):1024 x 1024

Prompt
a single coffee mug on a wooden table,
photorealistic photograph,
soft natural daylight,
realistic texture,
highly detailed

Negative Prompt
anime, illustration, painting, cartoon, CGI,
multiple mugs, duplicate objects,
deformed mug, distorted handle,
floating objects, liquid spilling,
blurry, low quality,
text, watermark

これで4枚生成したのが、こちら。

色は指定してないんですが、一般的にマグカップと言えば白になるんですかね。どれも、悪くはないです。

で、いよいよIP-Adapterの出番です。

そのために用意した画像がこちら。

赤いマグカップです。内側は白。これも別のプロンプトで生成した画像です。色指定してます。

この画像をControlNetに読み込ませます。

その他の設定は、画像にもある通り、Enableにチェックを付けるのはもちろんとして、

・Control Type:IP-Adapter
・Preprocessor:ip-adapter-auto
・Model:ip-adapter_sdxl_vit-h
・Control Weight:1.0
・Starting Control Step:0
・Ending Control Step:1
・Resize Mode:Crop and Resize
・Resolution:512

見ての通り、ここまでに設定したところ以外は全て初期値です。

プロンプトは先ほどと同じ、色指定なしのものです。

初回は不足しているファイルなどのダウンロードがあって時間がかかりますが、しばらく待ちましょう。

その結果がこちら。同じく4枚生成です。

元画像の持ち手が左側にあるのに、4枚すべて右側に持ち手が来ているのが不思議なところではありますが、全て内側が白く、外が赤いマグカップになっています。ただ、見た目の構図も、かなり元画像に引っ張られてる感はありますね。

というわけで、Control Weight を下げてみます。

・Control Weight:0.5

として、同じく4枚を生成。

最初の1枚は、重みを0.5にしたネタか、と思うような出来だったんですが、全体として、赤いマグカップを維持しつつ、構図に変化が出てきているように思います。

もう少し下げて、

・Control Weight:0.25

として、同じく4枚を生成。

これを順当といって良いのかどうか、赤いマグカップの比率が一気に減りました(何度か繰り返すと4枚共に白色となることもありました)が、構成の自由度は増していると思います。要は、元画像の縛りが弱くなっている、と。

では、元画像と反するプロンプトがあった場合は、どうなるでしょうか。

プロンプトの1行目を、

Prompt
a single blue ceramic coffee mug on a wooden table,
photorealistic photograph,
soft natural daylight,
realistic texture,
highly detailed

と変えてみます。さすがに重みが0.25だと、プロンプトに完敗しそうな気がしたので、0.5での生成です。

なかなか、面白い結果になりましたね。最後の1枚はプロンプトに負けてますが、他の3枚は内側が青かったり、縁だけ青かったり。そう来たか、という感じです。

ならば、と、重みを1.0にして4枚。

…面白くない結果ですみません。

プロンプトよりも元画像が勝つ、ということですね。

念のため、重み0.25でもやってみましたが、4枚とも青い陶器製のカップとなりました。こちらも面白くない結果なので、画像は省略します。

人物画像への適用

というわけで、主題の「人物の顔」を試してみたい思います。

プロンプト以外の設定は、マグカップと同じ。

Prompt
photorealistic portrait of a young Japanese woman, looking at the camera, upper body shot, simple casual clothing, soft natural lighting, plain indoor background, sharp focus, highly detailed skin texture, realistic photograph

Negative Prompt
anime, illustration, painting, cartoon, cgi, deformed face, asymmetrical eyes, distorted features, blurry, low quality, extra fingers, text, watermark

元画像は、もちろん、これ。

プロンプトだけで生成した「元画像」から人物部分をトリミングしたものです。それ以外の加工はしていません。

同じく4枚を生成。

むむ。

別人…。

やっぱり、人の顔では難しいんですかね。顔以外の服装などはよく再現できてるんですけどね。身体の向きも違ってますし、なにより「顔が真っすぐ」なのが地味に感動ポイントだったりします。

マグカップのときは重みを減らす方向でしたが、増やせばいいのかな?と 2.0 にしてみました(1→0.5が1/2倍なので反対に2倍というだけの理由です)。

そういう問題ではなさそうですね。

で、いろいろ調べてみると、IP-Adapterに使用したModel(ip-adapter_sdxl_vit-h)は汎用的なもので、これとは別に、人物の顔に特化したモデルがあるようなんですね。実は、さっきダウンロードしたページにあったんです。

ip-adapter-plus-face_sdxl_vit-h.safetensors という、顔の特徴を反映させるのに適したモデル、とのこと。

これをダウンロードして、同じフォルダに格納します。

そして、これをModelとして読み込み。

Preprocessorの方は、ip-adapter-autoのままで大丈夫なようです。

重みを1.0に戻して再チャレンジ。

んんん?

いや、まぁ、さっきよりは格段に「似てる」気はしますが、なんか、怖い。。

モノと違って、1.0は強すぎるんですかね。

0.5に落として再挑戦。

おー。いい感じかも。

やや違和感がありますが、元画像に近い雰囲気になっています。

念のため、0.25でも試してみます。

さすがに、雰囲気は残すものの、別人になってきますね。

ということは、0.5あたりが無難なのかな、と。さらに、プロンプトを修正してみます。

Prompt
photorealistic portrait of a young adult Japanese woman, looking at the camera,
gentle smile, youthful impression,
upper body shot, simple casual clothing, soft natural lighting, plain indoor background, sharp focus, natural skin texture, realistic photograph

顔の表情と、年齢層に関する補正です。

かなり近づいてきた感がありますね。

重みの値を前後に振ってみたんですが、似てるのもあれば遠のくのもある、という感じで、そのあたりは数を出して最適なのをピックアップする、でいいのかな、と思います。

ちなみに、IP-AdapterをOFFにすると、

と、完全に別人ですから、IP-Adapterで作成したものの中から選ぶ方が、遥かに効率的かと思います。

LoRAは必要?

結局、LoRAは必要なの?というところなので、汎用性確認の意味も込めて、

これで最後に作成した山登り風のスタイルでのプロンプトで生成してみました。重みは0.4にしています。

これでも、16枚の中から「最良」を選んだ結果です。他に使ってもいいかなと、自身で納得できる画像は3枚程度だったでしょうか。

もちろん、LoRAを使用すれば全てOKかというとそうでもないのも事実。何枚もの生成結果の中からいいものを選択して使用する、ということに違いはありません。

SD1.5のときに頑張って頑張って作成したLoRAと、同等かそれ以上のものが、学習も無しにControlNetだけで生成できた、ということへの驚きは隠せないですね。途中でも書きましたが、1枚の画像から学習すると、顔の傾きのような変なクセまで学習してしまうので、それが無いだけでも驚きです。

ただ、SD1.5ではなく、SDXLで作成し直したLoRAの方が、より汎用的というのか、自然な表情が出しやすいと感じていて、そこをIP-Adapterが覆せるかというと、ちょっと厳しいかな、と思います。

手軽に同じ人物を生成したい、ということであれば、IP-Adapterは十分に試す価値があると思います。が、汎用的に使用するには、やっぱりSDXLのLoRAが有効かな、という感想で締めさせてもらいたいと思います。