如何在 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 上运行。
Stable Diffusion Core ML 检查点
Stable Diffusion 权重(或检查点)存储在 PyTorch 格式中,因此在我们可以在原生应用中使用它们之前,需要将它们转换为 Core ML 格式。
幸运的是,Apple 工程师开发了 一个转换工具,基于 diffusers
将 PyTorch 检查点转换为 Core ML。
不过,在转换模型之前,请花点时间浏览 Hugging Face Hub——你感兴趣的模型可能已经以 Core ML 格式提供:
- Apple 组织包括 Stable Diffusion 1.4、1.5、2.0 基础版和 2.1 基础版
- coreml community 包括自定义微调模型
- 使用此 过滤器 查找所有可用的 Core ML 检查点
如果你找不到你感兴趣的模型,我们建议你按照 Apple 提供的 将模型转换为 Core ML 的说明进行操作。
选择要使用的 Core ML 变体
Stable Diffusion 模型可以转换为不同的 Core ML 变体,这些变体适用于不同的用途:
注意力块的类型。注意力操作用于“关注”图像表示中不同区域之间的关系,以及图像和文本表示之间的关系。注意力计算和内存密集,因此存在不同的实现,这些实现考虑了不同设备的硬件特性。对于 Core ML Stable Diffusion 模型,有两种注意力变体:
支持的推理框架。
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
snapshot_download(repo_id="model-repo", local_dir="models", allow_patterns="packages/*")
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}")
推理[[python-inference]]
一旦你下载了模型的快照,就可以使用 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/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。这适用于已经支持的模型和你自己训练或微调的自定义模型。
例如,如果你想使用 stable-diffusion-v1-5/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 stable-diffusion-v1-5/stable-diffusion-v1-5
Core ML 推理在 Swift 中
在 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}")
推理[[swift-inference]]
要运行推理,请克隆 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 默认使用的调度器,另一个是我们从
diffusers
实现中移植的DPMSolverMultistepScheduler
。我们建议你使用DPMSolverMultistepScheduler
,因为它在大约一半的步骤中产生相同的质量。 - 负面提示、无分类器引导比例和图像到图像任务在推理代码中可用。高级功能如深度引导、ControlNet 和潜在上采样器尚未可用。
Apple 的 转换和推理仓库 和我们自己的 swift-coreml-diffusers 仓库旨在作为技术演示,以帮助其他开发者构建自己的项目。
如果你对任何缺失的功能有强烈需求,请随时打开一个功能请求,或者更好的是,提交一个贡献 PR 🙂。
原生 Diffusers Swift 应用
在你自己的 Apple 硬件上运行 Stable Diffusion 的一种简单方法是使用 我们的开源 Swift 仓库,该仓库基于 diffusers
和 Apple 的转换和推理仓库。你可以研究代码,使用 Xcode 编译并根据自己的需求进行调整。为了方便起见,App Store 中还有一个 独立的 Mac 应用,因此你可以在不处理代码或 IDE 的情况下进行尝试。如果你是开发者,并且确定 Core ML 是构建你的 Stable Diffusion 应用的最佳解决方案,那么你可以使用本指南的其余部分开始你的项目。我们迫不及待想看看你会构建什么 🙂。