【Swift】Core ML Stable Diffusionを使ってみた(Apple Silicon)

Swift

AppleがApple Silicon向けにStable Diffusionを最適化したものを発表しました。
今回はこれを試してみます。

GitHub - apple/ml-stable-diffusion: Stable Diffusion with Core ML on Apple Silicon
Stable Diffusion with Core ML on Apple Silicon. Contribute to apple/ml-stable-diffusion development by creating an account on GitHub.

今回はコマンドラインからの実行までですが、
本記事の大半は占める環境構築してモデルを変換するまでの作業です。
ここで作成して変換済みのモデルはアプリへの組み込みでも必要となります。

アプリへの組み込みはこちらの記事です。

前置き

OSバージョンについて

macOS Ventura 13.1以降に最適化されたとの事ですが、
私は途中で気づいたので13.0.1でやりました。

この記事で扱う分には13以降であれば大丈夫です。

環境構築について

1から構築するとREADMEだけでは詰まるポイントが沢山あります。
環境構築から始める人はひとつずつ確実にこなしていって下さい。

私はこの類はWindowsでしかやっていなかったので、
エラーが何度も出て結構時間がかかりました。

Anacondaなので作った環境を削除すればやり直せるので、
困ったら環境の作成からやり直すと良いと思います。

モデル配布について

AppleがHugging Face Hubにて変換済みのStable Diffusionモデルを配布しています。
既存モデルをアプリに実装するだけの場合はそちらを利用できます。
GitHubリポジトリにREADMEにも書いてあります。

ただし、変換可能な環境を用意しておく事で、
自由にモデルを選んで使用する事ができるので、
1度環境構築しておく事をオススメします。

Command Line Tools for Xcodeについて

Command Line Tools for Xcodeが必要です。
インストールされていない場合はインストールして下さい。

Xcodeを複数利用している場合や、macOSのアップデートの際に設定がおかしくなっている場合があります。
以下のコマンドで確認して下さい。

~ % xcode-select -print-path
/Applications/Xcode.app/Contents/Developer

出力が上記にようになっていれば問題ありません。
設定がおかしくなっている場合は以下のコマンドで設定しなおして下さい。

sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer

Rustのインストール

まず前提としてRustのインストールをします。
Rustが無いとCore ML Stable Diffusionのインストールに失敗するからです。

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

途中で止まったら「1」を入力して進めて下さい。

インストールが終わったら指示通りに以下を実行しておきます。

source "$HOME/.cargo/env"

デフォルトではIntel Mac向けのツールチェインがインストールされます。
M1 Mac向けをインストールして変更します。

rustup toolchain install stable-aarch64-apple-darwin
rustup default stable-aarch64-apple-darwin

rustup toolchain listで以下のようになればOKです。

~ % rustup toolchain list                               
stable-aarch64-apple-darwin (default)
stable-x86_64-apple-darwin

python環境の構築

筆者はMacではpythonを使用していなかったので、まずはpython環境の構築をします。
直にインストールしてもいいとは思いますが、READMEでcondaと書いてあるのでAnacondaを入れます。

Anacondaのインストール

Anacondaは仮想環境を用いてpython環境を簡単に切り替えて使うことのできるツールです。

インストール方法は何でも良いですが今回はインストーラを使いました。

以下のURLにアクセスし下部までスクロールするとM1向けのインストーラがあります。
※画面上部にあるのはIntel Mac向けです。

Download Anaconda Distribution | Anaconda
Download Anaconda's open-source Distribution today. Discover the easiest way to perform Python/R data science and machine learning on a single machine.

インストーラに従って進めるだけで問題なく終わります。

インストールが終わった後にターミナルを起動するとAnacondaが有効になっています。
ターミナルが起動したままの場合は再起動して下さい。

自動的に有効になるのが嫌な場合は以下のコマンドを実行して下さい。

conda config --set auto_activate_base false

自動的に有効にしない場合はターミナル起動後に以下のコマンドで有効にします。

conda activate

なお自動的に有効になるのはbase環境ですが、
今回はCore ML Stable Diffusion用に環境を用意するのでbase環境は使用しません。

Core ML Stable Diffusion環境を構築する

ここからREADMEの中身に入って行きます。

まずはCore ML Stable Diffusion環境を構築します。
以下のコマンドを順に実行し環境の作成および有効化を行なって下さい。

conda create -n coreml_stable_diffusion python=3.8 -y
conda activate coreml_stable_diffusion

※削除方法
一発で成功したり、ダメなところを個別で入れ直す場合は不要ですが、
失敗時には削除してやり直すのが楽です。

conda remove -n coreml_stable_diffusion --all

tokenizersのインストール

Core ML Stable Diffusionに含まれているのですが、そのままだと後でエラーを吐くのでtokenizersだけ先にインストールします。

cloneするなどしてtokenizersのデータを取得して下さい。

git clone git@github.com:huggingface/tokenizers.git

tokenizers/bindings/pythonに移動します。
rustup toolchain listで以下のようにaarch64が使用される様になっていることを確認して下さい。

(coreml_stable_diffusion) python % rustup toolchain list
stable-aarch64-apple-darwin (default) (override)
stable-x86_64-apple-darwin

なっていない場合は以下のコマンドで変更します。

rustup default stable-aarch64-apple-darwin
rustup set default-host aarch64-apple-darwin

以下のコマンドでインストールします。

pip install -e .

Core ML Stable Diffusionのインストール

githubから直にインストールでも良さそうですが、
後で使うファイルもあるのでREADMEに従ってダウンロードしてからインストールします。

githubからCore ML Stable Diffusionのソースを持ってきましょう。
任意の場所でcloneします。※今回はcloneしましたが、別にzipで持ってきても良いです

git clone https://github.com/apple/ml-stable-diffusion.git

cloneが終わったらml-stable-diffusionのディレクトリに移動して以下のコマンドでインストール行います。

pip install -e .

Hugging Faceを利用する

まずはHugging Faceに登録して下さい。

Hugging Face – The AI community building the future.
We’re on a journey to advance and democratize artificial intelligence through open source and open science.

ユーザーアクセストークンを作成します。

Hugging Face – The AI community building the future.
We’re on a journey to advance and democratize artificial intelligence through open source and open science.

以下のコマンドを実行します。

pip install huggingface_hub
huggingface-cli login

loginを行うとアクセストークンが要求されるので、先に生成したアクセストークンを使用して下さい。
その後Add token as git credential?と聞かれますが、あって困らないと思ったのでYにしておきました。

モデルを変換する

CoreML用にモデルを変換します。

以下のコマンドを行うことでHugging Faceからモデルをダウンロードして変換します。

python -m python_coreml_stable_diffusion.torch2coreml --convert-unet --convert-text-encoder --convert-vae-decoder --convert-safety-checker -o <output-mlpackages-directory> --bundle-resources-for-swift-cli --chunk-unet

<output-mlpackages-directory>を出力先ディレクトリに変えて下さい。

最後の–bundle-resources-for-swift-cliはpythonで動かすだけなら要らないですが、
Swiftで稼働させたいなら必要です。

またiOSデバイスで使用する場合は–chunk-unetが必要とのことです。
Macで使用する場合はどちらでも良いそうですが、chunkした場合はPython pipelineと互換が無いそうです。
現在は–chunk-unetをつけてもchunkされていないファイルも生成されるので、今回はつけてしまっています。

出力ファイルは合計8.79GB程度になりました。
ダウンロードもそこそこ量行われている筈なので気をつけて下さい。
ちなみに–bundle-resources-for-swift-cliと–chunk-unetなしだと2.67GBでした。

なお今回はモデルバージョンを指定していないのでデフォルトのstable-diffusion-v1-4です。

他のモデルも試してみました。

pythonで画像を生成する

必要ファイル

pythonで画像を生成するのに必要なファイルはmlpackageファイルです。
先ほどの出力ディレクトリの中から以下のファイルを使用します。

  • Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_safety_checker.mlpackage
  • Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_text_encoder.mlpack
  • Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_unet.mlpackage
  • Stable_Diffusion_version_CompVis_stable-diffusion-v1-4_vae_decoder.mlpackage

unet_chunk1、unet_chunk2はここでは使用しません。
unetの代わりに使用するという事も出来ないので注意して下さい。

画像生成

画像の生成は以下のコマンドです

python -m python_coreml_stable_diffusion.pipeline --prompt "a photo of an astronaut riding a horse on mars" -i <output-mlpackages-directory> -o </path/to/output/image> --compute-unit ALL --seed 93

<output-mlpackages-directory>は先ほどのモデルファイルの出力ディレクトリです。
ファイル単体ではなくディレクトリを指定します。

</path/to/output/image>は画像ファイルの出力先です。

実行してしばらくしたらpromptを名前としたディレクトリが出来て中に画像ファイルがあります。
コマンドでseedを固定しているので同じ画像が生成される筈です。

Swiftで実行する

必要ファイル

ターミナルからSwiftで実行します。

–bundle-resources-for-swift-cliで作成される各種ファイルが必要になります。
必要なのは〜mlpackageではなくResourcesの中身です。

使用ファイルは以下のようになります。

  • merges.txt
  • SafetyChecker.mlmodelc
  • TextEncoder.mlmodelc
  • Unet.mlmodelc または UnetChunk1.mlmodelcとUnetChunk2.mlmodelc
  • VAEDecoder.mlmodelc
  • vocab.json

先ほどのモデルの変換で上記のオプションをつけていない場合は、
オプションを追加してもう一度モデルの変換を行なって下さい。

Unetについてですが、macOSの場合はどちらでもよく、
iOSデバイスの場合はchunk済みのものでなければなりません。
なお両方使用できる場合はUnet.mlmodelcが優先的に読み込まれます。

画像生成

ml-stable-diffusionのディレクトリに移動し、以下のコマンドを実行して下さい。

swift run StableDiffusionSample "a photo of an astronaut riding a horse on mars" --resource-path <output-mlpackages-directory>/Resources/ --seed 93 --output-path </path/to/output/image>

<output-mlpackages-directory>を先ほどのモデルファイルの出力ディレクトリにし、
</path/to/output/image>は画像の出力先を指定して下さい。

なおpythonの時とは異なりディレクトリが作成されず、指定先に直にpngができます。

seedを変更していなければpythonの時と全く同じものが出力されます。

最後に

今回はCore ML Stable Diffusionをインストールして実行しました。
コマンドラインからpythonとSwiftで実行まで行いました。

アプリに組み込む方法は以下の記事です。
SwiftUIで書いていますがStableDiffusionの実行コードはSwiftUIが直接影響しているわけではないので、
UIKitで使うつもりの方も参考になると思います。

なおApple siliconのiPadは持っていないのでiOS実機での動作確認は今の所考えていません。

コメント

  1. […] […]

タイトルとURLをコピーしました