Delegado de LiteRT Core ML

El delegado de Core ML de LiteRT permite ejecutar modelos LiteRT en Framework de Core ML, que da como resultado 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 se habilitará en dispositivos con SoC A12 y posteriores (iPhone Xs y modelos posteriores) para usar Neural Engine para una inferencia más rápida. Si quieres usar el delegado de Core ML en los dispositivos más antiguos, consulta prácticas recomendadas

Modelos compatibles

Actualmente, el delegado de Core ML admite modelos 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 LiteRT CocoaPods. Si quieres usar el delegado de Core ML, cambia el Pod de LiteRT para incluir subespecificación CoreML en su 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

Usa el delegado de Core ML en dispositivos sin Neural Engine

De forma predeterminada, el delegado de Core ML solo se creará si el dispositivo tiene Engine, y mostrará null si no se crea el delegado. Si deseas Ejecuta el delegado de Core ML en otros entornos (por ejemplo, un simulador), pasa .all como opción mientras creas el delegado en Swift. En C++ (y Objective-C), puedes pasa 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, puedes seguir usando Delegado de metal para obtener 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) en determinar su disponibilidad del motor neuronal. Consulta la código para obtener más detalles. También puedes implementar tu propio conjunto de listas de bloqueo dispositivos que usan 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 si es se convierten con la especificación del modelo Core ML 2. La versión de conversión objetivo es está configurada en la versión más reciente de forma predeterminada, pero puedes cambiarla estableciendo coreMLVersion (en Swift, coreml_version en la API de C) en la opción de delegar a versión anterior.

Operaciones admitidas

El delegado de Core ML admite las siguientes operaciones.

  • Se agregó
    • Solo se pueden transmitir ciertas formas. En el diseño de tensor de Core ML, las siguientes formas de tensor se pueden transmitir. [B, C, H, W], [B, C, 1, 1], [B, 1, H, W], [B, 1, 1, 1]
  • PromedioGrupo2D
  • Concat
    • La concatenación se debe realizar en el eje del canal.
  • Conv. 2D
    • Los pesos y el sesgo deben ser constantes.
  • DepthwiseConv2D
    • Los pesos y el sesgo deben ser constantes.
  • FullyConnected (también conocido como Dense o InnerProduct)
    • Los pesos y el sesgo (si están presentes) deben ser constantes.
    • Solo es compatible con casos de lote único. Las dimensiones de entrada deben ser 1, excepto la última dimensión.
  • Hardswish
  • Logística (también conocida como sigmoidea)
  • GrupoMáximo2D
  • MirrorPad
    • Solo se admite la entrada 4D con el modo REFLECT. El relleno debe tener las siguientes características: 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, las siguientes formas de tensor se pueden transmitir. [B, C, H, W], [B, C, 1, 1], [B, 1, H, W], [B, 1, 1, 1]
  • Pad y PadV2
    • Solo se admite la entrada 4D. El relleno debe ser constante y solo para las dimensiones H y W.
  • Relu
  • ReLUN1To1
  • Relu6
  • Cambiar forma
    • Solo es compatible cuando la versión de destino de Core ML es 2; no se admite cuando orientadas a Core ML 3.
  • ResizeBilinear
  • SoftMax
  • Tanh
  • TransposeConv
    • Los pesos deben ser constantes.

Comentarios

Si tienes problemas, crea un GitHub con todos los detalles necesarios para reproducirlo.

Preguntas frecuentes

  • ¿El delegado de CoreML admite el resguardo a la CPU si un gráfico contiene elementos no admitidos? las operaciones?
  • ¿El delegado de CoreML funciona en el simulador de iOS?
    • Sí. La biblioteca incluye destinos x86 y x86_64 para que pueda ejecutarse pero no verás un aumento del rendimiento con la CPU.
  • ¿Los delegados LiteRT y CoreML son compatibles con MacOS?
    • LiteRT solo se prueba en iOS, pero no en MacOS.
  • ¿Se admiten operaciones de LiteRT personalizadas?
    • No, el delegado de CoreML no admite operaciones personalizadas y recurrirá a CPU.

API