最近画像生成AIが流行りです.@shi3zさんの Memeplex.app で遊んだりしています.Memeplexはプロンプトのプリセットがあるし日本語を入力すると英語に翻訳してくれるので英語の出来ない自分でもとっつきやすいです.
ローカル環境でも試したいけどStable Diffusionはローカルで動かすにはGPUが必要.しかし手元にはないので出来ないな,クラウドを使ってみる?とか思っていたのですが,Intel CPU内蔵GPUで画像生成をしてくれる「stable_diffusion.openvino」を知ったので少し試してみました.
- Stable Diffusion with 🧨 Diffusers (NVIDIA製GPUが必要)
- Google Colab で はじめる Stable Diffusion v1.4|npaka|note (クラウドの一つ)
- bes-dev/stable_diffusion.openvino (iGPUで動作する今回試したもの)
Stable Diffusion OpenVINO 動作要件確認
Stable Diffusion OpenVINOの要件は以下のようになっています.OpenVINOに対応したCPUだとOKのようです.
Requirements
Linux, Windows, MacOS
Python 3.8.+
CPU compatible with OpenVINO.
OpenVINOの要件は以下のページを見るとCore i 6世代目〜12世代目のようです.
CPU
Processors
6th to 12th generation Intel Core processors
1st to 3rd generation of Intel® Xeon® Scalable processors
Intel Atom® processor with Intel® Streaming SIMD Extensions 4.2 (Intel® SSE4.2)
手元の端末のCPUは以下のような感じで3世代目と6世代目.後者はぎりぎり対応していそうです.
$ lscpu | grep ^Model\ name: Model name: Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz $ lscpu | grep ^Model\ name: Model name: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
Stable Diffusion OpenVINO 導入
端末の内蔵diskは狭く空き容量が少ないので外付けHDDのvirtualenvに導入することにします.
$ mkdir /media/matoken/export/sd (1) $ cd /media/matoken/export/sd $ virtualenv . (2) $ source bin/activate (3) $ git clone https://github.com/bes-dev/stable_diffusion.openvino (4) $ cd stable_diffusion.openvino $ pip install -r requirements.txt (5)
- HDDに作業ディレクトリ作成
- virtualenv で環境作成
- virtualenv環境反映
- stable_diffusion.openvinoをclone
- Install
初回実行時にダウンロードされるmodelが4GBほどあるのですが,10回ほど試してもタイムアウトで中断してしまうのでVPSでダウンロードしてコピーしました.規定値のホームディレクトリ以下に導入しようとしてdisk fullになったのでhddにシンボリックリンクを貼ってHDDに導入しました.オリジナルの場所は ~/.cache/huggingface
以下です.
$ ls -Ss1 ~/.cache/huggingface/hub/models--bes-dev--stable-diffusion-v1-4-openvino/blobs/ 合計 4169032 3357512 7655112cde3c5084c2709b2b89994834b24efc457f2c1b302bb3d7a056bfdb7a 480740 b3f34c33d8c272f61c6780251a503911c7e7a448cdc10f8fb7d9bc59c3462951 193328 456fd6d12ffab507af1ad6772b7b1922b35502272cd5be3708c8292252cd4c46 133460 8732df1da0a3026da5ee6070df8899efbccf0d844821368214af8d95abeae467 2952 a6514903a2875c318399e451c1f9ddaf4a3f7ba4 460 dfb9780b4527132dfe9a19ccc7ce5c0d885cb2ae 328 c0f568310ea3a649aea01772031087d324272780 252 87adf22fe4160e26a799270b2f53c8c21c9d6cd0
プロンプトからの画像生成
ここまで来たら画像生成が出来ます.テキストの文字列でどんな画像を生成するか伝えます.この文字列をプロンプトといい基本的に英語,英語圏で通じる言葉で指示します.今回は「kawaii neko」としてみました.
$ python ./demo.py --prompt "kawaii neko" Terminated
Terminatedと言われて処理が中断しました.どうもメモリが足りなそうです.実メモリは8GBです.disk swapでもう8GB追加して再度実行してみます.
メモリ不足なのでディスクスワップの追加
$ dd if=/dev/zero of=./swap.img bs=1M count=8096 (1) $ sudo chown 0.0 ./swap.img $ sudo chmod 600 ./swap.img $ sudo mkswap ./swap.img (2) $ sudo swapon `pwd`/swap.img (3) $ python ./demo.py --prompt "kawaii neko" (4) 32it [13:14, 24.84s/it]
- 8GB程のディスクイメージの作成
- スワップとして初期化
- スワップを有効にする
- 再度画像生成
今度は15分程経って処理が終了し,output.png
として画像が出来ました.何度か試すと10〜15分程で1枚出来ます.このときLoadAverageは10くらいまで上がって他の処理はあまりやりたくない感じに.寝ているときなどに処理する感じが良さそうです.
Note
|
他のCPUでの処理速度は以下にいくつか紹介されています.やはりGPUに比べると大分遅いですね. |
Note
|
何度か動かすと数回に一回 $ sudo systemctl stop nohang-desktop.service $ sudo systemctl stop nohang.service |
次回以降起動時
shellを開いて以下のコマンドでStable Diffusionの環境を有効にします.
$ cd /media/matoken/export/sd/stable_diffusion.openvino (1) $ source ../bin/activate (2) $ sudo swapon `pwd`/swap.img (3)
- Stable Diffusion 作業ディレクトリに移動
- virtualenv環境反映
- disk swap反映
help
demo.py
のhelpを見るとこんな感じ.色々できそうです.
$ python demo.py --help usage: demo.py [-h] [--model MODEL] [--seed SEED] [--beta-start BETA_START] [--beta-end BETA_END] [--beta-schedule BETA_SCHEDULE] [--num-inference-steps NUM_INFERENCE_STEPS] [--guidance-scale GUIDANCE_SCALE] [--eta ETA] [--tokenizer TOKENIZER] [--prompt PROMPT] [--init-image INIT_IMAGE] [--strength STRENGTH] [--mask MASK] [--output OUTPUT] optional arguments: -h, --help show this help message and exit --model MODEL model name --seed SEED random seed for generating consistent images per prompt --beta-start BETA_START LMSDiscreteScheduler::beta_start --beta-end BETA_END LMSDiscreteScheduler::beta_end --beta-schedule BETA_SCHEDULE LMSDiscreteScheduler::beta_schedule --num-inference-steps NUM_INFERENCE_STEPS num inference steps --guidance-scale GUIDANCE_SCALE guidance scale --eta ETA eta --tokenizer TOKENIZER tokenizer --prompt PROMPT prompt --init-image INIT_IMAGE path to initial image --strength STRENGTH how strong the initial image should be noised [0.0, 1.0] --mask MASK mask of the region to inpaint on the initial image --output OUTPUT output image name
img2img
初期イメージを指定も試してみます. --init-image
で適当な画像を指定してみました.ハンモックの画像にプロンプトで猫などを指定してみました.
$ python demo.py --seed ${seed} --prompt "sleep cat, campe site, hammock" --init-image=./hammock.jpg --output "${outfile}"
ハンモックに猫っぽいものが現れました.
もう少し線画とかシンプルな画像のほうがいいかも?
同じSEEDとプロンプトで画像が固定されるのを確認
出来上がる画像は毎回同じプロンプトでも既定値ではSEEDがランダム生成されるので別の画像が生成されます.SEEDとプロンプトを固定して同じ画像が出力されるか見てみます.
Note
|
少し古いStable DiffusionだとSEEDを固定しても別の画像が出てくるようです. |
$ python demo.py --seed 999999 --prompt "kawaii neko" --output "kawaii_neko-999999-01.png" 32it [09:47, 18.36s/it] $ python demo.py --seed 999999 --prompt "kawaii neko" --output "kawaii_neko-999999-02.png" 32it [09:41, 18.18s/it]
見た目もチェックサムを比較しても同じ値になりました.
$ sha512sum ./kawaii_neko-999999-0?.png 3cd2fad521495571842d9f37f13113bd6a18195e120fd4cded40f7fcf59eb3807cdd9aa43ae4831dfd7e4b0228077bdcabd2a7a86947507e2863143a43d7cee9 ./kawaii_neko-999999-01.png 3cd2fad521495571842d9f37f13113bd6a18195e120fd4cded40f7fcf59eb3807cdd9aa43ae4831dfd7e4b0228077bdcabd2a7a86947507e2863143a43d7cee9 ./kawaii_neko-999999-02.png
ということは恐らく低解像度だと処理時間は短くなると思うので,低解像度でたくさん画像生成して気に入ったものを高解像度で作り直すといったことをすると効率が良さそう.でもまだ解像度指定は出来ないようです.
とりあえず解像度指定できるようになったときのために毎回SEEDを指定して,SEEDとプロンプトをexifに保存しておくことにしました.
SEEDの範囲は手元で試した感じでは2^32で 0〜4294967295
のようです.
seed=$( shuf -i 0-4294967295 -n 1 ) python demo.py --seed ${seed} --prompt "${prompt}" --init-image="${image}" --output "${outfile}" exiftool -overwrite_original -comment="SEED:${seed}/PROMPT:${prompt}" "${outfile}"
SEEDで探索
MemeplexのDiscordでSEEDが近いと似た画像が生成されるというのを見たので試してみます.(そしてMemeplexにはSEED固定機能が追加された)
適当な画像のプロンプトは固定でSEEDを少しづつずらして画像生成を試してみます.
近いと似た傾向に画像になるような感じ?
strengthで探索
--strength
オプションは0〜1で既定値は0.5のようです.これを変更してどうなるか見てみます.
まずはプロンプトとSEEDを固定して初期画像無しで—strengthを0.1刻みで変更してみました.
見た目は変わらない?hashを比較すると別の画像になっています.
次は猫画像を作成して,その画像を初期画像に指定してプロンプトに「dog」を指定,SEEDを固定しました.
段々と猫から犬になり,–strengthが1では顔の向きくらいしか残ってなさそうです.
初期画像に対するプロンプトの強さが変わる感じですね.
CPUを全部使うようにしてみる(速度は変わらない)
しばらく動かしてみていると4コア中2コアしか使っていないように見えます.以下のISSUEを参考に4コア使うようにしてみましたが,他の方と同じように特に速度は変わらなかったので元に戻し( $ git restore stable_diffusion_engine.py
)ました.
$ git diff ./stable_diffusion_engine.py diff --git a/stable_diffusion_engine.py b/stable_diffusion_engine.py index f73541b..6c92198 100644 --- a/stable_diffusion_engine.py +++ b/stable_diffusion_engine.py @@ -27,6 +27,7 @@ class StableDiffusionEngine: self.scheduler = scheduler # models self.core = Core() + self.core.set_property("CPU", {"INFERENCE_NUM_THREADS": 4}) # text features self._text_encoder = self.core.read_model( hf_hub_download(repo_id=model, filename="text_encoder.xml"),
プロンプト(呪文)の作り方
まずは他の方のプロンプトを真似させてもらうのがお手軽です.Memeplex.appだとギャラリーで気に入ったものをクリックするとプロンプトが表示されるのでそれをコピーしてカスタマイズするといいです.ちなみにMemeplexはプリセットが充実しているので便利です.SEEDや英語翻訳後のプロンプトも表示されるのでべつのStable Diffusionに指定することも出来ます.
The Ai Art も便利で,構図やフィルタなどの例がたくさん紹介されています.Cyberpunk styleを多用しがち…….
Twitterで「#StableDiffusion」などで検索するとたくさんの画像が出てきてプロンプトが記載されていることが多いです.
プロンプトの不明な画像は以下のsiteでプロンプトを推測してもらうことが出来ます.自分の生成した画像を入れてみましたが自分のプロンプトとはかけ離れたものが出てきました.あくまで推測ですね.
$ git log -1 commit 294dd34234f0629f69d5af5b1190841560242969 (HEAD -> master, origin/master, origin/HEAD) Author: Brian Foley <bpfoley@gmail.com> Date: Mon Sep 5 09:25:43 2022 -0400 Update requirements.txt (#39) Add ftfy 6.1.1 to stop OpenAIGPTTokenizer's warning/fallback to BERT BasicTokenizer. $ dpkg-query -W python3 python3 3.9.2-3 $ lsb_release -dr Description: Debian GNU/Linux 11 (bullseye) Release: 11 $ lscpu | grep ^Model\ name: Model name: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz $ cat /proc/meminfo | grep MemTotal: MemTotal: 8019112 kB