Delegado de Core ML de Tensorflow Lite

El delegado Core ML de TensorFlow Lite permite ejecutar modelos de TensorFlow Lite en el framework de Core ML, lo que permite una inferencia de modelos más rápida en dispositivos iOS.

Versiones y dispositivos iOS compatibles:

  • iOS 12 y versiones posteriores En las versiones anteriores de iOS, el delegado de Core ML recurrirá automáticamente a la CPU.
  • De forma predeterminada, el delegado de Core ML solo estará habilitado en dispositivos con SoC A12 y versiones posteriores (iPhone Xs y versiones posteriores) a fin de usar Neural Engine para una inferencia más rápida. Si también quieres usar el delegado de Core ML en dispositivos más antiguos, consulta las prácticas recomendadas.

Modelos compatibles

Actualmente, el delegado de Core ML es compatible con los modelos de números de punto flotante (FP32 y FP16).

Prueba el delegado de Core ML en tu propio modelo

El delegado de Core ML ya se incluye en el lanzamiento nocturno de CocoaPods de TensorFlow Lite. Para usar el delegado de Core ML, cambia el Pod de TensorFlow Lite para incluir la subespecificación CoreML en tu Podfile.

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

O

# 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 (Hasta 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);
      

Prácticas recomendadas

Uso del delegado de Core ML en dispositivos sin Neural Engine

De forma predeterminada, el delegado de Core ML solo se creará si el dispositivo tiene Neural Engine y mostrará null si no se lo creó. Si quieres ejecutar el delegado de Core ML en otros entornos (por ejemplo, en el simulador), pasa .all como opción mientras creas el delegado en Swift. En C++ (y Objective-C), puedes pasar TfLiteCoreMlDelegateAllDevices. En el siguiente ejemplo, se muestra cómo hacerlo:

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
      

Uso del delegado de Metal(GPU) como resguardo

Cuando no se crea el delegado de Core ML, como alternativa, puedes usar un delegado de Metal para obtener los beneficios de rendimiento. En el siguiente ejemplo, se muestra cómo hacerlo:

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
      

La lógica de creación del delegado lee el ID de máquina del dispositivo (p.ej., iPhone11,1) para determinar la disponibilidad del motor neuronal. Consulta el código para obtener más detalles. Como alternativa, puedes implementar tu propio conjunto de dispositivos de la lista de bloqueo mediante otras bibliotecas, como DeviceKit.

Usa una versión anterior de Core ML

Aunque iOS 13 es compatible con Core ML 3, el modelo puede funcionar mejor cuando se convierte con la especificación del modelo Core ML 2. De forma predeterminada, la versión de conversión objetivo se establece en la versión más reciente, pero puedes cambiarla si configuras coreMLVersion (en Swift, coreml_version en la API de C) en la opción de delegar a la versión anterior.

Operaciones admitidas

El delegado de Core ML admite las siguientes operaciones.

  • Agregar
    • Solo se pueden transmitir ciertas formas. En el diseño de tensor de Core ML, se pueden transmitir las siguientes formas de tensores. [B, C, H, W], [B, C, 1, 1], [B, 1, H, W] y [B, 1, 1, 1].
  • GrupoPromedio2D
  • Concat
    • La concatenación se debe realizar a lo largo del eje del canal.
  • Conv2D
    • Las ponderaciones y el sesgo deben ser constantes.
  • DepthwiseConv2D
    • Las ponderaciones y el sesgo deben ser constantes.
  • Completamente conectado (también conocido como Dense o InnerProduct)
    • Las ponderaciones y el sesgo (si están presentes) deben ser constantes.
    • Solo es compatible con casos de un solo lote. Las dimensiones de entrada deben ser 1, excepto la última dimensión.
  • Hardswish
  • Logística (también conocida como sigmoide)
  • GrupoMax.2D
  • MirrorPad
    • Solo se admite la entrada 4D con el modo REFLECT. El relleno debe ser constante y solo se permite para las dimensiones H y W.
  • Mul
    • Solo se pueden transmitir ciertas formas. En el diseño de tensor de Core ML, se pueden transmitir las siguientes formas de tensores. [B, C, H, W], [B, C, 1, 1], [B, 1, H, W] y [B, 1, 1, 1].
  • Pad y PadV2
    • Solo se admite la entrada 4D. El relleno debe ser constante y solo se permite para las dimensiones H y W.
  • ReLU
  • ReLUN1To1
  • Relu6
  • Cambiar la forma
    • Solo se admite cuando la versión de Core ML de destino es 2 y no se admite cuando se orienta a Core ML 3.
  • ResizeBilinear
  • SoftMax
  • Patricio
  • TransposeConv
    • Los pesos deben ser constantes.

Comentarios

Si tienes problemas, crea un problema de GitHub con todos los detalles necesarios para reproducirlos.

Preguntas frecuentes

  • ¿El delegado CoreML admite el resguardo a la CPU si un gráfico contiene operaciones no compatibles?
  • ¿El delegado CoreML funciona en el simulador de iOS?
    • Sí. La biblioteca incluye objetivos de x86 y x86_64, por lo que se puede ejecutar en un simulador, pero no verás un aumento en el rendimiento de la CPU.
  • ¿El delegado de TensorFlow Lite y CoreML es compatible con macOS?
    • TensorFlow Lite solo se prueba en iOS, pero no en macOS.
  • ¿Se admiten operaciones personalizadas de TF Lite?
    • No, el delegado de CoreML no admite operaciones personalizadas y recurrirá a la CPU.

APIs