Delegado de ML do Tensorflow Lite Core

O delegado do TensorFlow Lite Core ML permite a execução de modelos do TensorFlow Lite na estrutura Core ML , o que resulta em uma inferência de modelo mais rápida em dispositivos iOS.

Versões e dispositivos iOS suportados:

  • iOS 12 e posterior. Nas versões mais antigas do iOS, o delegado do Core ML retornará automaticamente para a CPU.
  • Por padrão, o delegado do Core ML só será habilitado em dispositivos com A12 SoC e posterior (iPhone Xs e posterior) para usar o Neural Engine para inferência mais rápida. Se você quiser usar o delegado do Core ML também nos dispositivos mais antigos, consulte as práticas recomendadas

Modelos compatíveis

O delegado do Core ML atualmente oferece suporte aos modelos float (FP32 e FP16).

Tentando o delegado do Core ML em seu próprio modelo

O delegado do Core ML já está incluído no lançamento noturno do TensorFlow lite CocoaPods. Para usar o delegado do Core ML, altere seu pod lite do TensorFlow para incluir a subespecificação CoreML em seu Podfile .

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

OU

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

Rápido

    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)
    }
  

Objetivo-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 (Até 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);
      

Melhores Práticas

Como usar o delegado do Core ML em dispositivos sem o Neural Engine

Por padrão, o delegado do Core ML só será criado se o dispositivo tiver o Neural Engine e retornará null se o delegado não for criado. Se você deseja executar o delegado do Core ML em outros ambientes (por exemplo, simulador), passe .all como uma opção ao criar o delegado no Swift. Em C++ (e Objective-C), você pode passar TfLiteCoreMlDelegateAllDevices . O exemplo a seguir mostra como fazer isso:

Rápido

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

Objetivo-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
      

Usando o delegado Metal(GPU) como um substituto.

Quando o delegado do Core ML não é criado, como alternativa, você ainda pode usar o delegado do Metal para obter benefícios de desempenho. O exemplo a seguir mostra como fazer isso:

Rápido

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

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

Objetivo-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
      

A lógica de criação do delegado lê o ID da máquina do dispositivo (por exemplo, iPhone11,1) para determinar a disponibilidade do Neural Engine. Veja o código para mais detalhes. Como alternativa, você pode implementar seu próprio conjunto de dispositivos de lista de proibições usando outras bibliotecas, como DeviceKit .

Usando uma versão mais antiga do Core ML

Embora o iOS 13 ofereça suporte ao Core ML 3, o modelo pode funcionar melhor quando convertido com a especificação do modelo Core ML 2. A versão de conversão de destino é definida para a versão mais recente por padrão, mas você pode alterar isso definindo coreMLVersion (em Swift, coreml_version na API C) na opção delegada para versão mais antiga.

Operações compatíveis

As seguintes operações são suportadas pelo delegado do Core ML.

  • Adicionar
    • Apenas algumas formas podem ser transmitidas. No layout do tensor do Core ML, as seguintes formas de tensor podem ser transmitidas. [B, C, H, W] , [B, C, 1, 1] , [B, 1, H, W] , [B, 1, 1, 1] .
  • AveragePool2D
  • Concatenar
    • A concatenação deve ser feita ao longo do eixo do canal.
  • Conv2D
    • Pesos e viés devem ser constantes.
  • DepthwiseConv2D
    • Pesos e viés devem ser constantes.
  • Totalmente Conectado (também conhecido como Dense ou InnerProduct)
    • Pesos e viés (se presentes) devem ser constantes.
    • Suporta apenas caso de lote único. As dimensões de entrada devem ser 1, exceto a última dimensão.
  • Hardswish
  • Logística (também conhecido como sigmóide)
  • MaxPool2D
  • MirrorPad
    • Apenas a entrada 4D com modo REFLECT é suportada. O preenchimento deve ser constante e só é permitido para as dimensões H e W.
  • Mul
    • Apenas algumas formas podem ser transmitidas. No layout do tensor do Core ML, as seguintes formas de tensor podem ser transmitidas. [B, C, H, W] , [B, C, 1, 1] , [B, 1, H, W] , [B, 1, 1, 1] .
  • Pad e PadV2
    • Apenas a entrada 4D é suportada. O preenchimento deve ser constante e só é permitido para as dimensões H e W.
  • Relu
  • ReluN1To1
  • Relu6
  • Remodelar
    • Compatível apenas quando a versão do Core ML de destino é 2, não compatível com o Core ML 3.
  • Redimensionar Bilinear
  • SoftMax
  • Tanh
  • TransposeConv
    • Os pesos devem ser constantes.

Comentários

Para problemas, crie um problema no GitHub com todos os detalhes necessários para reproduzir.

Perguntas frequentes

  • O delegado do CoreML dá suporte ao fallback para a CPU se um gráfico contiver operações sem suporte?
    • Sim
  • O delegado CoreML funciona no iOS Simulator?
    • Sim. A biblioteca inclui alvos x86 e x86_64 para que possa ser executada em um simulador, mas você não verá aumento de desempenho sobre a CPU.
  • O delegado do TensorFlow Lite e CoreML é compatível com MacOS?
    • O TensorFlow Lite é testado apenas no iOS, mas não no MacOS.
  • As operações personalizadas do TF Lite são suportadas?
    • Não, o delegado CoreML não oferece suporte a operações personalizadas e eles retornarão à CPU.

API