感谢 Apple 工程师,您现在可以使用 Core ML 在 Apple Silicon 上运行 Stable Diffusion!
这个 Apple 存储库提供了基于🧨 Diffusers 的转换脚本和推理代码,我们喜欢它!为了让您尽可能轻松,我们自己转换了权重并将模型的 Core ML 版本放在Hugging Face Hub中。
这篇文章将指导您如何使用转换后的权重。可用检查点
已经转换并准备使用的检查点是这些模型的检查点: Core ML 支持您设备中可用的所有计算单元:CPU、GPU 和 Apple 的神经引擎 (NE)。Core ML 还可以在不同设备上运行模型的不同部分,以最大限度地提高性能。 每种型号都有多种变体,它们可能会产生不同的性能,具体取决于您使用的硬件。我们建议您试用它们并坚持使用最适合您系统的那个。继续阅读以了解详细信息。性能说明
每个模型有几个变体:- “原始”注意力与“split_einsum”。这是关键注意块的两个替代实现。之前由 Apple 推出split_einsum,兼容所有计算单元(CPU、GPU 和 Apple 的神经引擎)。,另一方面,仅与 CPU 和 GPU 兼容。尽管如此,它可能比某些设备更快,所以一定要检查一下!originaloriginalsplit_einsum
- “ML 包”与“编译”模型。前者适用于 Python 推理,而compiled版本则需要 Swift 代码。compiledHub 中的模型将大型 UNet 模型权重拆分为多个文件,以便与 iOS 和 iPadOS 设备兼容。这对应于—chunk-unet转换选项。
- original注意力。
- all计算单元(详见下一节)。
- macOS 文图拉 13.1 测试版 4 (22C5059b)。
⚠️__注意
macOS Ventura 13.1 测试版中引入了对 Core ML 的多项改进,它们是 Apple 实施所必需的。如果您使用 macOS Ventura (13.0.1) 的当前发行版,您可能会得到黑色图像——而且速度会慢得多。如果您不能或不会安装测试版,请等待 macOS Ventura 13.1 正式发布。
每个模型 repo 都以树结构组织,提供这些不同的变体:您可以下载并使用您需要的变体,如下所示。
coreml-stable-diffusion-v1-4
├── README.md
├── original
│ ├── compiled
│ └── packages
└── split_einsum
├── compiled
└── packages
Python 中的核心 ML 推理
先决条件
pip install huggingface_hub
pip install git+https://github.com/apple/ml-stable-diffusion
下载模型检查点
要在 Python 中运行推理,您必须使用存储在文件夹中的版本之一packages,因为编译后的版本仅与 Swift 兼容。您可以选择是否要使用original或split_einsum注意样式。original这就是您从 Hub下载注意力变体的方式:
上面的代码会将下载的模型快照放在您指定的目录中(models在本例中为 )。
from huggingface_hub import snapshot_download
from huggingface_hub.file_download import repo_folder_name
from pathlib import Path
import shutil
repo_id = "apple/coreml-stable-diffusion-v1-4"
variant = "original/packages"
def download_model(repo_id, variant, output_dir):
destination = Path(output_dir) / (repo_id.split("/")[-1] + "_" + variant.replace("/", "_"))
if destination.exists():
raise Exception(f"Model already exists at {destination}")
# Download and copy without symlinks
downloaded = snapshot_download(repo_id, allow_patterns=f"{variant}/*", cache_dir=output_dir)
downloaded_bundle = Path(downloaded) / variant
shutil.copytree(downloaded_bundle, destination)
# Remove all downloaded files
cache_folder = Path(output_dir) / repo_folder_name(repo_id=repo_id, repo_type="model")
shutil.rmtree(cache_folder)
return destination
model_path = download_model(repo_id, variant, output_dir="./models")
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 ALL --seed 93
对于 Stable Diffusion 2 基地(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-v1-5_original_packages --model-version 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-2-base_original_packages --model-version stabilityai/stable-diffusion-2-base
Swift 中的 Core ML 推理
在 Swift 中运行推理比在 Python 中运行稍快,因为模型已经以格式编译mlmodelc。当加载模型时,这在应用程序启动时会很明显,但如果您之后运行几代,则不应该很明显。下载
要在 Mac 上使用 Swift 运行推理,您需要其中一个compiled检查点版本。我们建议您使用类似于我们上面显示的代码的 Python 代码在本地下载它们,但使用其中一种变compiled体:
from huggingface_hub import snapshot_download
from huggingface_hub.file_download import repo_folder_name
from pathlib import Path
import shutil
repo_id = "apple/coreml-stable-diffusion-v1-4"
variant = "original/compiled"
def download_model(repo_id, variant, output_dir):
destination = Path(output_dir) / (repo_id.split("/")[-1] + "_" + variant.replace("/", "_"))
if destination.exists():
raise Exception(f"Model already exists at {destination}")
# Download and copy without symlinks
downloaded = snapshot_download(repo_id, allow_patterns=f"{variant}/*", cache_dir=output_dir)
downloaded_bundle = Path(downloaded) / variant
shutil.copytree(downloaded_bundle, destination)
# Remove all downloaded files
cache_folder = Path(output_dir) / repo_folder_name(repo_id=repo_id, repo_type="model")
shutil.rmtree(cache_folder)
return destination
model_path = download_model(repo_id, variant, output_dir="./models")
print(f"Model downloaded at {model_path}")
推理
要运行推理,请克隆 Apple 的存储库:然后使用 Swift Package Manager 的工具使用 Apple 的命令行工具:
git clone https://github.com/apple/ml-stable-diffusion
cd ml-stable-diffusion
您必须在—resource-path上一步下载的检查点之一中指定,因此请确保它包含已编译的 Core ML 包,扩展名为.mlmodelc. 必须—compute-units是以下值之一:all, cpuOnly, cpuAndGPU, cpuAndNeuralEngine。 更多详细信息,请参阅Apple 的 repo 中的说明。
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"
带上你自己的模型
如果您创建了与 Stable Diffusion 兼容的自己的模型(例如,如果您使用了 Dreambooth、Textual Inversion 或微调),那么您必须自己转换模型。幸运的是,Apple 提供了一个允许您这样做的转换脚本。 对于此任务,我们建议您遵循这些说明。下一步
我们对这带来的机会感到非常兴奋,迫不及待地想看看社区可以从这里创造什么。一些潜在的想法是:- 适用于 Mac、iPhone 和 iPad 的原生高质量应用程序。
- 为 Swift 引入额外的调度器,以实现更快的推理。
- 额外的管道和任务。
- 探索量化技术和进一步优化。