ml-stable-diffusion - アップルシリコン上のコアMLによる安定拡散

(Stable Diffusion with Core ML on Apple Silicon)

Created at: 2022-11-16 08:48:18
Language: Python
License: NOASSERTION

コアML安定拡散

コアMLを使用したアップルシリコンでの安定した拡散の実行

このリポジトリは、次のもので構成されます。

  • python_coreml_stable_diffusion
    は、PyTorch モデルをコア ML 形式に変換し、Python のハギングフェイスディフューザーを使用して画像生成を実行するための Python パッケージです。
  • StableDiffusion
    は、開発者がアプリにイメージ生成機能をデプロイするための依存関係として Xcode プロジェクトに追加できる Swift パッケージです。Swiftパッケージは、によって生成されたコアMLモデルファイルに依存しています
    python_coreml_stable_diffusion

インストール中または実行時に問題が発生した場合は、FAQセクションを参照してください。

結果の例

ハギングフェイスハブで利用できる安定した拡散には多数のバージョンがあります。これらのモデルのうち 3 つの結果の例を以下に示します。

--model-version
安定性AI/安定拡散2塩基 CompVis/stable-diffusion-v1-4 滑走路ML/安定拡散-V1-5
アウトプット
M1 iPad Pro 8GB レイテンシ (秒) 29 38 38
M1 マックブックプロ 16GB レイテンシ (秒) 24 35 35
M2マックブックエア8GBレイテンシ(秒) 18 23 23

詳細については、「パフォーマンスベンチマークに関する重要な注意事項」セクションを参照してください。

モデルをコア ML に変換する

クリックして展開

ステップ1:Python 環境を作成し、依存関係をインストールします。

conda create -n coreml_stable_diffusion python=3.8 -y
conda activate coreml_stable_diffusion
cd /path/to/cloned/ml-stable-diffusion/repository
pip install -e .

ステップ2:Hugging Faceアカウントにログインまたは登録し、ユーザーアクセストークンを生成し、このトークンを使用して、ターミナルウィンドウで実行してHugging FaceAPIアクセスを設定します。

huggingface-cli login

ステップ3:ハギングフェイスハブで使用する安定した拡散のバージョンに移動し、その利用規約に同意します。デフォルトのモデルバージョンはCompVis/stable-diffusion-v1-4 です。モデルのバージョンは、次の手順で説明するように、ユーザーが変更できます。

ステップ4:ターミナルから次のコマンドを実行して、コアMLモデルファイルを生成します(

.mlpackage
)

python -m python_coreml_stable_diffusion.torch2coreml --convert-unet --convert-text-encoder --convert-vae-decoder --convert-safety-checker -o <output-mlpackages-directory>

警告:このコマンドは、数GB相当のPyTorchチェックポイントをハグフェイスからダウンロードします。

これは通常、M1 MacBook Proでは15〜20分かかります。正常に実行されると、安定拡散を構成する 4 つのニューラル ネットワーク モデルが PyTorch から Core ML () に変換され、指定されたものに保存されます。いくつかの追加の注目すべき議論:

.mlpackage
<output-mlpackages-directory>

  • --model-version
    : モデルのバージョンはデフォルトでCompVis/stable-diffusion-v1-4 です。開発者は、Hugging Face Hub で利用可能な他のバージョン、例えば stableai/stable-diffusion-2-base&runwayml/stable-diffusion-v1-5 を指定することができます。

  • --bundle-resources-for-swift-cli
    : 4つのモデルすべてをコンパイルし、テキストトークン化に必要なリソースとともにバンドルします。このフラグは、ディフューザーベースの Python パイプラインには必要ありません。
    <output-mlpackages-directory>/Resources

  • --chunk-unet
    : Unet モデルを 2 つのほぼ等しいチャンク (それぞれ 1 GB 未満の重み) に分割して、モバイル フレンドリーな展開を実現します。これは、iOS および iPadOS での ANE 展開に必要です。これは macOS では必要ありません。Swift CLIは、Unetモデルのチャンクバージョンと通常バージョンの両方を使用できますが、前者を優先します。Python パイプラインは macOS のみを対象としているため、チャンク化された unet は Python パイプラインと互換性がないことに注意してください。チャンキングは、Swift を使用したデバイス上の展開専用です。

  • --attention-implementation
    : デフォルトは、Apple Neural Engine へのトランスフォーマーのデプロイで説明されている実装です。非 ANE デプロイに使用する代替手段に切り替わります。詳細なガイダンスについては、「パフォーマンスベンチマーク」セクションを参照してください。
    SPLIT_EINSUM
    --attention-implementation ORIGINAL

  • --check-output-correctness
    : 元の PyTorch モデルの出力と最終的なコア ML モデルの出力を比較します。このフラグは RAM 消費量を大幅に増加させるため、デバッグ目的でのみ推奨されます。

Python による画像生成

クリックして展開

ディフューザーに基づく Python パイプラインの例を使用して、テキストから画像への生成を実行します。

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

利用可能なすべての引数については、ヘルプメニューを参照してください。いくつかの注目すべき議論:

python -m python_coreml_stable_diffusion.pipeline -h

  • -i
    : 上記の「モデルをコア ML に変換する」セクションのステップ 4 のディレクトリをポイントする必要があります。
    -o
  • --model-version
    : モデルをCore MLに変換するときにデフォルトのモデルバージョンをオーバーライドした場合は、ここで同じモデルバージョンを指定する必要があります。
  • --compute-unit
    : この特定の実装で最もパフォーマンスの高いコンピューティング ユニットは、ハードウェアによって異なる場合があることに注意してください。または、より高速である場合があります。詳細なガイダンスについては、「パフォーマンスベンチマーク」セクションを参照してください。
    CPU_AND_GPU
    CPU_AND_NE
    ALL
  • --scheduler
    : さまざまなスケジューラを試してみたい場合は、ここで指定できます。利用可能なオプションについては、ヘルプメニューを参照してください。また、推論ステップのカスタム数を指定することもできます。デフォルトは 50 です。
    --num-inference-steps

スウィフトによる画像生成

クリックして展開

システム要件

Swift プロジェクトをビルドするには、次のものが必要です。

  • macOS 13 以降
  • コマンドラインツールがインストールされているXcode 14.1以降。最新バージョンについてはdeveloper.apple.comを確認してください。
  • コア ML モデルとトークン化リソース。上記の「コア ML へのモデルの変換」セクションから参照してください。
    --bundle-resources-for-swift-cli

このモデルを次の場所にデプロイする場合:

  • アイフォン
    • iOS 16.2 以降
    • iPhone 12以降
  • アプリ
    • iPadOS 16.2 以降
    • M1 以降
  • マック
    • macOS 13.1以降
    • M1 以降

CLI の使用例

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>

出力には、プロンプトとランダムシードに基づいて名前が付けられます。 例えば。

</path/to/output/image>/a_photo_of_an_astronaut_riding_a_horse_on_mars.93.final.png

バッチ生成などについて学ぶためにフラグを使用してください。

--help

ライブラリの使用例

import StableDiffusion
...
let pipeline = try StableDiffusionPipeline(resourcesAt: resourceURL)
let image = try pipeline.generateImages(prompt: prompt, seed: seed).first

スウィフトパッケージの詳細

この Swift パッケージには、次の 2 つの製品が含まれています。

  • StableDiffusion
    図書館
  • StableDiffusionSample
    コマンド ライン ツール

どちらの製品でも、Core ML モデルとトークン化リソースを指定する必要があります。ディレクトリパスを使用してリソースを指定する場合、そのディレクトリには次のものが含まれている必要があります。

  • TextEncoder.mlmodelc
    (テキスト埋め込みモデル)
  • Unet.mlmodelc
    or&(ノイズ除去オートエンコーダーモデル)
    UnetChunk1.mlmodelc
    UnetChunk2.mlmodelc
  • VAEDecoder.mlmodelc
    (イメージデコーダモデル)
  • vocab.json
    (トークナイザー語彙ファイル)
  • merges.text
    (バイトペアエンコーディングファイルのマージ)

オプションで、安定拡散の一部のバージョンに含まれる安全性チェッカーモデルを含めることもできます。

  • SafetyChecker.mlmodelc

チャンク化されたバージョンの Unet が最初にチェックされることに注意してください。存在しない場合にのみ、fullbeがロードされます。チャンキングは iOS および iPadOS では必須であり、macOS では必要ありません。

Unet.mlmodelc

パフォーマンスベンチマーク

クリックして展開

標準コンプビジュアライゼーション/安定拡散-v1-4ベンチマーク

デバイス
--compute-unit
--attention-implementation
待機時間 (秒)
Mac Studio (M1 Ultra, 64-core GPU)
CPU_AND_GPU
ORIGINAL
9
Mac Studio (M1 Ultra, 48-core GPU)
CPU_AND_GPU
ORIGINAL
13
MacBook Pro (M1 Max, 32-core GPU)
CPU_AND_GPU
ORIGINAL
18
MacBook Pro (M1 Max, 24-core GPU)
CPU_AND_GPU
ORIGINAL
20
MacBook Pro (M1 Pro, 16-core GPU)
ALL
SPLIT_EINSUM (default)
26
マックブックプロ (M2)
CPU_AND_NE
SPLIT_EINSUM (default)
23
マックブックプロ(M1)
CPU_AND_NE
SPLIT_EINSUM (default)
35
iPad Pro (第 5 世代、M1)
CPU_AND_NE
SPLIT_EINSUM (default)
38

詳細については、「パフォーマンスベンチマークに関する重要な注意事項」セクションを参照してください。

パフォーマンスベンチマークに関する重要な注意事項

クリックして展開
  • このベンチマークは、2022年11月にiOS16.2、iPadOS16.2、およびmacOS13.1のパブリックベータ版を使用してAppleによって実施されました。
  • 実行されたプログラムはmacOSデバイス用であり、iOSおよびiPadOSデバイス用のSwiftパッケージ。
    python_coreml_stable_diffusion.pipeline
    StableDiffusion
  • 3 つのエンドツーエンド実行の中央値が報告されます。
  • パフォーマンスは、モデル自体のアーキテクチャの変更により、安定拡散のバージョンによって大きく異なる場合があります。報告される各番号は、そのコンテキストで言及されているモデルバージョンに固有です。
  • 画像生成手順は、標準構成に従います:50の推論ステップ、512x512の出力画像解像度、77のテキストトークンシーケンス長、分類器なしのガイダンス(unetの場合はバッチサイズ2)。
  • Core ML モデルは、入力テキストの実際の長さに関係なく、テキスト トークン シーケンス内の 77 個の要素 () すべてのフォワード パスを計算する静的図形に変換されるため、実際のプロンプトの長さはパフォーマンスに影響を与えません。
    tokenizer.model_max_length
  • 4つのモデル間のパイプライン処理は最適化されておらず、これらのパフォーマンス数値は、他のアプリケーションからのシステム負荷の増加によって変動する可能性があります。これらの要因を考慮して、待機時間の秒未満の分散は報告されません。
  • 重みとアクティブ化は、GPU と ANE の両方で float16 の精度です。
  • Swift CLIプログラムは、約2.6GB(セーフティチェッカーなし)のピークメモリを消費し、そのうち2.1GBはfloat16精度のモデル重みです。8ビットの重み量子化を適用し、ピーク時のメモリ消費量を約1GB削減しました。しかし、生成された画質に悪影響があることを観察し、ロールバックしました。開発者は、より良い結果が得られる可能性のある旺盛や剪定などの他の高度な重量圧縮技術を試すことをお勧めします。
  • ベンチマーク表では、デバイスごとの最高のパフォーマンスと値を報告します。前者は Core ML モデルを変更せず、実行時に適用できます。後者は、コアMLモデルを変更します。最もパフォーマンスの高いコンピューティング ユニットは、モデル バージョンとハードウェア固有であることに注意してください。
    --compute-unit
    --attention-implementation

異なる演算ユニットでの結果

クリックして展開

異なる演算ユニットを使用して生成された画像間でわずかな違いがある可能性が高いです。

以下の画像は、M1 MacBook ProおよびmacOS 13.1で、滑走路ml/stable-diffusion-v1-5モデルバージョンを使用して「火星で馬に乗っている宇宙飛行士の写真」というプロンプトで生成されました。ランダムシードは93に設定されました。

CPU_AND_NE CPU_AND_GPU すべての

異なる入力では、違いが少なくなったり、顕著になったりする場合があります。詳しい説明はFAQQ8をご覧ください。

FAQ

クリックして展開
質問1:
 ERROR: Failed building wheel for tokenizers or error: can't find Rust compiler 

回答1:この潜在的な解決策を確認してください。

質問2:
 RuntimeError: {NSLocalizedDescription = "Error computing NN outputs." 

A2:このエラーには多くの潜在的な原因があります。このコンテキストでは、システムが他のアプリケーションからのメモリ負荷が増加している場合に発生する可能性が高くなります。他のアプリケーションのメモリ使用率を減らすと、問題の軽減に役立つ可能性があります。

質問3:私のMacには8GBのRAMがあり、サンプルコマンドを使用してモデルをCore MLに変換しています。メモリの問題により、プロセスが強制終了されています。この問題を修正するにはどうすればよいですか?

A3:モデル変換プロセスのメモリへの影響を最小限に抑えるには、代わりに次のコマンドを実行します。

python -m python_coreml_stable_diffusion.torch2coreml --convert-vae-decoder -o <output-mlpackages-directory> && \
python -m python_coreml_stable_diffusion.torch2coreml --convert-unet -o <output-mlpackages-directory> && \
python -m python_coreml_stable_diffusion.torch2coreml --convert-text-encoder -o <output-mlpackages-directory> && \
python -m python_coreml_stable_diffusion.torch2coreml --convert-safety-checker -o <output-mlpackages-directory> &&

必要に応じて、以前にエクスポートされたUnetモデルを再利用し、単にそれを所定の位置にチャンクするさらに別の独立したコマンドでこれを行うことができます。

--chunk-unet

python -m python_coreml_stable_diffusion.torch2coreml --convert-unet --chunk-unet -o <output-mlpackages-directory>
質問4:私のMacには8GBのRAMが搭載されていますが、画像生成は私のマシンで機能する必要がありますか?

A4:はい!特にオプションは、他のアプリケーションからの妥当なシステム負荷の下で機能するはずです。サンプル結果の一部は、8GBのRAMを搭載したM2 MacBook Airを使用して生成されたことに注意してください。

--compute-unit CPU_AND_NE

質問5:Python パイプラインを使用して画像を生成するたびに、すべてのコア ML モデルの読み込みには 2 分から 3 分かかります。これは予期される動作ですか?

A5:はい、Swiftライブラリを使用すると、これがほんの数秒に短縮されます。その理由は、Core ML モデル () をロードし、各モデルはロード時に要求されたコンピューティング ユニットで実行するようにコンパイルされるためです。unetモデルの操作のサイズと数のため、ニューラルエンジンの実行用にコンパイルするのに約2〜3分かかります。他のモデルはせいぜい数秒かかります。後のロードのためにコンパイルされたモデルをキャッシュしないため、各ロードに等しく時間がかかります。コンパイルキャッシュの恩恵を受けるために、SwiftパッケージはデフォルトでコンパイルされたCore MLモデル()に依存しており、最初のロード時に要求されたコンピューティングユニット用にコンパイルされますが、キャッシュは使用不足のためにパージされるまで後続のロードで再利用されます。

coremltools
.mlpackage
coremltools
StableDiffusion
.mlmodelc

質問6:Swiftパッケージをモバイルアプリにデプロイしたいと思います。何に注意すべきですか?」
StableDiffusion

A6:このセクションでは、SDK と OS の最小バージョンと、このパッケージでサポートされているデバイス モデルについて説明します。これらの要件に加えて、ベスト プラクティスとして、展開ターゲットの中で使用可能な RAM の量が最も少ないデバイスでパッケージをテストすることをお勧めします。これは、使用中に実行時に約2.6GBのピークメモリを消費します(Swiftに相当)。他のコンピューティングユニットは、ピークメモリ消費量が多い可能性があるため、iOSおよびiPadOSの展開に推奨されます(デバイスモデルの最小要件については、このセクションを参照してください)。画像の生成中にアプリがクラッシュした場合は、Xcodeプロジェクトにメモリ制限の増加機能を追加して、アプリのメモリ制限を大幅に増加させてみてください。

StableDiffusion
.cpuAndNeuralEngine
coremltools.ComputeUnit.CPU_AND_NE
.cpuAndNeuralEngine

質問7:同じ Core ML モデルを使用して異なる解像度の画像を生成するにはどうすればよいですか?

A7:現在のバージョンは、単一モデルのマルチ解像度をすぐにサポートしていません。ただし、開発者はこのプロジェクトをフォークし、coremltools の柔軟なシェイプのサポートを利用して、を使用してスクリプトを拡張することができます。画像の解像度に左右されませんが、モデルの入力と出力は目的の画像解像度に依存することに注意してください。

python_coreml_stable_diffusion
torch2coreml
coremltools.EnumeratedShapes
text_encoder
vae_decoder
unet

質問8:Core ML と PyTorch で生成された画像は同じになりますか?

A8:必要に応じて、PyTorch と Core ML で生成された画像をほぼ同一にすることができます。ただし、デフォルトでは保証されていません。PyTorch と Core ML で異なるイメージにつながる可能性があるいくつかの要因があります。

1. 乱数ジェネレータの動作

PyTorch とコア ML で異なる可能性のある結果の主なソースは、乱数ジェネレーター (RNG) の動作です。PyTorch と Numpy はランダム性のソースが異なり、一般的に RNG (潜在初期化など) を Numpy に依存しており、Swift Library はこの RNG の動作を再現します。ただし、Hugging Face などの PyTorch ベースのパイプラインは、PyTorch の RNG 動作に依存しています。

python_coreml_stable_diffusion
StableDiffusion
diffusers

2.パイトーチ

「完全に再現可能な結果は、PyTorchのリリース、個々のコミット、または異なるプラットフォーム間で保証されるものではありません。さらに、同じシードを使用している場合でも、CPUとGPUの実行間で結果を再現できない場合があります。」(ソース)。

3. 変換時のモデル関数ドリフト

対応する PyTorch モデルとコア ML モデル間の出力の違いは、潜在的な原因です。シグナルインテグリティは変換プロセス中にテストされ(引数を介して有効)、ランダム入力でテストされた最小PSNR値を超えていることが確認されます。これは単なるサニティ チェックであり、すべての可能な入力でこの最小 PSNR を保証するものではないことに注意してください。さらに、異なるコンピューティング ユニット間で同じ Core ML モデルを実行した場合、結果が同一であることは保証されません。これは、このセクションでサンプルの視覚結果が示すように、大きな違いの原因になるとは予想されていません。

--check-output-correctness
python_coreml_stable_diffusion.torch2coreml

4. 重みとアクティベーションのデータ型

モデルを float32 から float16 などの低精度データ型に量子化する場合、同じ PyTorch モデルを使用している場合でも、生成される画像はセマンティクスが若干異なることがわかっています。coremltools によって生成されたコア ML モデルには、明示的にオーバーライドされない限り、既定で float16 の重みとアクティブ化があります。これは大きな違いの原因になるとは予想されていません。

質問9:モデルファイルは非常に大きいですが、アプリの大きなバイナリを避けるにはどうすればよいですか?

A9:推奨されるオプションは、アプリの初回起動時にこれらのアセットをダウンロードするようにユーザーに求めることです。これにより、アプリのバイナリ サイズは、デプロイされる Core ML モデルから独立しています。ダウンロードのサイズをユーザーに開示することは、ユーザーが快適ではない可能性のあるデータ料金やストレージへの影響がある可能性があるため、非常に重要です。