目录

端侧推理框架选型实战:Core ML、LiteRT、ONNX Runtime、NCNN、MNN 怎么选

模型训练完只是第一步,把它塞进手机、嵌入式设备、NAS 才是真正的考验。推理框架选错,后面转换报错、性能不达标、平台不支持,全部返工。本文用一张对比表加一个决策树,帮你十分钟定下框架选型。

五个框架一句话定位

先给结论性对比(star 数为 2026-08 实测 GitHub 数据):

框架 维护方 主打平台 模型格式 量化支持 硬件加速 GitHub star
Core ML Apple iOS/iPadOS/macOS .mlpackage FP16/INT8 神经网络引擎/GPU/CPU 5.4k
LiteRT(原 TensorFlow Lite) Google Android/iOS/Linux/单片机 .tflite FP16/INT8 GPU 委托/NNAPI/Hexagon DSP 并入 TensorFlow 仓库
ONNX Runtime Mobile 微软 全平台 .onnx INT8 动态/静态 XNNPACK/NNAPI/Core ML 执行提供程序 2.1万
NCNN 腾讯 Android/iOS/Linux/嵌入式 .param + .bin INT8/FP16 Vulkan GPU/ARM NEON 2.4万
MNN 阿里巴巴 全平台 .mnn INT8/FP16 Metal/Vulkan/OpenCL/NNAPI 1.6万

两个容易踩的认知更新:

  1. TensorFlow Lite 已更名 LiteRT:2024 年底 Google 官方宣布更名,老文章里的 TFLite 名词仍然通用,但新项目查文档、找依赖要搜 LiteRT,官方仓库也从 tensorflow 移到了独立的 LiteRT 仓库。
  2. ONNX Runtime 不只是服务端引擎:它 star 数已超 2.1 万,Mobile 包(onnxruntime-mobile)是跨平台端侧部署的成熟选择,服务端和端侧共用同一份 ONNX 模型,省掉二次转换。

怎么选:一张决策树

按你的实际约束走,不用把五个框架都研究一遍:

  1. 只做 iOS 生态、不跨平台:直接 Core ML。Xcode 一键集成,Vision framework 帮你做图像预处理,神经网络引擎(ANE)加速白拿,coremltools 转换链最成熟。
  2. 只做 Android、或 Android 为主:LiteRT 与 NCNN 二选一。要 Google 官方生态、NNAPI 硬件加速,选 LiteRT;要极致轻量、零第三方依赖、老机器也能流畅跑,选 NCNN(纯 C++ 实现,自带 Vulkan GPU 加速)。
  3. 服务端与端侧共用一套模型:ONNX Runtime。训练用 PyTorch,导出 ONNX 后服务端用 onnxruntime,端侧用 onnxruntime-mobile,一套模型两端跑。
  4. 跨平台统一 SDK(iOS + Android + Linux 桌面):MNN 或 ONNX Runtime Mobile。MNN 的 Metal/Vulkan/OpenCL 三套 GPU 后端覆盖最全,对 PyTorch 导出的模型兼容性好。
  5. 嵌入式 Linux / 树莓派 / 工控机:NCNN。无第三方依赖、可直接交叉编译,ARM NEON 优化到位,是端侧框架里对低配硬件最友好的一个。

实战:同一模型,两种框架集成

以 MobileNetV2 图像分类为例(3.4M 参数,FP32 约 13.6MB,INT8 约 3.4MB),演示转换与推理链路。

路径一:PyTorch 导出 ONNX,喂给 ONNX Runtime Mobile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import torch
from torchvision.models import mobilenet_v2, MobileNet_V2_Weights

model = mobilenet_v2(weights=MobileNet_V2_Weights.IMAGENET1K_V1)
model.eval()

# 动态 batch 维度,方便端侧按需推理
dummy = torch.randn(1, 3, 224, 224)
torch.onnx.export(
    model, dummy, "mobilenetv2.onnx",
    input_names=["input"], output_names=["output"],
    dynamic_axes={"input": {0: "batch"}, "output": {0: "batch"}},
    opset_version=17,
)

移动端集成用 C++ API,注意在 SessionOptions 里限制线程数、开启图优化:

1
2
3
4
5
6
Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "mobile");
Ort::SessionOptions opts;
opts.SetIntraOpNumThreads(2);   // 移动端不是线程越多越快
opts.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);
Ort::Session session(env, "mobilenetv2.onnx", opts);
// input 为 224x224x3 的 float 张量,直接 Run 即可

路径二:NCNN 极简接入

NCNN 用 .param + .bin 两个文件描述模型,PyTorch 模型先导出 ONNX,再用官方工具 onnx2ncnn 转换,推理代码非常直接:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include "net.h"

ncnn::Net net;
net.opt.use_vulkan_compute = true;  // 设备有 GPU 就开 Vulkan 加速
net.load_param("mobilenetv2.param");
net.load_model("mobilenetv2.bin");

ncnn::Mat in = ncnn::Mat::from_pixels_resize(
    rgb_data, ncnn::Mat::PIXEL_RGB, w, h, 224, 224);
// 归一化后执行 forward,输出 1000 维分类得分

三个高频踩坑

  1. Core ML 转换失败先查算子:PyTorch 太新的算子 coremltools 可能不支持。先用 torch.onnx.export 转 ONNX,再经 onnx-coreml 走一遍,报错信息更友好,也方便定位到具体算子。
  2. 神经网络引擎对 INT8 不感冒:Core ML 的 ANE 对 FP16 优化最好,INT8 在 ANE 上反而可能变慢。想要小体积优先用 FP16,不要无脑 INT8。
  3. INT8 量化必须做校准:直接 post-training 量化,分类模型一般掉点不到 1%,前提是给足校准集(几百张有代表性的图),否则个别类别可能崩掉。

结论

选型本质是平台约束优先:Apple 生态无脑 Core ML,Android 生态 LiteRT/NCNN 二选一,跨平台统一模型选 ONNX Runtime 或 MNN。模型侧建议训练时就以 PyTorch 导出 ONNX 作为中间格式,端侧框架随时可换,不被任何一家绑死。下一个实战可以直接复用这套链路,把自家模型快速部署到目标设备上实测延迟和内存。