Diffusers 在 Apple Silicon 上落地原生应用的 Core ML 实践指南:Stable Diffusion 转换与 Python/Swift 双路径推理
本文基于 Diffusers 仓库的 Core ML 官方优化文档(含韩语版)系统讲解如何在 Apple 设备上运行 Stable Diffusion:先用基于 diffusers 的 Apple 转换工具把 PyTorch 检查点转成 Core ML 格式,再分别通过 Python(packages 变体)与 Swift(compiled 变体)完成推理,并梳理 Core ML 路径对 Diffusers 特性的支持边界,最终帮助你在 macOS/iOS/iPadOS 原生应用与 Python 后端两种场景下做出正确的技术选型。
为什么选 Core ML:计算引擎与原生应用
Core ML 是 Apple 框架支持的模型格式与机器学习库。如果你希望在 macOS 或 iOS/iPadOS 应用内运行 Stable Diffusion,本指南覆盖「PyTorch 检查点 → Core ML 转换 → Python/Swift 推理」的完整链路。
Core ML 模型可以充分利用 Apple 设备上可用的全部计算引擎:
- CPU 与 GPU;
- Apple Neural Engine(ANE):面向张量运算优化的加速引擎,存在于 Apple Silicon Mac 及较新的 iPhone/iPad 上。
并且,根据模型与运行设备不同,Core ML 可以混合调度这些引擎——例如模型一部分算子跑在 CPU,另一部分跑在 GPU。这是它与纯 PyTorch 路径的本质区别之一:Core ML 交由 Apple 运行时做底层引擎编排,适合需要长期运行在端侧、追求低延迟与低功耗的原生应用。
TIP:如果只是想在 Apple Silicon Mac 上跑
diffusers的 Python 代码库,也可以直接使用 PyTorch 内建的mps加速器。该方案在仓库的 mps 指南中有详细说明(包括enable_attention_slicing()等性能建议),但它不兼容原生 App——这正是选择 Core ML 的核心动因。
Stable Diffusion 的 Core ML 检查点从哪里来
Stable Diffusion 的权重(检查点)以 PyTorch 格式存储,要在原生 App 中使用,必须先转换为 Core ML 格式。Apple 工程团队开发了一个基于 diffusers 的转换工具(位于 apple/ml-stable-diffusion 仓库),可以把 PyTorch 检查点转换为 Core ML。
转换之前,建议先浏览 Hugging Face Hub,目标模型很可能已经有现成的 Core ML 版本:
- apple 组织:提供 Stable Diffusion 1.4、1.5、2.0 base 与 2.1 base 的 Core ML 检查点,例如
apple/coreml-stable-diffusion-v1-4; - coreml 社区组织:提供应用了自定义 DreamBooth 或经过微调的社区模型;
- Hub 上还可以按
pipeline_tag=text-to-image且library=coreml过滤,列出所有可用的 Core ML 检查点。
如果找不到目标模型,推荐遵循 Apple 仓库中「Converting Models to Core ML」的章节自行转换(需要 diffusers 环境加载原始 PyTorch 模型后导出)。
变体(Variant)选型:注意力类型 × 推理框架
Stable Diffusion 可以按不同目的转换成不同的 Core ML 变体,由两个维度正交组合:
维度一:注意力块类型
注意力(Attention)操作用于在图像表征的不同区域之间建立关联、理解图像与文本表征之间的对应关系。该运算对算力与内存都很敏感,因此存在针对不同硬件特性的多种实现。Core ML Stable Diffusion 模型有两种注意力变体:
split_einsum:由 Apple 提出(详见 Apple 关于 Neural Engine 上 Transformer 的研究),针对 ANE 优化,适用于现代 iPhone、iPad 与 M 系列 Mac;original(原始注意力):即diffusers中使用的基础实现,仅兼容 CPU/GPU,不支持 ANE。值得注意的是,用original注意力在 CPU + GPU 上跑模型,速度有时反而比走 ANE 更快。可参考官方性能基准博客(fast-mac-diffusers)以及社区在 swift-coreml-diffusers 仓库 issue 中提供的补充实测数据。
这一差异的根源在于 UNet 内部注意力模块的计算结构:diffusers 的 UNet 主体实现见 UNet2DConditionModel,其 forward(第 979 行起)中包含大量注意力子层。split_einsum 通过把大矩阵乘拆分成 ANE 友好的 einsum 分块计算来提升利用率,而 original 的朴素 QKV 实现则更贴合 CPU/GPU 的执行特征。
维度二:支持的推理框架
packages:适合 Python 推理。可用于在集成进原生 App 之前先验证转换后的 Core ML 模型,或仅想评估 Core ML 性能而无须支持原生 App 的场景。例如,带 Web UI 的应用完全可以采用「Python + Core ML」的后端组合。compiled(已编译):Swift 代码必需。Hub 上的compiled模型会把体积庞大的 UNet 权重分片到多个文件中,以适配 iOS/iPadOS 设备——这对应转换时的--chunk-unet选项。要做原生 App,必须选择compiled变体。
官方 Core ML Stable Diffusion 模型仓库同时包含这四种变体组合(社区版本目录结构可能不同):
coreml-stable-diffusion-v1-4
├── README.md
├── original
│ ├── compiled
│ └── packages
└── split_einsum
├── compiled
└── packages
选型速查:
| 场景 | 注意力变体 | 格式 |
|---|---|---|
| Python 快速验证 / Web UI 后端 | original 或 split_einsum |
packages |
| Swift 原生 App(iOS/iPadOS) | original 或 split_einsum(按设备) |
compiled |
| Apple Silicon Mac 追求 GPU 极限速度 | original(CPU+GPU 往往快于 ANE) |
packages 或 compiled |
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}")
要点:allow_patterns=f"{variant}/*" 保证只拉取目标变体子树;local_dir_use_symlinks=False 让文件真实落地,便于后续被命令行脚本读取。
运行推理
下载完成后,用 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
参数说明:
--prompt:生成用提示词;-i:上一步下载的检查点目录(指向packages变体);-o:可选,输出图片路径;--compute-unit:允许推理使用的硬件,取值必须是ALL、CPU_AND_GPU、CPU_ONLY、CPU_AND_NE之一;--seed:可选,固定随机种子以保证可复现。
该脚本默认假设你使用的是 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
Swift 中的 Core ML 推理
Swift 推理比 Python 略快,因为模型已经是 mlmodelc 格式的编译产物——这种优势主要体现在 App 启动加载模型阶段,连续多次生成后差距不再明显。
下载编译版检查点
在 Mac 上做 Swift 推理需要 compiled 检查点。推荐用与上文类似的 Python 代码下载,只是变体换成 original/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 Package Manager 运行
克隆 Apple 的转换/推理仓库:
git clone https://github.com/apple/ml-stable-diffusion
cd ml-stable-diffusion
然后用命令行工具 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 bundle;--compute-units:取值必须是all、cpuOnly、cpuAndGPU、cpuAndNeuralEngine之一;- 末尾的字符串位置参数即为生成提示词。
更完整的参数与工程说明,参见 Apple 仓库(apple/ml-stable-diffusion)内的 README 指引。
Core ML 路径支持哪些 Diffusers 特性
Core ML 模型与推理代码不支持 🧨 Diffusers 的大量特性、选项与灵活性,落地前需要认清以下限制:
- 仅推理:Core ML 模型只适合推理,不能用于训练或微调;
- 调度器受限:移植到 Swift 的调度器只有两个——Stable Diffusion 默认调度器,以及从
diffusers移植到 Swift 的DPMSolverMultistepScheduler。推荐后者,因为它大约用一半的步数就能达到同等生成质量。对应的diffusers参考实现见 scheduling_dpmsolver_multistep.py 中的DPMSolverMultistepScheduler(第 123 行起); - 部分管线可用:推理代码支持负向提示词(negative prompt)、classifier-free guidance scale 以及 image-to-image 任务;而 depth guidance、ControlNet、latent upscaler 等高级功能尚不可用。
需要强调:Apple 的转换/推理仓库与社区的 swift-coreml-diffusers 仓库都定位为「技术演示」,其价值在于让其他开发者可以在其上构建。如果某个缺失功能对你很关键,可以在相应仓库提功能请求,或直接提交贡献 PR。
原生 Swift 应用:swift-coreml-diffusers 与 Mac App
在自己的 Apple 硬件上运行 Stable Diffusion 的最便捷方式,是使用基于 diffusers 与 Apple 转换/推理仓库构建的开源 Swift 仓库 swift-coreml-diffusers(huggingface 组织下)。你可以研读其代码、用 Xcode 编译并按需改造。该仓库还提供了上架 App Store 的独立 Mac App,无需接触代码与 IDE 即可直接体验。
如果你作为开发者已经判断 Core ML 是构建 Stable Diffusion 应用的最佳路径,就可以按本文「变体选型 → Python/Swift 推理」的其余部分着手自己的项目。
小结与选型建议
- 只做 Python 研究/后端:优先走
mps(见 mps 指南),完整保留 Diffusers 生态;确需 Core ML 性能评测时,选packages变体 +python_coreml_stable_diffusion.pipeline; - 做原生 App:选
compiled变体 + Swift Package Manager;iOS/iPadOS 上优先split_einsum以利用 ANE,M 系列 Mac 上可实测original+cpuAndGPU对比cpuAndNeuralEngine的耗时; - 检查点优先找现成的:apple 组织(SD 1.4/1.5/2.0/2.1 base)与 coreml 社区组织(自定义微调模型),没有再走 Apple 转换流程自行转换;
- 预期管理:Core ML 路径当前不支持训练、ControlNet、depth guidance、latent upscaler 等 Diffusers 高级特性,规划功能范围时务必先对照本文「支持的特性」一节。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00