Core ML版Stable DiffusionをiOSで快適に動かす

11.2K Views

October 17, 23

スライド概要

「Mobile勉強会 Wantedly × チームラボ #11」での発表資料です。
https://wantedly.connpass.com/event/297601/

profile-image

フリーランスiOSエンジニア 「エンジニアと人生」コミュニティ主宰

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

Core ML版 Stable Diffusion を iOS で快適に動かす 堤 修一 @shu223

2.

自己紹介 • 堤 修一 • @shu223 (GitHub, Qiita, Zenn, note, 𝕏, YouTube, Podcast, etc...) • 書籍(商業出版4冊、個人出版多数 @BOOTH):

3.

• 1年間研究開発部のマネージャーにチャレンジ • 12年間iOSだけやってきたエンジニアのキャリアチェンジ • 2023年6月からエンジニアに復帰 • マネージャーからエンジニアに戻ります • 最近のお仕事 • タッチ名刺交換

4.

本日のお題について • ⭕ ❌ 「Stable Diffusion」という画像生成AIの解説 • 巨大なモデルをiOSで動かす際の考え方や勘所

5.

Stable Diffusionとは • 画像生成AI • 入力テキストに応じて画像を自動 生成するtext-to-imageモデル • 2022.8 オープンソースとして公開

6.

Core ML Stable Diffusion とは Core ML フォーマットに変換された Stable Diffusion のモデル • 従来のモデルをAppleハードウェアで動かす => CPUのみ利 用 • Core MLモデル => CPU, GPU, Neural Engineを利用 → Appleのハードウェアを最大限活かせるのがCore MLモデル 1 詳細な最適化の解説: Deploying Transformers on the Apple Neural Engine - Apple Machine Learning Research 1

7.

Core ML Stable Diffusion のリポジトリ https://github.com/apple/ml-stable-diffusion • Apple謹製 • モデル変換コード、macOS/iOSで動かすためのSwiftコード等 を含む • 公式ブログ記事: Stable Diffusion with Core ML on Apple Silicon - Apple Machine Learning Research

8.

初登場時以降の進化 2022年12月の初公開時以降あまり話題になっていないが、着々 と進化している • ControlNetサポート • SDXLサポート • 6ビット量子化(関連記事: 1, 2, 3) • Multilingual text encoder サポート • 関連記事: [iOS 17] 多言語BERT埋め込みモデルのサポー

9.

Core ML Stable Diffusion の何が嬉しいのか? • 手元のMacで、無料かつオフラインで使いまくれる • 自前のmacOS/iOSアプリに組み込める • For me: 様々なノウハウが詰まったCore MLの公式サンプル

10.

CLIから動かす Swiftで書かれたCLIサンプル StableDiffusionSampleを利用 swift run StableDiffusionSample \ "a photo of an astronaut riding a horse on mars" \ --resource-path </path/to/models> --seed 93 \ --output-path </path/to/output/image> • --resource-path • コンパイル済みCore MLモデルファイル .mlmodelc が 入ったディレクトリのパスを指定

11.

自作アプリに組み込む 1/2 Swift Package としてプロジェクトに追加する • → Package Product "StableDiffusion" をターゲットに追加

12.

自作アプリに組み込む 2/2 import StableDiffusion ... let pipeline = try StableDiffusionPipeline(resourcesAt: resourceURL) pipeline.loadResources() let image = try pipeline.generateImages(prompt: prompt, seed: seed).first

14.

Diffusers を iPhone 15 Pro で動かしてみる

15.

モデルのダウンロード (初回のみ必要)

16.

モデルのロード (起動毎に必要)

17.

⚠ ローディングがとてつもなく長い

18.

起動する度に 5分 2 Pipeline loaded in 293.2635090351105 2 モデルのダウンロードが完了した状態からの起動

19.

起動状態

20.

⚠ 画像生成時に必ずクラッシュ

21.

使用メモリ量のスパイク (iPhone 15 Pro利用)

22.

iOSで「まともに」動かす

23.

iOSでまともに動かす • 使用メモリ量を小さくする • 起動時間を短くする • 画像生成時間を短くする

24.

iOSでまともに動かす • 使用メモリ量を小さくする • 起動時間を短くする • 画像生成時間を短くする

25.

使用メモリ量を小さくする方法 • reduceMemory オプションを有効にする • サイズの小さいモデルに変更する

26.

使用メモリ量を小さくする方法 • ⭕ reduceMemory オプションを有効にする • サイズの小さいモデルに変更する

27.

reduceMemory を有効にする ModelInfo.swift の reduceMemory プロパティを決定する 処理を書き換える 3 var reduceMemory: Bool { // Enable on iOS devices, except when using quantization if runningOnMac { return false } if isXL { return !deviceHas8GBOrMore } return !(quantized && deviceHas6GBOrMore) } 3 現行実装ではiPhone 15 Proの場合は必ず無効化されてしまう

28.

reduceMemory を有効にするとどうなるか? • 必要なときにモデルをロードし、すぐにアンロードする • 画像生成処理のオーバーヘッドを増やすことになる • ドキュメントでは解説されていないが、ソースコードを見る と起動時に prewarmResources という処理を行っている public func loadResources() throws { if reduceMemory { try prewarmResources() } ...

29.

prewarmResources loadResources 後すぐに unloadResources を行う func prewarmResources() throws { try loadResources() unloadResources() } Both .mlpackage and .mlmodelc models are compiled upon first load. (中略) .mlmodelc files do cache this compiled asset and non-first load times are reduced to just a few seconds.

30.

デモ

31.

画像生成時にクラッシュしなくなった

32.

画像生成の処理時間 Got images: [Optional(<CGImage 0x12810d510> (IP) <<CGColorSpace 0x283e04780> (kCGColorSpaceDeviceRGB)> width = 768, height = 768, bpc = 8, bpp = 24, row bytes = 2304 kCGImageAlphaNone | 0 (default byte order) | kCGImagePixelFormatPacked is mask? No, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes)] in 83.99049496650696 1枚あたり 83.99 秒 起動時間も依然として 5分 かかっている

33.

iOSでまともに動かす • 使用メモリ量を小さくする • 起動時間を短くする • 画像生成時間を短くする

34.

起動時間を短くする方法 起動時間のほとんどが、モデルのロード (実態としては 4 MLModel の初期化)に時間がかかっている → サイズの小さいモデルに変更する 4 ライブラリ内の loadResources メソッド

35.

画像生成時間を短くする方法 サイズの小さいモデルに変更する The Neural Engine is capable of accelerating models with low-bit palettization: 1, 2, 4, 6 or 8 bits. (ニューラル・エンジンは、低 ビットのパレタイズでモデルを高速化できる) compressed weights are faster to fetch from memory ... (圧縮さ れたウェイトはメモリからのフェッチが高速になり、) 5 apple/ml-stable-diffusion: Stable Diffusion with Core ML on Apple Silicon のREADMEより 5

36.

(再掲)使用メモリ量を小さくする方法 ⭕ • reduceMemory オプションを有効にする • サイズの小さいモデルに変更する

37.

とにかくモデルの圧縮が重要

38.

現在の使用モデルを調べる 1/3 let loader = PipelineLoader(model: iosModel()) func iosModel() -> ModelInfo { guard deviceSupportsQuantization else { return ModelInfo.v21Base } if deviceHas6GBOrMore { return ModelInfo.xlmbpChunked } return ModelInfo.v21Palettized } → iPhone 15 Proでは ModelInfo.xlmbpChunked を利用 6 deviceSupportsQuantization が true かつ deviceHas6GBOrMore が true 6

39.

現在の使用モデルを調べる 2/3 static let xlmbpChunked = ModelInfo( modelId: "apple/coreml-stable-diffusion-xl-base-ios", modelVersion: "SDXL base (768, iOS) [4 bit]", supportsEncoder: false, quantized: true, isXL: true )

40.

現在の使用モデルを調べる 3/3 apple/coreml-stable-diffusion-xl-base-ios • iOS向けに 4.04 混合ビット量子化(mixed-bit palettization)したもの • ・・・ではあるが、もともとがSDXLモデルなのでクソでか い • Unetだけで 1.3 GB以上

41.

モデルを圧縮する or モデルの圧縮版を探す

42.

Hugging Face で公開されている Core ML Stable Diffusion モデル → 2023年10月現在で16種類

43.

! どれを選べばいいのか

44.

軽いSDモデルを選ぶポイント • SDXLではないもの・・・XLは最新の高画質版であり、デカ い • palletized とついているもの・・・圧縮されていることを示 す • 16bit -> 6-bit • SDバージョンの違いによるサイズの違いはあまりない → "apple/coreml-stable-diffusion-2-1-base-palettized"

45.

デモ

46.

各種パフォーマンス • 起動時間 :100秒前後(300%高速化) 7 • 使用メモリ量のピーク値 :約850MB 8 • 画像生成処理時間:10秒以下(800%高速化) 7 アプリの起動時間全体ではなく、パイプラインのロード時間を計測 8 サイズの小さいモデルの使用に伴い、reduceMemory は再び無効化した

47.

さらなる起動時間の短縮 モデルのロード(MLModelの初期化)が90%以上を占める time to load unet: 57.41793203353882 time to load textEncoder: 30.462964057922363 time to load decoder: 3.1042929887771606 time to load encoder: 2.146523952484131 Pipeline resources loaded in 106.28662097454071

48.

さらなるモデル圧縮 Mixed-Bit Palettization 公式リポジトリREADME の "Advanced Weight Compression (Lower than 6-bits)" に詳細あり

49.

more • ControlNet • Multilingual text encoder • 関連記事: [iOS 17] 多言語BERT埋め込みモデルのサポー ト

50.

まとめ Stable DiffusionのようなクソデカCore MLモデルをiOSで動かす • キャッシュ機構を利用して都度ロード & アンロード • → メモリ使用量を抑える • モデルサイズを小さくする • → 起動時間・メモリ使用量・画像生成時間すべて改善 • Hugging Face探す/coremltoolsで自前圧縮/Mixed-Bit Palettization

51.

ご清聴ありがとうございました!