目录

端侧目标检测实战:YOLOv8 导出 Core ML 部署到 iPhone

为什么让手机自己"看"

云端识别 API 成熟好用,但三个痛点始终绕不开:隐私——画面要上传到别人服务器;时延——往返一次网络 200-500ms,实时视频流根本扛不住;成本——按次计费,摄像头一直开着就是烧钱。端侧部署把模型塞进手机,推理不出设备,隐私、时延、成本一次解决。这也是智能安防、工业质检、AR 应用的主流做法。

选模型:YOLOv8n 是性价比起点

Ultralytics YOLOv8 是当前落地最广的目标检测家族。模型命名规则很直白:字母越小越轻量。端侧部署首选 YOLOv8n(nano):

模型 参数量 权重大小 COCO mAP50-95 定位
YOLOv8n 3.2M ~6MB 37.3 手机端首选,实时
YOLOv8s 11.2M ~22MB 44.9 平衡精度与速度
YOLOv8m 25.9M ~52MB 50.2 追求精度,平板/桌面

以上为 Ultralytics 官方 COCO 预训练数据。3.2M 参数对 NPU/GPU 来说毫无压力,实测阶段再按帧率需求往上升级即可。

第一步:导出 Core ML 模型

Apple 的推理格式是 .mlpackage(Core ML 模型包)。用 ultralytics 一行命令导出:

1
2
pip install ultralytics coremltools
yolo export model=yolov8n.pt format=coreml imgsz=640

输出 yolov8n.mlpackage,默认 FP32。想更小更快,用 coremltools 转成 FP16(精度损失可忽略):

1
2
3
4
import coremltools as ct
model = ct.models.MLModel("yolov8n.mlpackage")
model = ct.models.neural_network.quantization_utils.quantize_weights(model, nbits=16)
model.save("yolov8n_fp16.mlpackage")

FP16 版本体积砍半(约 3MB),A 系列芯片的 ANE(神经网络引擎)原生支持 FP16,推理速度反而更快。INT8 量化能再压一半,但目标检测对精度敏感,mAP 会掉 2-4 个点,建议先跑 FP16。

第二步:Vision 框架集成,Swift 代码 30 行

Xcode 里把 .mlpackage 拖进工程,勾选 Target Membership,系统自动生成 YOLOv8n 类。然后交给 Vision 框架,它会自动调度 ANE:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import Vision
import UIKit

func detectObjects(in image: UIImage) throws -> [VNRecognizedObjectObservation] {
    guard let model = try? VNCoreMLModel(for: YOLOv8n().model) else { return [] }
    let request = VNCoreMLRequest(model: model)
    request.imageCropAndScaleOption = .scaleFit  // 保持宽高比缩放
    let handler = VNImageRequestHandler(cgImage: image.cgImage!)
    try handler.perform([request])
    return request.results as? [VNRecognizedObjectObservation] ?? []
}

核心优势:NMS(非极大值抑制)由 Vision 帮你做了。YOLO 原始输出是 8400 个候选框(640x640 输入),直接在 Core ML 层做 NMS 很痛苦;而 VNRecognizedObjectObservation 直接给你去重后的结果,每个框带 boundingBox(归一化坐标)和 labels。画框时记得把归一化坐标乘回图片实际尺寸。

性能数据:够不够实时?

社区实测(640x640 输入、FP16、iPhone 真机):

设备 芯片 单帧推理耗时
iPhone 12 A14 Bionic ~35ms
iPhone 13 A15 ~25ms
iPhone 15 Pro A17 Pro ~18ms

这是社区公开实测区间,不同 iOS 版本和 thermal 状态会有波动。30fps 视频流要求单帧 33ms 以内,也就是说 A14 以上跑 YOLOv8n 都能达到实时;想留出余量,可以把输入降到 480x480(耗时约降 40%),或改用更小的 YOLOv8n 蒸馏版。

跨平台备选:一张表选框架

框架 平台 适用场景
Core ML Apple 全家桶 Vision 无缝集成,自动用 ANE
TensorFlow Lite Android/iOS 生态最大,量化工具成熟
ONNX Runtime Mobile 跨平台 模型来源广,易切换
NCNN Android 为主 腾讯开源,国内适配好
MNN Android 为主 阿里开源,端侧推理快

只做 iOS 就 Core ML;要一套代码覆盖双端,优先 TFLite 或 ONNX Runtime Mobile。

踩坑记录

  1. 输入 shape 必须匹配:导出时 imgsz=640,推理前图片要等比缩放再补边,否则 Vision 会静默输出空结果。scaleFit 就是干这个的。
  2. 不要在 Core ML 层自己写 NMS:YOLOv8 导出 Core ML 默认不带 NMS,直接读原始输出会得到 8400 个候选框。要么用 Vision 自动 NMS,要么在导出时加 nms=True 参数。
  3. 双精度输入不支持:Core ML 模型输入要求 Float32,喂 Double 数组会直接报错。
  4. 真机 vs 模拟器性能差 10 倍:ANE 只在真机可用,模拟器走 CPU,别用模拟器测帧率。

下一步

模型跑通后,可以接 AVFoundation 实时摄像头流(AVCaptureVideoDataOutput 每帧回调送 Vision 检测),配合 SwiftUI 画框覆盖层,就是一个完整的实时目标检测 App。端侧视觉的想象空间很大,从车牌识别到宠物监控都能落地,趁端侧 AI 这波红利,值得一试。