Swift で Core ML Stable Diffusion を実行しようとするとエラーが起こる

2023年6月29日

Appleシリコンに最適化された Stable Diffusion(Core ML Stable Diffusion) を Swift で画像生成をする場合,python と違って複数の画像を同時生成できるらしい。

ただ,README.md にあるコマンドを打ってもエラーが返ってきて実行できない。エラーメッセージを見ると,何らかのライブラリが見つからないらしい。

ググって調べてみると,Swift のバージョンが低いようである。

たしかに,README.md に書いてある実行環境では Xcode のバージョンが 15.0 になっている。
自分の環境(Xcode)は,最新版だが 14 になる。

そこで,Xcode の beta 版をダウンロードし,あわせてコマンドラインツールもインストールする。

コマンドラインツールは,Xcode の環境設定から使用するバージョンを選ばないと,ターミナルでの実行時に「コマンドラインツールが見つからない」とエラーが出るので注意。

% swift --version
swift-driver version: 1.82.2 Apple Swift version 5.9 (swiftlang-5.9.0.114.10 clang-1500.0.29.1)
Target: arm64-apple-macosx13.0

これで swift のバージョンが 5.9 になったのも確認できた。

早速 SatableDiffusionSample のオプションを確認する。

% swift run StableDiffusionSample --help
Building for debugging…
Build complete! (0.22s)
OVERVIEW: Run stable diffusion to generate images guided by a text prompt

USAGE: stable-diffusion-sample []

ARGUMENTS:
Input string prompt

OPTIONS:
--negative-prompt
Input string negative prompt
--resource-path
Path to stable diffusion resources. (default: ./)
The resource directory should contain
- compiled models: {TextEncoder,Unet,VAEDecoder}.mlmodelc
- tokenizer info: vocab.json, merges.txt
--image  Path to starting image.
--strength Strength for image2image. (default: 0.5)
--image-count
Number of images to sample / generate (default: 1)
--step-count
Number of diffusion steps to perform (default: 50)
--save-every
How often to save samples at intermediate steps
(default: 0)
Set to 0 to only save the final sample
--output-path
Output path (default: ./)
--seed Random seed (default: 3042604697)
--guidance-scale
Controls the influence of the text prompt on sampling
process (0=random images) (default: 7.5)
--compute-units
Compute units to load model with
{all,cpuOnly,cpuAndGPU,cpuAndNeuralEngine} (default:
all)
--scheduler Scheduler to use, one of {pndm, dpmpp} (default: pndm)
--rng Random number generator to use, one of {numpy, torch}
(default: numpy)
--controlnet
ControlNet models used in image generation (enter
file names in Resources/controlnet without extension)
--controlnet-inputs
image for each controlNet model (corresponding to the
same order as --controlnet)
--disable-safety Disable safety checking
--reduce-memory Reduce memory usage
--use-multilingual-text-encoder
Use system multilingual NLContextualEmbedding as
encoder model
--script

上がオプションである(直貼り)。

全く swift は触らないのだが,毎回ビルドするのだろうか。

ちょっと試しに,TrinArt を使ってテスト。
プロンプトは,「手を高く上げる少女」「ファンタジー」を加えてみた。
生成枚数は3枚。

% swift run StableDiffusionSample \
"Girl raising right arm fantasy" \
--negative-prompt "lowres, (bad hands, fewer digits, bad anatomy, mutated limbs, extra limbs:1.4, Unclear face)" \
--resource-path trinart_characters_19.2m_stable_diffusion_v1/Resources/ \
--output-path output \
--image-count 3 \
--step-count 50 \
--compute-units cpuAndGPU
Building for debugging…
Build complete! (0.12s)
Loading resources and creating pipeline
(Note: This can take a while the first time using these resources)
Step 50 of 51 [mean: 0.51, median: 0.52, last 0.52] step/sec
Saved Girl_raising_right_arm_fantasy.0.2660956987.final.png
Saved Girl_raising_right_arm_fantasy.1.2660956987.final.png
Saved Girl_raising_right_arm_fantasy.2.2660956987.final.png

なんかそれっぽいのが生成できた。
どっかの誰かが書いている絵を拾ってきている,のでなかったら,ほんと生成AIすごいね。
ただ,指先など細かい部分はあやしいところもある。
細かい描写はまだ十分ではないとどこかで読んだので,今後に期待というところでしょうか。

あと,前はこんな結果が出なかったので,プロンプトに加えた「ファンタジー」がかなり重要な気がする。
試しにプロンプトから「ファンタジー」を外してみる。

% swift run StableDiffusionSample \
"Girl raising right arm" \
--negative-prompt "lowres, (bad hands, fewer digits, bad anatomy, mutated limbs, extra limbs:1.4, Unclear face)" \
--resource-path trinart_characters_19.2m_stable_diffusion_v1/Resources/ \
--output-path output \
--image-count 3 \
--step-count 50 \
--compute-units cpuAndGPU

先と同様,とくに,1枚目があやしいが,こんなもんでしょうか。
3枚目も雰囲気にだまされそうだが,右手はどうなってんだ。

最後に,プロンプトを Girl から Boy に変えてみる。

% swift run StableDiffusionSample \
"Boy raising right arm" \
--negative-prompt "lowres, (bad hands, fewer digits, bad anatomy, mutated limbs, extra limbs:1.4, Unclear face)" \
--resource-path trinart_characters_19.2m_stable_diffusion_v1/Resources/ \
--output-path output \
--image-count 3 \
--step-count 50 \
--compute-units cpuAndGPU
Building for debugging…
Build complete! (0.13s)
Loading resources and creating pipeline
(Note: This can take a while the first time using these resources)
Step 50 of 51 [mean: 0.50, median: 0.51, last 0.51] step/sec
Image 0 failed safety check and was not savedImage 1 failed safety check and was not savedSaved Boy_raising_right_arm.2.3638967655.final.png

2枚生成に失敗しているし,生成されたやつの左手もなんかおかしなことになってる。

safety check が何か分からないが,ちょっとググったところ,Stable Diffusion には,露骨な性・暴力描写(Explicit)を防ぐ機能が入っているそうな。それにひっかかったと考えてよいかな。

上で書いた「ファンタジー」を追加。

% swift run StableDiffusionSample \
"Boy raising right arm fantasy" \
--negative-prompt "lowres, (bad hands, fewer digits, bad anatomy, mutated limbs, extra limbs:1.4, Unclear face)" \
--resource-path trinart_characters_19.2m_stable_diffusion_v1/Resources/ \
--output-path output \
--image-count 3 \
--step-count 50 \
--compute-units cpuAndGPU
Building for debugging…
Build complete! (0.12s)
Loading resources and creating pipeline
(Note: This can take a while the first time using these resources)
Step 50 of 51 [mean: 0.50, median: 0.51, last 0.51] step/sec
Saved Boy_raising_right_arm_fantasy.0.4206095319.final.png
Saved Boy_raising_right_arm_fantasy.1.4206095319.final.png
Saved Boy_raising_right_arm_fantasy.2.4206095319.final.png

1枚目は,顔とか分からず,サイレントヒルチックな感じがする。ファンタジーよりホラーかな。

2枚目と3枚目は,それっぽいがよく見ると手が変。2枚目は指,3枚目は腕の先。

それっぽくはできているが。

step-count と image-count をもっと増やせば,より精度の高い作品が出るのかな。

また試してみます。


投稿に関連する記事抜粋

投稿記事のカテゴリやタグと同じ記事をランダム表示します。

 カテゴリ一覧

 雑談(171)
アニメ(19)/ゲーム(12)/ドラマ(3)/パソコン(36)/小説(3)/広島東洋カープ(16)/映画(11)/漫画(33)/音楽(61)
 製作記(89)
AI(4)/CakePHP(3)/CentOS(4)/JavaScript(JS)(9)/Nuxt.js(4)/Vue.js(18)/WordPress(23)/料理(10)