如何在 Core ML 上运行 Stable Diffusion
Core ML 是 Apple 框架支持的模型格式和机器学习库。如果您有兴趣在 macOS 或 iOS/iPadOS 应用程序中运行 Stable Diffusion 模型,本指南将向您展示如何将现有的 PyTorch 检查点转换为 Core ML 格式,并在 Python 或 Swift 中使用它们进行推理。
Core ML 模型可以利用 Apple 设备中所有可用的计算引擎:CPU、GPU 和 Apple 神经引擎(或 ANE,一种在 Apple Silicon Mac 和现代 iPhone/iPad 中可用的张量优化加速器)。根据模型和其运行的设备,Core ML 也可以混合匹配计算引擎,例如,模型的某些部分可能在 CPU 上运行,而其他部分在 GPU 上运行。
您还可以在 Apple Silicon Mac 上使用 PyTorch 中内置的 mps
加速器运行 diffusers
Python 代码库。这种方法在 mps 指南 中进行了深入的解释,但它与原生应用程序不兼容。
Stable Diffusion Core ML 检查点
Stable Diffusion 权重(或检查点)存储在 PyTorch 格式中,因此您需要将它们转换为 Core ML 格式,然后才能在原生应用程序中使用它们。
幸运的是,Apple 工程师基于 diffusers
开发了 一个转换工具,用于将 PyTorch 检查点转换为 Core ML。
但是,在转换模型之前,请花点时间探索 Hugging Face Hub - 您感兴趣的模型很可能已经以 Core ML 格式提供。
- the Apple 组织包含 Stable Diffusion 版本 1.4、1.5、2.0 基础版和 2.1 基础版
- coreml 社区 包含定制微调模型
- 使用此 过滤器 返回所有可用的 Core ML 检查点
如果您找不到您感兴趣的模型,建议您按照 Apple 提供的 将模型转换为 Core ML 的说明进行操作。
选择要使用的 Core ML 变体
Stable Diffusion 模型可以转换为不同的 Core ML 变体,这些变体针对不同的目的而设计。
使用的注意力块类型。注意力操作用于“关注”图像表示中不同区域之间的关系,并了解图像和文本表示之间的关系。注意力是计算密集型和内存密集型的,因此存在考虑不同设备硬件特性的不同实现。对于 Core ML Stable Diffusion 模型,有两种注意力变体。
split_einsum
(由 Apple 引入)针对 ANE 设备进行了优化,ANE 设备在现代 iPhone、iPad 和 M 系列计算机中可用。- “原始”注意力(
diffusers
中使用的基本实现)仅与 CPU/GPU 兼容,而不与 ANE 兼容。与 ANE 相比,使用original
注意力在 CPU + GPU 上运行您的模型可能更快。请参阅 此性能基准测试 以及 社区提供的其他测量方法 以获取更多详细信息。
支持的推理框架。
packages
适用于 Python 推理。这可用于在尝试将转换后的 Core ML 模型集成到原生应用程序中之前对其进行测试,或者如果您想探索 Core ML 的性能,但不需要支持原生应用程序。例如,具有 Web UI 的应用程序可以完美地使用 Python Core ML 后端。compiled
模型是 Swift 代码所必需的。Hub 中的compiled
模型将大型 UNet 模型权重拆分为多个文件,以与 iOS 和 iPadOS 设备兼容。这对应于--chunk-unet
转换选项。如果您想支持原生应用程序,则需要选择compiled
变体。
官方的 Core ML Stable Diffusion 模型 包含这些变体,但社区变体可能有所不同。
coreml-stable-diffusion-v1-4
├── README.md
├── original
│ ├── compiled
│ └── packages
└── split_einsum
├── compiled
└── packages
您可以下载并使用您需要的变体,如下所示。
Python 中的 Core ML 推理
安装以下库以在 Python 中运行 Core ML 推理
pip install huggingface_hub pip install git+https://github.com/apple/ml-stable-diffusion
下载模型检查点
要在 Python 中运行推理,请使用 packages
文件夹中存储的版本之一,因为 compiled
版本仅与 Swift 兼容。您可以选择是否要使用 original
或 split_einsum
注意力。
以下是如何从 Hub 下载 original
注意力变体到名为 models
的目录
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}")
推理
下载模型快照后,可以使用 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 CPU_AND_GPU --seed 93
将下载的检查点路径与-i
标记一起传递给脚本。--compute-unit
指示您要允许用于推理的硬件。它必须是以下选项之一:ALL
、CPU_AND_GPU
、CPU_ONLY
、CPU_AND_NE
。您还可以提供一个可选的输出路径和一个用于可重复性的种子。
推理脚本假定您使用的是 Stable Diffusion 模型的原始版本,CompVis/stable-diffusion-v1-4
。如果您使用其他模型,则**必须**在推理命令行中使用--model-version
选项指定其 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
Swift 中的 Core ML 推理
在 Swift 中运行推理比在 Python 中略快,因为模型已在mlmodelc
格式中编译。这在应用程序启动时加载模型时很明显,但在您随后运行几次生成时应该不明显。
下载
要在 Mac 上使用 Swift 运行推理,您需要一个compiled
检查点版本。建议您使用类似于上一个示例的 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
然后使用 Apple 的命令行工具,Swift Package Manager
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
中指定上一步中下载的检查点之一,因此请确保它包含具有扩展名.mlmodelc
的已编译 Core ML 捆绑包。--compute-units
必须是以下值之一:all
、cpuOnly
、cpuAndGPU
、cpuAndNeuralEngine
。
有关更多详细信息,请参阅Apple 仓库中的说明。
支持的 Diffusers 功能
Core ML 模型和推理代码不支持 🧨 Diffusers 的许多功能、选项和灵活性。以下是一些需要注意的限制。
- Core ML 模型仅适用于推理。它们不能用于训练或微调。
- 仅将两个调度器移植到 Swift,即 Stable Diffusion 使用的默认调度器和
DPMSolverMultistepScheduler
,我们从我们的diffusers
实现中将其移植到 Swift。建议您使用DPMSolverMultistepScheduler
,因为它在大约一半的步骤中产生相同的质量。 - 负面提示、无分类器引导比例和图像到图像任务在推理代码中可用。深度引导、ControlNet 和潜在上采样等高级功能目前不可用。
Apple 的转换和推理仓库以及我们自己的swift-coreml-diffusers仓库旨在作为技术演示,使其他开发人员能够在此基础上构建。
如果您强烈认为缺少任何功能,请随时提出功能请求,或者更好的是,贡献 PR 🙂。
原生 Diffusers Swift 应用程序
在您自己的 Apple 硬件上运行 Stable Diffusion 的一种简单方法是使用我们基于diffusers
和 Apple 的转换和推理仓库的开源 Swift 仓库。您可以研究代码,使用Xcode进行编译并根据自己的需求进行调整。为了方便起见,App Store 中还提供了一个独立的 Mac 应用程序,因此您可以使用它而不必处理代码或 IDE。如果您是开发人员并确定 Core ML 是构建 Stable Diffusion 应用程序的最佳解决方案,那么您可以使用本指南的其余部分来开始您的项目。我们迫不及待地想看看您将构建什么 🙂。