Core ML端侧推理:真正能上线的模式
Core ML是每台现代Apple设备都搭载的端侧推理引擎。该框架会根据模型和硬件情况自动选择最快路径:优先调度到Neural Engine,不可用时调度到GPU,最后才回退到CPU1。在较新的iPhone上,大多数生产级模型尺寸的推理延迟在亚毫秒到几十毫秒之间,每次调用零成本,无网络往返,也不会向第三方暴露数据。
Core ML被视为”晦涩底层管线”的印象早已过时。如今Core ML支撑着Apple Intelligence的端侧LLM、照片应用的语义搜索、相机应用的场景识别,以及大多数搭载本地ML的第三方应用。让Core ML部署真正能上线(而不是停留在”在我电脑上能跑”)的模式其实只有少数几种:模型转换、调度提示、延迟预算和量化。本文将逐一对照Apple文档进行讲解。
TL;DR
- Core ML在Apple Silicon的Neural Engine、GPU和CPU上运行
.mlpackage和.mlmodel文件。调度自动进行,但可通过MLModelConfiguration.computeUnits提示2。 - 模型转换通过
coremltools完成(PyTorch、TensorFlow、ONNX → Core ML)。转换是工具链任务,不是运行时任务;模型转换并打包后,应用即可加载并运行。 - Apple Silicon的统一内存架构意味着模型权重无需在CPU、GPU和NE之间复制;同一块内存为三者共同支撑3。这一架构细节正是亚毫秒推理得以实现的关键。
- 量化(INT8,以及近期Core ML版本支持的INT4)可缩减模型体积并加速Neural Engine上的推理,但精度损失可衡量,具体取决于模型。
- Agent工作流的衔接:Foundation Models(Apple Intelligence的端侧LLM)以Core ML模型形式发布,背后是高层Swift API;同样适用本文所述的调度与量化模式。
心智模型:三条计算路径,一份内存
Apple Silicon(M系列Mac和A12 Bionic及之后的A系列iPhone)搭载三个推理目标:
Neural Engine。 专为低精度矩阵乘法设计的加速器。对现代ML模型依赖的运算(卷积、注意力、嵌入)速度最快,功耗最低。仅支持特定运算类型和张量形状;不支持的运算会按层回退到GPU或CPU。
GPU。 通过Metal提供的通用并行计算。处理ML类工作时比Neural Engine慢,但比CPU快。负责处理Neural Engine不支持的运算。
CPU。 兜底方案。ML推理速度慢,但始终可用、支持所有运算,且行为可预测。
统一内存架构让同一块物理RAM支撑三者3。模型权重一次加载后,调度在不同目标之间切换时无需复制。这一架构事实将多目标调度从”按层复制成本”转变为”按层调度决策”。
MLModelConfiguration.computeUnits控制调度:
let config = MLModelConfiguration()
config.computeUnits = .all // default: NE, GPU, CPU
// Other options:
// .cpuAndGPU
// .cpuAndNeuralEngine
// .cpuOnly
let model = try MyModel(configuration: config)
.all是默认值,对几乎所有应用都是正确选择。框架会按运算选择最快路径,这种逐运算的决策比开发者编写的任何启发式规则都要快。少数需要覆盖的场景包括:强制.cpuOnly以测试一致性(模型在不同路径上行为不同,测试需要确定性路径),或强制.cpuAndGPU以释放Neural Engine供另一个并发任务使用。
模型转换:工具链任务
大多数ML模型在PyTorch、TensorFlow中训练,或直接通过Apple的Create ML训练。Core ML接受.mlpackage文件,这是Xcode 13引入的现代格式,取代了旧的.mlmodel4。转换通过coremltools完成,这是Apple开源的Python包5。
典型的PyTorch到Core ML转换分三步:
- 加载训练好的PyTorch模型并设置为推理模式。
- 使用与生产输入形状匹配的示例输入张量追踪模型。
- 使用
coremltools针对目标部署iOS版本进行转换。
import torch
import coremltools as ct
model = MyTrainedModel()
model.load_state_dict(torch.load("weights.pth"))
example_input = torch.rand(1, 3, 224, 224)
traced_model = torch.jit.trace(model, example_input)
mlmodel = ct.convert(
traced_model,
inputs=[ct.ImageType(name="image", shape=example_input.shape)],
minimum_deployment_target=ct.target.iOS18,
compute_units=ct.ComputeUnit.ALL,
)
mlmodel.save("MyModel.mlpackage")
转换在开发环境中执行一次,针对目标部署iOS版本(minimum_deployment_target)进行。输出的.mlpackage是放入Xcode项目的文件。运行时应用不会运行coremltools。
转换中有两个实务陷阱。第一,动态形状输入需要通过ct.RangeDim显式处理,因为Core ML默认的静态形状会在生产应用喂入不同尺寸输入时产生难以理解的错误。第二,PyTorch中没有Core ML等价物的自定义运算,需要Core ML自定义层(用Swift代码实现缺失的运算),或在转换前修改模型架构以移除该运算。两者文档齐全5。
真正适用的延迟预算
对上线应用而言,三类延迟预算最为重要:
16毫秒(60 fps实时UI)。 实时相机滤镜、逐帧更新的AR场景、实时音频分析器。该预算涵盖一切:图像预处理、模型推理、后处理、UI更新。能放进这一预算的模型通常较小(MobileNetV3级别,参数量低于1亿),运行在Neural Engine上。
100毫秒(交互式UI)。 用户执行操作并等待结果:点击识别、绘制识别、口述转写。该预算更宽松,可支持更大的模型。10亿参数以下的语言模型、小型视觉Transformer,以及大多数生产级分类器都能轻松适配。
1秒以上(后台或批处理)。 照片库索引、文档分析、应用启动时的模型预热。更大的模型可行,但必须配合进度指示器来管理用户预期。Foundation Models端侧LLM在更大上下文窗口操作时落在这一区间。
这些预算是参考线,不是硬限制。正确做法是在目标设备上使用os_signpost或Instruments的Core ML模板进行测量6,而不是相信另一台机器上的理论数据。
量化:何时更小即更快
Core ML支持多档量化7:
- Float32(全精度)。 训练默认值。体积最大、最准确、最慢。
- Float16。 半精度。在GPU和NE上更小、更快;对调校良好的模型,精度损失通常可忽略。
- INT8。 带校准的8位整数量化。约为Float32的四分之一大小,在NE上通常快2-4倍。精度损失因模型而异;对视觉模型,配合量化感知训练可将top-1精度损失控制在1%以内。
- INT4及以下。 激进量化,近期Core ML版本对特定模型架构(LLM、大型视觉模型)提供支持。代价是显著的精度损失;该技术与模型感知的量化感知训练配合时效果最佳。
通过coremltools.optimize.coreml.linear_quantize_weights进行的线性量化配置接受全局运算配置,用于选择量化模式(linear_symmetric或linear),以及一个权重大小阈值,低于该阈值的权重保留全精度。转换针对现有.mlpackage运行,生成新的量化包;两者可同时打包进bundle,由应用根据设备类别选择加载哪一个。
量化决策因模型而异:小型分类器可能并不受益,因为其计算本就廉价;大型语言模型则受益巨大,因为其计算被量化权重上的矩阵乘法主导。正确做法是先量化,在留出测试集上测量精度,若精度损失对该用例可接受则发布。
Apple内置可直接使用的模型
Apple通过Core ML Models页面发布了多个预训练Core ML模型8。值得了解的类别:
- 图像分类: MobileNetV2、ResNet50、SqueezeNet变体,均已打包,可直接放入Vision框架的
VNCoreMLRequest。 - 目标检测: YOLOv3、MNIST、CenterNet变体。
- 姿态估计: PoseNet用于人体姿态(Vision的
VNDetectHumanBodyPoseRequest的基线替代方案)。 - 语义分割: DeepLabV3用于图像分割。
- 文字识别: Vision内置OCR的基于ML的替代方案。
对大多数应用,Apple预训练模型可覆盖感知原语(分类、检测、分割),无需自训练。Foundation Models端侧LLM(详见Foundation Models端侧LLM)是最大的例子:一个数十亿参数的LLM,以Core ML模型形式发布,背后是高层Swift API,调度到Neural Engine,离线可用。
模型加密与App Store考量
应用bundle中的.mlpackage对解包IPA的人来说可读。对代表重要知识产权的模型,Apple通过Encrypt your Core ML model工作流支持模型加密9:通过Xcode生成加密密钥并由CloudKit管理,bundle中的模型加密存储,Core ML在加载时解密。
对大多数应用而言,加密属于过度设计。在通用ImageNet数据上训练的模型并非竞争性差异化要素;加密只会增加运维复杂度,却保护不了什么有价值的东西。加密应保留给真正代表训练数据投入或竞争优势的模型。
端侧隐私:架构层面的胜出
隐私故事很直接。Core ML推理完全在设备上进行。输入数据(图像、音频、文本)不离开设备。模型文件在本地;推理在本地;结果也在本地。
对受监管行业(医疗、金融、教育)的应用,这一架构事实消除了一类合规工作。无需在隐私政策中加入第三方数据处理者。无需审核模型API端点的安全性。也不存在数据驻留问题,因为数据从未移动。
Privacy Manifest格式10为App Store提交编纂了隐私故事:仅使用Core ML进行端侧推理、不做其他事的应用,可在推理路径上声明零第三方数据共享。提交流程更快,隐私审查更短,面向用户的隐私营养标签也更清爽。
Agent工作流的衔接
Core ML与本系列已涵盖的三种模式相配合:
Vision框架的VNCoreMLRequest。 自定义Core ML模型通过Vision管线运行,自动完成预处理。该模式(详见Vision Framework)是在iOS应用中发布自定义图像分类器或检测器的正确方式。
Foundation Models端侧LLM。 Apple Intelligence的LLM是一个Core ML模型,背后是高层Swift API。同样的调度(优先Neural Engine)、量化(LLM权重使用INT4)和延迟预算(短生成亚秒级)模式都适用。Foundation Models文章讲解API;本文讲解底层引擎。
使用本地ML的App Intents工具。 运行本地图像分类器或文本分类器的AppIntent,可向Apple Intelligence返回结构化结果,无需网络往返。这一组合让”agent化的Apple”真正具备隐私属性;agent的工具在本地运行,因为框架支持这样做。
何时云端推理才是正确选择
Core ML的上限是设备的算力。三种情况下云端是正确选择:
模型太大,无法打包发布。 700亿参数的LLM放不进应用bundle。该规模的负载,云端推理(或端侧流式权重,另一种模式)才是正确工具。
推理过程中需要跨设备共享状态。 推理时需要读写共享数据库的模型(针对数十亿条记录做协同过滤的推荐系统)。Core ML纯本地的模型并不适用。
快速模型迭代。 每天发布模型更新的团队会从服务端推理中受益,因为发布无需App Store审核周期。Core ML将模型打包进应用的模式给模型迭代节奏带来摩擦;这是真实的权衡。
模式如下:云端在规模与迭代速度上胜出;Core ML在延迟、成本和隐私上胜出。
这一模式对iOS 26+应用意味着什么
三个要点。
-
凡是能放进bundle、且每次调用结果可供用户操作的模型,都应默认使用Core ML。 图像分类、目标检测、音频分类、手势识别、嵌入生成、中小型语言任务。框架的自动调度加上Apple Silicon的NPU,可免费提供亚毫秒到几十毫秒的推理。
-
在精度损失可接受时积极量化。 INT8通常安全;INT4适用于体积节省至关重要的大型模型。在留出集上测量精度,而不是相信量化普遍安全。
-
与Vision和Foundation Models配合,构成完整的本地管线。 Core ML是引擎;Vision是其上的感知API;Foundation Models是其上的LLM。本系列的Vision一文和Foundation Models一文讲解更高层接口。
完整的Apple生态系统系列:类型化的App Intents;MCP服务器;路由问题;Foundation Models;运行时与工具链LLM的区分;三个表面;单一事实来源模式;两个MCP服务器;Apple开发hooks;Live Activities;watchOS运行时;SwiftUI内部;RealityKit的空间心智模型;SwiftData schema纪律;Liquid Glass模式;多平台发布;平台矩阵;Vision框架;Symbol Effects;我拒绝写的内容。系列入口在Apple Ecosystem Series。如需更广泛的iOS与AI agent结合背景,请参阅iOS Agent Development guide。
FAQ
Core ML如何在Neural Engine、GPU和CPU之间做选择?
Core ML会检查模型图中的每个运算,将其分派到支持该运算的最快目标。Neural Engine以最低延迟和最低功耗处理它支持的运算(大多数矩阵乘法、卷积、注意力)。GPU处理NE不支持的运算。CPU处理其余运算。决策按运算自动进行,比手写启发式规则更快。
是否应始终使用.computeUnits = .all?
几乎总是如此。框架的自动调度调优良好。覆盖到.cpuOnly用于测试输出一致性(同一模型在NE与CPU上由于浮点舍入会返回略有不同的结果),或覆盖到.cpuAndGPU以释放Neural Engine供并发任务使用。
.mlpackage和.mlmodel的实际区别是什么?
.mlpackage是Xcode 13引入的现代格式。它支持存储元数据、为ML Program(mlprogram)编译提供多个模型变体,以及iOS 13之后的工具链。.mlmodel是旧格式。两者都通过MLModel加载;新开发应使用.mlpackage。
应用bundle中的Core ML模型可以多大?
没有固定上限,但App Store的bundle大小下载上限为4 GB,OTA安装也存在实际限制。Foundation Models的端侧LLM约3 GB,由操作系统分发,而不是通过应用bundle。对于应用打包的模型,100 MB以下较为宽松;100-500 MB通过启动时加载策略可行;500 MB以上最好通过BGProcessingTask后台下载或按需资源处理。
如何判断量化是否损害了模型精度?
留出测试集,在原始Float32模型和量化模型上分别推理,对比指标(分类器的top-1精度、检测器的F1、语言模型的困惑度、翻译的BLEU等),根据应用的精度要求做决策。量化感知训练(在损失中模拟量化进行训练)通常能恢复大部分精度损失。
References
-
Apple Developer Documentation: Core ML. Framework reference covering automatic dispatch behavior across compute units. ↩
-
Apple Developer Documentation:
MLModelConfiguration.computeUnits. Enum cases controlling which compute units the model may use. ↩ -
Apple Developer: Apple silicon performance (WWDC 2020 introduction to Apple Silicon’s unified memory architecture). ↩↩
-
Apple Developer Documentation: Core ML Model.
.mlpackageand.mlmodelformat reference. ↩ -
coremltoolsdocumentation. Apple’s open-source Python package for converting trained models from PyTorch, TensorFlow, and ONNX to Core ML. ↩↩ -
Apple Developer Documentation: Profiling Core ML models with Instruments. The Core ML Instruments template for per-layer latency and dispatch analysis. ↩
-
coremltoolsOptimization. Quantization techniques and accuracy-preservation patterns supported by Core ML. ↩ -
Apple Developer: Core ML Models. Apple’s gallery of pre-trained models ready to drop into iOS apps. ↩
-
Apple Developer Documentation: Encrypting a Model in Your App. The CloudKit-backed encryption workflow for Core ML models. ↩
-
Apple Developer Documentation: Privacy manifest files. The format for declaring an app’s data-collection and tracking behaviors. ↩