Tensorflow Lite Core ML 代理

TensorFlow Lite Core ML 代理支持在 Core ML 框架上运行 TensorFlow Lite 模型,从而加快在 iOS 设备上进行模型推断的速度。

支持的 iOS 版本和设备

  • iOS 12 及更高版本。在旧版 iOS 中,Core ML 委托会自动回退到 CPU。
  • 默认情况下,系统只会在搭载 A12 SoC 及更高版本的设备(iPhone Xs 及更高版本)上启用 Core ML 代理,以便使用 Neural Engine 来加快推断速度。如果您还想在旧版设备上使用 Core ML 委托,请参阅最佳实践

支持的模型

Core ML 代理目前支持浮点(FP32 和 FP16)模型。

在您自己的模型上试用 Core ML 代理

Core ML 代理已包含在每夜发布的 TensorFlow lite CocoaPods 中。如需使用 Core ML 代理,请将您的 TensorFlow lite pod 更改为在 Podfile 中添加子规范 CoreML

target 'YourProjectName'
  pod 'TensorFlowLiteSwift/CoreML', '~> 2.4.0'  # Or TensorFlowLiteObjC/CoreML

OR

# Particularily useful when you also want to include 'Metal' subspec.
target 'YourProjectName'
  pod 'TensorFlowLiteSwift', '~> 2.4.0', :subspecs => ['CoreML']

Swift

    let coreMLDelegate = CoreMLDelegate()
    var interpreter: Interpreter

    // Core ML delegate will only be created for devices with Neural Engine
    if coreMLDelegate != nil {
      interpreter = try Interpreter(modelPath: modelPath,
                                    delegates: [coreMLDelegate!])
    } else {
      interpreter = try Interpreter(modelPath: modelPath)
    }
  

Objective-C


    // Import module when using CocoaPods with module support
    @import TFLTensorFlowLite;

    // Or import following headers manually
    # import "tensorflow/lite/objc/apis/TFLCoreMLDelegate.h"
    # import "tensorflow/lite/objc/apis/TFLTensorFlowLite.h"

    // Initialize Core ML delegate
    TFLCoreMLDelegate* coreMLDelegate = [[TFLCoreMLDelegate alloc] init];

    // Initialize interpreter with model path and Core ML delegate
    TFLInterpreterOptions* options = [[TFLInterpreterOptions alloc] init];
    NSError* error = nil;
    TFLInterpreter* interpreter = [[TFLInterpreter alloc]
                                    initWithModelPath:modelPath
                                              options:options
                                            delegates:@[ coreMLDelegate ]
                                                error:&error];
    if (error != nil) { /* Error handling... */ }

    if (![interpreter allocateTensorsWithError:&error]) { /* Error handling... */ }
    if (error != nil) { /* Error handling... */ }

    // Run inference ...
  

C(直到 2.3.0)

    #include "tensorflow/lite/delegates/coreml/coreml_delegate.h"

    // Initialize interpreter with model
    TfLiteModel* model = TfLiteModelCreateFromFile(model_path);

    // Initialize interpreter with Core ML delegate
    TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate();
    TfLiteDelegate* delegate = TfLiteCoreMlDelegateCreate(NULL);  // default config
    TfLiteInterpreterOptionsAddDelegate(options, delegate);
    TfLiteInterpreterOptionsDelete(options);

    TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options);

    TfLiteInterpreterAllocateTensors(interpreter);

    // Run inference ...

    /* ... */

    // Dispose resources when it is no longer used.
    // Add following code to the section where you dispose of the delegate
    // (e.g. `dealloc` of class).

    TfLiteInterpreterDelete(interpreter);
    TfLiteCoreMlDelegateDelete(delegate);
    TfLiteModelDelete(model);
      

最佳实践

在没有 Neural Engine 的设备上使用 Core ML 代理

默认情况下,仅当设备具有 Neural Engine 时,才会创建 Core ML 委托;如果未创建该委托,则返回 null。如果您要在其他环境(例如模拟器)上运行 Core ML 委托,请在 Swift 中创建委托时传递 .all 选项。在 C++(和 Objective-C)中,您可以传递 TfLiteCoreMlDelegateAllDevices。以下示例展示了如何执行此操作:

Swift

    var options = CoreMLDelegate.Options()
    options.enabledDevices = .all
    let coreMLDelegate = CoreMLDelegate(options: options)!
    let interpreter = try Interpreter(modelPath: modelPath,
                                      delegates: [coreMLDelegate])
      

Objective-C

    TFLCoreMLDelegateOptions* coreMLOptions = [[TFLCoreMLDelegateOptions alloc] init];
    coreMLOptions.enabledDevices = TFLCoreMLDelegateEnabledDevicesAll;
    TFLCoreMLDelegate* coreMLDelegate = [[TFLCoreMLDelegate alloc]
                                          initWithOptions:coreMLOptions];

    // Initialize interpreter with delegate
  

C

    TfLiteCoreMlDelegateOptions options;
    options.enabled_devices = TfLiteCoreMlDelegateAllDevices;
    TfLiteDelegate* delegate = TfLiteCoreMlDelegateCreate(&options);
    // Initialize interpreter with delegate
      

使用 Metal(GPU) 代理作为后备方案。

如果未创建 Core ML 代理,您仍然可以使用 Metal 代理来提升性能。以下示例展示了如何执行此操作:

Swift

    var delegate = CoreMLDelegate()
    if delegate == nil {
      delegate = MetalDelegate()  // Add Metal delegate options if necessary.
    }

    let interpreter = try Interpreter(modelPath: modelPath,
                                      delegates: [delegate!])
  

Objective-C

    TFLDelegate* delegate = [[TFLCoreMLDelegate alloc] init];
    if (!delegate) {
      // Add Metal delegate options if necessary
      delegate = [[TFLMetalDelegate alloc] init];
    }
    // Initialize interpreter with delegate
      

C

    TfLiteCoreMlDelegateOptions options = {};
    delegate = TfLiteCoreMlDelegateCreate(&options);
    if (delegate == NULL) {
      // Add Metal delegate options if necessary
      delegate = TFLGpuDelegateCreate(NULL);
    }
    // Initialize interpreter with delegate
      

委托创建逻辑会读取设备的机器 ID(例如 iPhone11、1),以确定其 Neural Engine 可用性。如需了解详情,请参阅代码。或者,您也可以使用其他库(如 DeviceKit)实现自己的一组拒绝名单设备。

使用旧版 Core ML

虽然 iOS 13 支持 Core ML 3,但如果根据 Core ML 2 模型规范进行转换,该模型可能会更好地发挥作用。目标转换版本默认设置为最新版本,但您可以通过将委托选项中的 coreMLVersion(在 Swift 中,在 C API 中是 coreml_version)设置为旧版本来更改此设置。

支持的操作

Core ML 代理支持以下操作。

  • 添加了
    • 只有特定形状是可以广播的。在 Core ML 张量布局中,以下张量形状是可广播的。[B, C, H, W][B, C, 1, 1][B, 1, H, W][B, 1, 1, 1]
  • 2D 平均值池
  • 连接
    • 串联应沿着通道轴进行。
  • 转化 2D
    • 权重和偏差应该恒定。
  • DepthwiseConv2D
    • 权重和偏差应该恒定。
  • 完全连接(也称为 Dense 或 InnerProduct)
    • 权重和偏差(如果存在)应该恒定。
    • 仅支持单批次情况。输入维度应为 1,但最后一个维度除外。
  • 硬地星
  • 逻辑函数(也称为 S 型函数)
  • 最大池 2D
  • MirrorPad
    • 系统仅支持在 REFLECT 模式下使用 4D 输入。内边距应为常量,且只能用于 H 和 W 尺寸。
  • Mul
    • 只有特定形状是可以广播的。在 Core ML 张量布局中,以下张量形状是可广播的。[B, C, H, W][B, C, 1, 1][B, 1, H, W][B, 1, 1, 1]
  • Pad 和 PadV2
    • 仅支持 4D 输入。内边距应为常量,且只允许针对 H 和 W 尺寸使用。
  • ReLU
  • ReluN1To1
  • Relu6
  • 调整形状
    • 仅在目标 Core ML 版本为 2 时受支持;以 Core ML 3 为目标平台时不受支持。
  • ResizeBilinear
  • SoftMax
  • 三角形
  • TransposeConv
    • 权重应该恒定。

反馈

如有问题,请创建 GitHub 问题,并提供重现问题所需的所有详细信息。

常见问题解答

  • 如果图包含不受支持的操作,CoreML 委托是否支持回退到 CPU?
  • CoreML 委托是否可以在 iOS 模拟器上运行?
    • 可以。该库包含 x86 和 x86_64 目标,因此可以在模拟器上运行,但性能在 CPU 上不会得到提升。
  • TensorFlow Lite 和 CoreML 委托是否支持 MacOS?
    • TensorFlow Lite 仅在 iOS 上进行了测试,不会在 MacOS 上进行测试。
  • 是否支持自定义 TF Lite 操作?
    • 不能,CoreML 委托不支持自定义操作,它们将回退到 CPU。

API