感谢 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转换选项

在撰写本文时,我们使用以下组合在我的 MacBook Pro(M1 Max,32 个 GPU 内核,64 GB)上获得了最佳结果:

  • original注意力。
  • all计算单元(详见下一节)。
  • macOS 文图拉 13.1 测试版 4 (22C5059b)。

有了这些,使用 Core ML 版本的 Stable Diffusion v1.4 🤯 生成一张图像需要 18 秒。
⚠️注意
macOS Ventura 13.1 测试版中引入了对 Core ML 的多项改进,它们是 Apple 实施所必需的。**如果您使用 macOS Ventura (13.0.1) 的当前发行版,您可能会得到黑色图像——而且速度会慢得多。**如果您不能或不会安装测试版,请等待 macOS Ventura 13.1 正式发布。
每个模型 repo 都以树结构组织,提供这些不同的变体:

  1. coreml-stable-diffusion-v1-4
  2. ├── README.md
  3. ├── original
  4. ├── compiled
  5. └── packages
  6. └── split_einsum
  7. ├── compiled
  8. └── packages

您可以下载并使用您需要的变体,如下所示。

Python 中的核心 ML 推理

先决条件

  1. pip install huggingface_hub
  2. pip install git+https://github.com/apple/ml-stable-diffusion

下载模型检查点

要在 Python 中运行推理,您必须使用存储在文件夹中的版本之一packages,因为编译后的版本仅与 Swift 兼容。您可以选择是否要使用original或split_einsum注意样式。
original这就是您从 Hub下载注意力变体的方式:

  1. from huggingface_hub import snapshot_download
  2. from huggingface_hub.file_download import repo_folder_name
  3. from pathlib import Path
  4. import shutil
  5. repo_id = "apple/coreml-stable-diffusion-v1-4"
  6. variant = "original/packages"
  7. def download_model(repo_id, variant, output_dir):
  8. destination = Path(output_dir) / (repo_id.split("/")[-1] + "_" + variant.replace("/", "_"))
  9. if destination.exists():
  10. raise Exception(f"Model already exists at {destination}")
  11. # Download and copy without symlinks
  12. downloaded = snapshot_download(repo_id, allow_patterns=f"{variant}/*", cache_dir=output_dir)
  13. downloaded_bundle = Path(downloaded) / variant
  14. shutil.copytree(downloaded_bundle, destination)
  15. # Remove all downloaded files
  16. cache_folder = Path(output_dir) / repo_folder_name(repo_id=repo_id, repo_type="model")
  17. shutil.rmtree(cache_folder)
  18. return destination
  19. model_path = download_model(repo_id, variant, output_dir="./models")
  20. print(f"Model downloaded at {model_path}")

上面的代码会将下载的模型快照放在您指定的目录中(models在本例中为 )。

推理

下载模型快照后,运行推理的最简单方法是使用 Apple 的 Python 脚本。

  1. 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

应指向您在上述步骤中下载的检查点,并—compute-unit指示您要允许进行推理的硬件。它必须是以下选项之一:ALL, CPUAND_GPU, CPU_ONLY, CPU_AND_NE。您还可以提供可选的输出路径和可重复性的种子。
推理脚本采用稳定扩散模型的原始版本,在 Hub 中存储为CompVis/stable-diffusion-v1-4. 如果您使用其他模型,则
必须_使用该选项在推理命令行中指定其 Hub id —model-version。这既适用于已经支持的模型,也适用于您自己训练或微调的自定义模型。
对于 Stable Diffusion 1.5(Hub id runwayml/stable-diffusion-v1-5:):

  1. 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 基地(Hub id stabilityai/stable-diffusion-2-base:):

  1. 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体:

  1. from huggingface_hub import snapshot_download
  2. from huggingface_hub.file_download import repo_folder_name
  3. from pathlib import Path
  4. import shutil
  5. repo_id = "apple/coreml-stable-diffusion-v1-4"
  6. variant = "original/compiled"
  7. def download_model(repo_id, variant, output_dir):
  8. destination = Path(output_dir) / (repo_id.split("/")[-1] + "_" + variant.replace("/", "_"))
  9. if destination.exists():
  10. raise Exception(f"Model already exists at {destination}")
  11. # Download and copy without symlinks
  12. downloaded = snapshot_download(repo_id, allow_patterns=f"{variant}/*", cache_dir=output_dir)
  13. downloaded_bundle = Path(downloaded) / variant
  14. shutil.copytree(downloaded_bundle, destination)
  15. # Remove all downloaded files
  16. cache_folder = Path(output_dir) / repo_folder_name(repo_id=repo_id, repo_type="model")
  17. shutil.rmtree(cache_folder)
  18. return destination
  19. model_path = download_model(repo_id, variant, output_dir="./models")
  20. print(f"Model downloaded at {model_path}")

推理

要运行推理,请克隆 Apple 的存储库:

  1. git clone https://github.com/apple/ml-stable-diffusion
  2. cd ml-stable-diffusion

然后使用 Swift Package Manager 的工具使用 Apple 的命令行工具:

  1. 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上一步下载的检查点之一中指定,因此请确保它包含已编译的 Core ML 包,扩展名为.mlmodelc. 必须—compute-units是以下值之一:all, cpuOnly, cpuAndGPU, cpuAndNeuralEngine。
更多详细信息,请参阅Apple 的 repo 中的说明

带上你自己的模型

如果您创建了与 Stable Diffusion 兼容的自己的模型(例如,如果您使用了 Dreambooth、Textual Inversion 或微调),那么您必须自己转换模型。幸运的是,Apple 提供了一个允许您这样做的转换脚本。
对于此任务,我们建议您遵循这些说明

下一步

我们对这带来的机会感到非常兴奋,迫不及待地想看看社区可以从这里创造什么。一些潜在的想法是:

  • 适用于 Mac、iPhone 和 iPad 的原生高质量应用程序。
  • 为 Swift 引入额外的调度器,以实现更快的推理。
  • 额外的管道和任务。
  • 探索量化技术和进一步优化。

期待看到你创造的东西!