在 Apple Silicon 上透過 Core ML 使用 Stable Diffusion
感謝蘋果公司的工程師們,你現在可以在 Apple Silicon 上透過 Core ML 執行 Stable Diffusion 了!
這個 Apple 的 repo 提供了基於 🧨 Diffusers 的轉換指令碼和推理程式碼,我們非常喜歡!為了讓你儘可能輕鬆地使用,我們自己轉換了權重,並將模型的 Core ML 版本放在了 Hugging Face Hub 上。
更新:在這篇文章釋出幾周後,我們建立了一個原生的 Swift 應用,你可以用它在自己的硬體上輕鬆執行 Stable Diffusion。我們在 Mac App Store 上釋出了一個應用,並開源了原始碼,以允許其他專案使用它。
本文的其餘部分將指導你如何在自己的程式碼中使用轉換後的權重,或者自己轉換其他權重。
可用的 checkpoints
官方的 Stable Diffusion checkpoints 已經轉換完畢並可供使用
- Stable Diffusion v1.4: 轉換版 原始版
- Stable Diffusion v1.5: 轉換版 原始版
- Stable Diffusion v2 base: 轉換版 原始版
- Stable Diffusion v2.1 base: 轉換版 原始版
Core ML 支援你裝置上所有可用的計算單元:CPU、GPU 和蘋果的神經網路引擎 (NE)。Core ML 還可以將模型的不同部分在不同裝置上執行以最大化效能。
每個模型都有幾個變體,根據你使用的硬體可能會產生不同的效能。我們建議你嘗試一下,並選擇在你的系統上效果最好的那個。詳情請繼續閱讀。
效能說明
每個模型有幾個變體
- “Original” attention vs “split_einsum”。這是關鍵的 attention 模組的兩種替代實現。
split_einsum
是由蘋果之前引入的,並且與所有計算單元 (CPU、GPU 和蘋果的神經網路引擎) 相容。而original
只與 CPU 和 GPU 相容。儘管如此,original
在某些裝置上可能比split_einsum
更快,所以一定要試試! - “ML Packages” vs “Compiled” 模型。前者適用於 Python 推理,而
compiled
版本是 Swift 程式碼所必需的。Hub 中的compiled
模型將大型 UNet 模型權重分割成多個檔案,以相容 iOS 和 iPadOS 裝置。這對應於--chunk-unet
轉換選項。
在撰寫本文時,我們在我的 MacBook Pro (M1 Max, 32 核 GPU, 64 GB) 上使用以下組合獲得了最佳結果
original
attention。all
計算單元 (詳見下一節)。- macOS Ventura 13.1 Beta 4 (22C5059b)。
有了這些,使用 Core ML 版本的 Stable Diffusion v1.4 生成一張圖片需要 18 秒 🤯。
⚠️ 注意
macOS Ventura 13.1 中引入了對 Core ML 的幾項改進,這些改進是 Apple 實現所必需的。如果你使用舊版本的 macOS,可能會得到黑色的圖片——並且速度會慢得多。
每個模型倉庫都以樹狀結構組織,提供了這些不同的變體
coreml-stable-diffusion-v1-4
├── README.md
├── original
│ ├── compiled
│ └── packages
└── split_einsum
├── compiled
└── packages
你可以如下所示下載並使用你需要的變體。
在 Python 中使用 Core ML 進行推理
先決條件
pip install huggingface_hub
pip install git+https://github.com/apple/ml-stable-diffusion
下載模型 Checkpoints
要在 Python 中執行推理,你必須使用儲存在 packages
資料夾中的版本之一,因為編譯後的版本只與 Swift 相容。你可以選擇使用 original
還是 split_einsum
的 attention 風格。
以下是如何從 Hub 下載 original
attention 變體的方法
from huggingface_hub import snapshot_download
from pathlib import Path
repo_id = "apple/coreml-stable-diffusion-v1-4"
variant = "original/packages"
model_path = Path("./models") / (repo_id.split("/")[-1] + "_" + variant.replace("/", "_"))
snapshot_download(repo_id, allow_patterns=f"{variant}/*", local_dir=model_path, local_dir_use_symlinks=False)
print(f"Model downloaded at {model_path}")
以上程式碼會將下載的模型快照放在一個名為 models
的目錄中。
推理
下載模型快照後,執行推理最簡單的方法是使用 Apple 的 Python 指令碼。
python -m python_coreml_stable_diffusion.pipeline --prompt "a photo of an astronaut riding a horse on mars" -i models/coreml-stable-diffusion-v1-4_original_packages -o </path/to/output/image> --compute-unit ALL --seed 93
<output-mlpackages-directory>
應該指向你在上一步下載的 checkpoint,而 --compute-unit
則指明你希望用於推理的硬體。它必須是以下選項之一:ALL
、CPU_AND_GPU
、CPU_ONLY
、CPU_AND_NE
。你也可以提供一個可選的輸出路徑,以及一個用於可復現性的種子 (seed)。
推理指令碼假設使用的是 Stable Diffusion 模型的原始版本,該版本儲存在 Hub 上的 CompVis/stable-diffusion-v1-4
。如果你使用其他模型,你*必須*在推理命令列中使用 --model-version
選項指定其 Hub id。這對於已經支援的模型和你自己訓練或微調的自定義模型都適用。
對於 Stable Diffusion 1.5 (Hub id: runwayml/stable-diffusion-v1-5
)
python -m python_coreml_stable_diffusion.pipeline --prompt "a photo of an astronaut riding a horse on mars" --compute-unit ALL -o output --seed 93 -i models/coreml-stable-diffusion-v1-5_original_packages --model-version runwayml/stable-diffusion-v1-5
對於 Stable Diffusion 2 base (Hub id: stabilityai/stable-diffusion-2-base
)
python -m python_coreml_stable_diffusion.pipeline --prompt "a photo of an astronaut riding a horse on mars" --compute-unit ALL -o output --seed 93 -i models/coreml-stable-diffusion-2-base_original_packages --model-version stabilityai/stable-diffusion-2-base
在 Swift 中使用 Core ML 進行推理
在 Swift 中執行推理比在 Python 中稍快,因為模型已經編譯成 mlmodelc
格式。這在應用啟動載入模型時會很明顯,但如果你之後執行多次生成,則不應明顯。
下載
要在你的 Mac 上用 Swift 執行推理,你需要一個 compiled
版本的 checkpoint。我們建議你使用類似於我們上面展示的 Python 程式碼在本地下載它們,但要使用 compiled
變體之一
from huggingface_hub import snapshot_download
from pathlib import Path
repo_id = "apple/coreml-stable-diffusion-v1-4"
variant = "original/compiled"
model_path = Path("./models") / (repo_id.split("/")[-1] + "_" + variant.replace("/", "_"))
snapshot_download(repo_id, allow_patterns=f"{variant}/*", local_dir=model_path, local_dir_use_symlinks=False)
print(f"Model downloaded at {model_path}")
推理
要執行推理,請克隆 Apple 的倉庫
git clone https://github.com/apple/ml-stable-diffusion
cd ml-stable-diffusion
然後使用 Swift Package Manager 的功能來執行 Apple 的命令列工具
swift run StableDiffusionSample --resource-path models/coreml-stable-diffusion-v1-4_original_compiled --compute-units all "a photo of an astronaut riding a horse on mars"
你必須在 --resource-path
中指定上一步下載的 checkpoint 之一,所以請確保它包含副檔名為 .mlmodelc
的已編譯 Core ML 包。--compute-units
的值必須是以下之一:all
、cpuOnly
、cpuAndGPU
、cpuAndNeuralEngine
。
更多詳情,請參考Apple 倉庫中的說明。
使用你自己的模型
如果你建立了自己與 Stable Diffusion 相容的模型 (例如,如果你使用了 Dreambooth、Textual Inversion 或微調),那麼你必須自己轉換模型。幸運的是,Apple 提供了一個轉換指令碼,可以讓你做到這一點。
對於這項任務,我們建議你遵循這些說明。
下一步
我們對這帶來的機會感到非常興奮,並迫不及待地想看看社群能從中創造出什麼。一些潛在的想法是
- 適用於 Mac、iPhone 和 iPad 的原生、高質量應用。
- 將更多的排程器引入 Swift,以實現更快的推理。
- 額外的流水線和任務。
- 探索量化技術和進一步的最佳化。
期待看到你的創作!