mlmodel —— 是 Apple 的 Core ML 框架的机器学习模型文件格式,在 .mlpackage 格式出现之前用于存储训练好的模型。.mlmodel 文件是一种基于 protobuf 格式的二进制包,包含模型描述、神经网络权重、元数据以及输入/输出信息。根据 Apple Core ML Release Notes(2025),从 Xcode 13 和 Core ML 4 开始,旧格式 .mlmodel 被宣布弃用,改用 .mlpackage,后者提供了更好的版本管理和元数据可读性。
要点
mlmodel —— 是 Apple 于 2017 年在 WWDC 2017 上随 Core ML 框架一起推出的二进制文件格式。该格式基于 Google 的 protobuf(Protocol Buffers)序列化技术,从而保证了紧凑的体积(模型权重使用 Float32)和高效的内存加载。.mlmodel 文件的扩展名为 .mlmodel,MIME 类型为 application/x-Apple-mlmodel。
.mlmodel 格式在 2017 年至 2021 年期间是 Core ML 的唯一格式。在此期间,通过 coremltools 转换了来自 TensorFlow、Keras、PyTorch、Caffe、scikit-learn 等库的数百万个模型。随着模型复杂度的提高,格式的限制变得明显:protobuf 不支持方便的版本管理,元数据以二进制形式存储(无法在 git diff 中读取),而添加新字段需要修改 protobuf 模式。
mlmodel 文件以紧凑的二进制表示形式存储模型。大小从几十 KB(线性回归)到数 GB(拥有数百万参数的神经网络)不等。该格式支持所有类型的 Core ML 模型:神经网络(NeuralNetwork、NeuralNetworkClassifier、NeuralNetworkRegressor)、集成模型(TreeEnsemble、GradientBoosting)、回归模型(LinearRegression、SVM)以及预处理/后处理管道(OneHotEncoder、FeatureVectorizer)。
| 特性 | mlmodel |
|---|---|
| 格式 | 二进制(protobuf) |
| 可读性 | 不可读(只能通过 coremltools) |
| 版本管理 | 无(单个二进制文件) |
| 元数据 | 位于 protobuf 模式中 |
| Git 友好性 | 否(二进制差异低效) |
.mlmodel 文件的内部结构由 CoreML.framework 框架中描述的 protobuf 模式决定。主要部分:modelDescription —— 模型的输入、输出和元数据描述;modelParameters —— 模型类型的具体参数(神经网络的权重、树集成、回归系数);preprocessing —— 预处理配置(缩放、图像归一化);postprocessing —— 后处理(softmax、argmax、阈值)。
modelDescription(MLModelDescription)部分包含模型名称、作者、版本、描述、许可证,以及所有输入和输出参数的详细描述:名称、数据类型(Float32、Int32、String、Image)、维度、图像格式(BGR、RGB)、可选限制(取值范围)。Xcode 使用该部分生成具有类型化输入和输出的 Swift 模型类。
modelParameters 部分包含训练模型的真实权重和参数。对于神经网络,它是一个层数组(NeuralNetworkLayer),每一层包含类型(convolution、pooling、activation、innerProduct)、权重(weights)、偏置(bias)、参数(kernelSize、stride、padding)。对于集成模型 —— 决策树及其节点。对于回归模型 —— 系数和截距。权重以 Float32 存储(每个值 4 字节)。
preprocessing 部分描述了在将输入数据送入模型之前执行的预处理步骤。Core ML 支持:缩放(Scaler)—— 通过均值和标准差进行归一化;图像转换(ImagePreprocessing)—— 调整大小、裁剪、颜色通道归一化、BGR→RGB 转换;OneHotEncoder —— 分类特征编码;FeatureVectorizer —— 将多个特征合并为一个向量。
mlpackage —— 是 Core ML 模型的新一代格式,于 WWDC 2021 上推出。与单一的 .mlmodel 二进制文件不同,.mlpackage 是一个带有文件结构的目录(包):模型内容以可读的 JSON 文件(元数据、层配置)和独立的二进制权重文件形式存储。这从根本上改变了 ML 模型的存储、版本管理和协作方式。
| 参数 | mlmodel | mlpackage |
|---|---|---|
| 类型 | 单个二进制文件 | 目录(包) |
| 元数据 | 二进制 protobuf | JSON(可读) |
| Git diff | 无用 | 可用(权重除外) |
| 版本管理 | 手动 | JSON 中自动进行 |
| 自定义层 | 无 | 支持 |
| 状态 | 已弃用 | 当前 |
.mlpackage 包包含:ModelCI/ —— 带版本管理的模型配置目录;Data/ —— 二进制权重文件(SharedWeights.bin);Metadata.json —— 模型名称、作者、描述、版本、创建日期;Model.json —— 模型架构、输入/输出、层类型的描述;Manifests/ —— 用于 CI/CD 的版本清单。这种结构允许在 git 中高效地使用模型:元数据和配置会被跟踪,而二进制权重可以使用 Git LFS。
将 .mlmodel 转换为 .mlpackage 的转换可以通过两种方式完成:在 Xcode 中构建时自动转换(Xcode 在编译过程中自动将 .mlmodel 转换为 .mlpackage),或通过 Python 中的 coremltools 手动转换。手动转换提供更大的控制力,并且可以更新模型元数据、添加描述和设置作者。转换后,模型保存为 .mlpackage,可以替代原始的 .mlmodel 使用。
import coremltools as ct
model = ct.models.MLModel(
"OldModel.mlmodel"
)
model.author = "IT Sectr"
model.short_description = "Converted from mlmodel"
model.version = "2.0"
model.save("NewModel.mlpackage")
将 .mlmodel 文件添加到 Xcode 项目时,系统会自动识别其格式,并在构建(build)时启动 Model Compiler —— 这是一个将 .mlmodel 转换为 .mlpackage 的工具。编译后的 .mlpackage 被放入构建目录(DerivedData)。开发人员不会注意到这一过程 —— 无论原始格式如何,所有 Core ML API 都会以统一的方式使用模型。但是,添加 .mlmodel 时 Xcode 会发出警告,建议使用 .mlpackage。
转换后,必须确保模型保持了精度。coremltools 提供了 ct.utils.compare_models() 工具,用于在相同的输入数据上比较原始模型和转换后模型的预测。允许的偏差 —— Float32 不超过 1e-5。如果偏差超出范围,则模型可能包含新格式不支持的自定义层或操作。
.mlmodel 的向后兼容性在所有当前的 iOS 和 macOS 版本上都有保障。使用 Xcode 12 或更高版本编译的应用会自动获得模型的 .mlpackage 版本,即使原始文件是 .mlmodel。然而,从 Xcode 15(2023)开始,Apple 宣布新型模型(动态神经网络、受控学习)将仅在 .mlpackage 格式中可用,.mlmodel 将不再获得新功能。
从 iOS 18 和 macOS 15(Sequoia)开始,Core ML 不再支持直接加载 .mlmodel。所有 .mlmodel 模型都必须预先转换为 .mlpackage,或者使用 Xcode Model Compiler 在构建期间进行转换。系统 API MLModel(contentsOf:) 仍然可以打开 .mlmodel 文件,但前提是它们在项目构建阶段已转换为 .mlpackage。
Apple 尚未正式公布完全移除 .mlmodel 支持的日期,但历史背景表明过渡期为 3-4 年。.mlmodel 格式于 2017 年推出,.mlpackage 于 2021 年推出。弃用警告出现在 Xcode 13(2021)中。参照 32 位应用(iOS 11 终止了支持),可以预计 .mlmodel 的完整支持将在 iOS 20-21(2026-2027)中终止。
尽管格式已弃用,.mlmodel 仍然存在于现有项目和一些场景中。对于使用 Core ML 的开发人员来说,了解 .mlmodel 何时仍是工作流程的一部分,以及如何在不损失性能的情况下正确使用它,非常重要。
2021 年之前启动的现有项目可能包含数十个通过 Swift Package Manager 或直接在 Xcode 中加载的 .mlmodel 模型。将所有模型迁移到 .mlpackage 可能很费时,尤其是当模型由旧版 coremltools(5.0 之前)生成时。Apple 建议在最近一次功能更新时逐步迁移,一次一个模型。
一些现有的 CI/CD 管道使用 coremltools 4.x 版本进行自动模型转换,默认导出为 .mlmodel。将 coremltools 更新到 5+ 版本会将导出格式改为 .mlpackage,这可能需要更新脚本和测试。在这种情况下,团队有时会暂时保留导出为 .mlmodel,同时计划稍后进行迁移。
2021 年之前发布的第三方库和 CocoaPods 可能包含 .mlmodel 格式的模型。例如,用于人脸识别、图像过滤或 AR 滤镜的库。使用这些库的开发人员可以继续使用 .mlmodel,因为 Xcode 会在构建时自动转换它们。但是,建议检查作者是否已发布带有 .mlpackage 的更新。
在使用已弃用的 .mlmodel 格式时,开发人员会遇到几个常见问题。了解这些问题及其解决方案,有助于避免在将 Core ML 模型集成到现代项目时浪费时间。我们来看看主要问题。
在 Xcode 13+ 中添加 .mlmodel 时会出现警告:“'mlmodel' format is deprecated. Use 'mlpackage' instead.”。该警告不会阻止构建,但表明需要进行迁移。要消除警告,请通过 coremltools 转换模型,或更新模型创建工具。
由旧版 coremltools(3.0 之前)创建的 .mlmodel 文件可能无法在装有 iOS 16+ 的新设备上打开,因为 protobuf 编解码器发生了变化。解决方法 —— 通过 Python 加载模型:model = ct.models.MLModel("old.mlmodel"),然后重新保存:model.save("fixed.mlmodel"),或者更好的是直接转换为 .mlpackage。
包含 custom layers(自定义神经网络层)的 .mlmodel 模型不能在没有额外步骤的情况下直接转换为 .mlpackage。首先需要将模型加载到 coremltools 中,检查哪些层不受新格式支持,并为 .mlpackage 实现它们。如果自定义层并不关键,可以尝试将其从模型中移除。
常见问题解答
mlmodel —— 是已弃用的二进制文件格式,用于存储 Core ML 模型,2017 年至 2021 年间使用。它基于 protobuf 序列化,在一个扩展名为 .mlmodel 的二进制文件中包含模型权重、元数据和输入/输出数据描述。
mlmodel —— 是单个二进制文件,在 git 中不可读,且不支持版本管理。mlpackage —— 是带有 JSON 元数据的目录(包),在 git 中可读且支持版本管理。mlpackage 还支持自定义层,并自动生成版本清单。Apple 建议所有新项目使用 mlpackage。
可以通过三种方式打开 .mlmodel 文件:通过 Xcode(添加到项目 —— 模型会带元数据显示在编辑器中)、通过 Python 中的 coremltools(model = ct.models.MLModel("model.mlmodel")),或通过 Netron —— 一款支持 Core ML、ONNX、TensorFlow 等格式的免费模型可视化工具。
建议转换,但不必立即进行。Xcode 在构建项目时会自动将 .mlmodel 转换为 .mlpackage。但是,Xcode 的弃用警告会持续出现,而且新的 Core ML 功能(动态网络、iOS 18+)将不适用于 .mlmodel。请在最近一次功能更新时转换模型。
iOS 18+ 仅在向后兼容模式下支持 .mlmodel:如果模型以 .mlmodel 形式添加到 Xcode 项目,Xcode 会在构建时自动将其转换为 .mlpackage。在装有 iOS 18+ 的设备上,通过 MLModel(contentsOf:) 直接加载 .mlmodel 并不保证可用 —— Apple 建议将模型存储在 .mlpackage 中。
结论
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。