在 Android 与 iOS 上完成 ONNX 模型部署的完整指南

发布时间:2026/9/6 15:20:17
在 Android 与 iOS 上完成 ONNX 模型部署的完整指南 在 Android 与 iOS 上完成 ONNX 模型部署的完整指南【免费下载链接】onnxruntimeONNX Runtime: cross-platform, high performance ML inferencing and training accelerator项目地址: https://gitcode.com/GitHub_Trending/on/onnxruntime给相机 App 加人脸检测、给笔记 App 加文字识别这类端侧推理需求现在大多绕不开 ONNX Runtime 移动端部署。它是微软开源的跨平台机器学习推理引擎你导出一份标准 ONNX 模型Android 和 iOS 各接一次推理部分共用同一套模型资产。本文按备模型 → 落平台 → 压测排障的顺序走一遍照着做完即可上线。选型速览为什么用 ONNX Runtime本节回答一个问题相比自己写推理循环或直接绑原生框架ONNX Runtime 多了什么。方案模型迁移成本硬件加速算子覆盖纯 CPU 自实现推理每种框架各写一套无自己兜底Core ML / NNAPI 原生框架模型需转换双端各写一套有但绑定单一生态受平台算子列表限制ONNX Runtime一份 ONNX 模型全端通用Execution Provider 按需切换持续扩充不支持算子自动回退上图是它的核心机制训练侧框架统一导出 ONNX 格式部署侧通过Execution Provider执行器决定模型算子跑在哪种硬件上的执行后端把图分发到 CPU、GPU、NPU。端侧对应的就是 Android 的 NNAPI 执行器和 iOS 的 Core ML 执行器切换执行器不改动模型代码。模型就绪之后剩下的问题是怎么喂给两端。第一步模型准备与 ONNX 模型量化本节解决三件事从主流框架导出 ONNX、做 INT8 量化压缩、用官方工具校验可用性。导出以 PyTorch 为例torch.onnx.export指定 opset 后直接产出.onnx文件TensorFlow/Keras 走tf2onnx或keras-onnx转换器。移动端建议导出时固定 batch 维静态 shape 对 Core ML 执行器更友好。量化是降低体积与内存占用的关键步骤仓库内置了量化工具链核心代码在 onnxruntime/python/tools/quantization 目录。静态量化的最小用法from onnxruntime.quantization import quantize_static, QuantType quantize_static( mobilenetv2.onnx, mobilenetv2_int8.onnx, calibration_table, per_channelTrue, weight_typeQuantType.QInt8, )INT8 权重的代价是精度可能轻微下降量化后务必用原模型的校验集对比精度再决定是否采用。导出与量化都完成后用官方校验工具确认模型能被当前 ONNX Runtime 解析python -m onnxruntime.tools.check_onnx_model mobilenetv2.onnx模型过了校验接下来把它落到 Android 工程里。Android 集成与 NNAPI 加速本节解决 Android 端的依赖、模型装载与硬件加速开关。依赖配置。在app/build.gradle中声明 onnxruntime-android 制品版本号以仓库根目录的 VERSION_NUMBER 和 Maven Central 上的实际发布为准dependencies { implementation com.microsoft.onnxruntime:onnxruntime-android::arm64 }模型放置。把mobilenetv2.onnx放进src/main/assets随 APK 打包大模型几十 MB 以上建议改为首次启动时从 assets 解到应用私有目录避免每次从压缩区读取。核心推理代码。会话选项与推理的完整链路如下JavaKotlin 写法一致OrtEnvironment env OrtEnvironment.getEnvironment(); OrtSession.SessionOptions opts new OrtSession.SessionOptions(); opts.addNnapi(EnumSet.of(NNAPIFlags.USE_FP16)); // 开启 NNAPI 加速 OrtSession session env.createSession(modelPath, opts); float[] input preprocess(bitmap); // 预处理缩放、归一化 long[] shape {1, 3, 224, 224}; OnnxTensor inputTensor OnnxTensor.createTensor(env, input, shape); try (OrtSession.Result result session.run(Map.of(input, inputTensor))) { float[] scores (float[]) result.get(0).getValue(); }NNAPI 是 Android 的神经网络 API由系统把算子派发到设备的 NPU/DSP。注意它是尽量使用语义设备不支持的算子会自动回退到 CPU而不是加载失败。若某个调试场景必须确认算子全部落在 NNAPI 上可以显式传入NNAPIFlags.CPU_DISABLED此时有任何 CPU 实现参与的算子模型加载会直接报错方便定位。线程数用opts.setIntraOpNumThreads(n)按设备核心数调节具体建议见 docs/Android_testing.md。Android 跑通后iOS 侧的接入路径类似。iOS 集成与 Core ML 执行器本节解决 iOS 端的依赖接入、Swift 推理代码与 Core ML 执行器的版本适配。依赖接入。用 CocoaPods 在Podfile写pod ONNXRuntime后执行pod install偏好 SPM 的项目直接在 Xcode 中添加 package 依赖即可版本号以官方发布页为准。模型文件拖进 Xcode 工程并勾选 Copy items if needed运行时通过Bundle.main.url(forResource:withExtension:)拿到路径。核心推理代码。Objective-C 层封装见 objectivec/ort_session.mmSwift 侧这样使用let env try ORTEnv(loggingLevel: .warning) let opts try ORTSessionOptions() let mlOpts ORTCoreMLExecutionProviderOptions() mlOpts.useCPUOnly false try opts.appendCoreMLExecutionProvider(with: mlOpts) guard let url Bundle.main.url(forResource: mobilenetv2, withExtension: onnx) else { fatalError(model not found) } let session try ORTSession(env: env, modelURL: url, sessionOptions: opts)Core ML 执行器与 iOS 版本映射。Core ML 是苹果的系统级机器学习框架执行器底层会把它编译为 Core ML 模型后交给 GPU/ANE 执行。版本对应关系以官方文档为准Core ML 3 对应 iOS 13Core ML 4 对应 iOS 14Core ML 5 对应 iOS 15。createMLProgram选项需要 Core ML 5iOS 15低版本设备加载会失败所以建议用onlyEnableForDevicesWithANE控制只在 ANE 设备上启用或按#available做运行时分支。选项定义可见 objectivec/include/ort_coreml_execution_provider.h。两端代码都就位最后一关是压测与排障。双端压测与指标监控本节给你一套可复制的压测方法和一张优化前/优化后对照表。Android 端可以直接用仓库自带的onnx_test_runner在设备上跑 ONNX 测试集把模型推到/data/local/tmp后执行具体流程参考 docs/Android_testing.mdadb push onnx_test_runner /data/local/tmp/ adb push mobilenetv2_int8.onnx /data/local/tmp/ adb shell /data/local/tmp/onnx_test_runner /data/local/tmp/mobilenetv2_int8.onnxiOS 端用 Instruments 组合三张表Time Profiler 看单帧耗时Allocations 看峰值内存Energy Log 看能耗。日常监控抓三个指标就够延迟推理前后各记一次时间戳统计 P50/P95内存Android 用Debug.getNativeHeapAllocatedSize()iOS 用 Allocations功耗Android Studio Energy Profiler / Instruments Energy Log。优化时逐项记录避免凭感觉调参优化项预期影响记录方式INT8 量化ONNX 模型量化模型体积、内存下降延迟通常下降量化前后各测一轮 P50/P95调整setIntraOpNumThreads小 batch 下延迟敏感扫 1/2/4/8 取最优开启 memory arbitrator内存占用与碎片下降对照 Allocations 峰值具体数值取决于模型与机型建议以实测数据回填这张表内存优化细节可查 docs/Memory_Optimizer.md。高频问题排障表上线前把这几类高频问题过一遍能省掉大量现场排查时间。现象原因与处理模型加载 OOM / 崩溃检查设备内存水位确认 memory arbitrator 状态docs/Memory_Optimizer.md大模型考虑解包到磁盘再加载NNAPI 上个别算子异常缓慢默认会自动回退 CPU属正常行为要定位具体算子可传NNAPIFlags.CPU_DISABLED强制报错老设备/Core ML 版本低时appendCoreMLExecutionProvider失败用#available(iOS 13.0, *)做运行时分支失败时留 CPU 执行器兜底动态 shape 输入下 Core ML 端性能波动给onlyAllowStaticInputShapes置 true 强制静态或导出时固定 batch 维与第三方库链接符号冲突用静态库集成时注意-force_load与符号前缀配置详见 objectivec 目录 ReadMe排障表兜不住的问题优先查仓库的 FAQ 文档其中覆盖了大部分环境类疑难。趋势与下一步端侧推理的走向可以概括为三点更多 NPU 执行器落地模型一次导出、任意芯片加速低代码路径成熟训练框架直接产出可部署模型动态 shape 支持增强适配视频流等变分辨率场景。模型上线只是起点。后续文章我们拆一遍 ONNX 模型量化的完整参数校准集怎么选、per-channel 与对称量化的取舍、以及量化后精度掉点时怎么定位到具体算子。【免费下载链接】onnxruntimeONNX Runtime: cross-platform, high performance ML inferencing and training accelerator项目地址: https://gitcode.com/GitHub_Trending/on/onnxruntime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考