コア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 |
詳細については、「パフォーマンスベンチマークに関する重要な注意事項」セクションを参照してください。
ステップ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 -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 プロジェクトをビルドするには、次のものが必要です。
--bundle-resources-for-swift-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.mlmodelcor&(ノイズ除去オートエンコーダーモデル)
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 |
詳細については、「パフォーマンスベンチマークに関する重要な注意事項」セクションを参照してください。
python_coreml_stable_diffusion.pipeline
StableDiffusion
tokenizer.model_max_length
--compute-unit
--attention-implementation
異なる演算ユニットを使用して生成された画像間でわずかな違いがある可能性が高いです。
以下の画像は、M1 MacBook ProおよびmacOS 13.1で、滑走路ml/stable-diffusion-v1-5モデルバージョンを使用して「火星で馬に乗っている宇宙飛行士の写真」というプロンプトで生成されました。ランダムシードは93に設定されました。
CPU_AND_NE | CPU_AND_GPU | すべての |
---|---|---|
![]() |
![]() |
![]() |
異なる入力では、違いが少なくなったり、顕著になったりする場合があります。詳しい説明はFAQQ8をご覧ください。
ERROR: Failed building wheel for tokenizers or error: can't find Rust compiler
回答1:この潜在的な解決策を確認してください。
RuntimeError: {NSLocalizedDescription = "Error computing NN outputs."
A2:このエラーには多くの潜在的な原因があります。このコンテキストでは、システムが他のアプリケーションからのメモリ負荷が増加している場合に発生する可能性が高くなります。他のアプリケーションのメモリ使用率を減らすと、問題の軽減に役立つ可能性があります。
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>
A4:はい!特にオプションは、他のアプリケーションからの妥当なシステム負荷の下で機能するはずです。サンプル結果の一部は、8GBのRAMを搭載したM2 MacBook Airを使用して生成されたことに注意してください。
--compute-unit CPU_AND_NE
A5:はい、Swiftライブラリを使用すると、これがほんの数秒に短縮されます。その理由は、Core ML モデル () をロードし、各モデルはロード時に要求されたコンピューティング ユニットで実行するようにコンパイルされるためです。unetモデルの操作のサイズと数のため、ニューラルエンジンの実行用にコンパイルするのに約2〜3分かかります。他のモデルはせいぜい数秒かかります。後のロードのためにコンパイルされたモデルをキャッシュしないため、各ロードに等しく時間がかかります。コンパイルキャッシュの恩恵を受けるために、SwiftパッケージはデフォルトでコンパイルされたCore MLモデル()に依存しており、最初のロード時に要求されたコンピューティングユニット用にコンパイルされますが、キャッシュは使用不足のためにパージされるまで後続のロードで再利用されます。
coremltools
.mlpackage
coremltools
StableDiffusion
.mlmodelc
StableDiffusion
A6:このセクションでは、SDK と OS の最小バージョンと、このパッケージでサポートされているデバイス モデルについて説明します。これらの要件に加えて、ベスト プラクティスとして、展開ターゲットの中で使用可能な RAM の量が最も少ないデバイスでパッケージをテストすることをお勧めします。これは、使用中に実行時に約2.6GBのピークメモリを消費します(Swiftに相当)。他のコンピューティングユニットは、ピークメモリ消費量が多い可能性があるため、iOSおよびiPadOSの展開に推奨されます(デバイスモデルの最小要件については、このセクションを参照してください)。画像の生成中にアプリがクラッシュした場合は、Xcodeプロジェクトにメモリ制限の増加機能を追加して、アプリのメモリ制限を大幅に増加させてみてください。
StableDiffusion
.cpuAndNeuralEngine
coremltools.ComputeUnit.CPU_AND_NE
.cpuAndNeuralEngine
A7:現在のバージョンは、単一モデルのマルチ解像度をすぐにサポートしていません。ただし、開発者はこのプロジェクトをフォークし、coremltools の柔軟なシェイプのサポートを利用して、を使用してスクリプトを拡張することができます。画像の解像度に左右されませんが、モデルの入力と出力は目的の画像解像度に依存することに注意してください。
python_coreml_stable_diffusion
torch2coreml
coremltools.EnumeratedShapes
text_encoder
vae_decoder
unet
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 の重みとアクティブ化があります。これは大きな違いの原因になるとは予想されていません。
A9:推奨されるオプションは、アプリの初回起動時にこれらのアセットをダウンロードするようにユーザーに求めることです。これにより、アプリのバイナリ サイズは、デプロイされる Core ML モデルから独立しています。ダウンロードのサイズをユーザーに開示することは、ユーザーが快適ではない可能性のあるデータ料金やストレージへの影響がある可能性があるため、非常に重要です。