Delegado do Tensorflow Lite Core ML

O delegado TensorFlow Lite Core ML permite a execução de modelos do TensorFlow Lite na estrutura Core ML , o que resulta em 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 Core ML retornará automaticamente à CPU.
  • Por padrão, o delegado Core ML só será habilitado em dispositivos com SoC A12 e posteriores (iPhone Xs e posteriores) para usar o Neural Engine para inferência mais rápida. Se você quiser usar o delegado Core ML também em dispositivos mais antigos, consulte as práticas recomendadas

Modelos suportados

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

Experimentando o delegado Core ML em seu próprio modelo

O delegado Core ML já está incluído no lançamento noturno do TensorFlow lite CocoaPods. Para usar o delegado Core ML, altere seu pod TensorFlow Lite 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

Usando delegado Core ML em dispositivos sem Neural Engine

Por padrão, o delegado Core ML só será criado se o dispositivo tiver Neural Engine e retornará null se o delegado não for criado. Se você deseja executar o delegado 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 substituto.

Quando o delegado Core ML não é criado, como alternativa, você ainda pode usar o delegado 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 de delegado lê o ID da máquina do dispositivo (por exemplo, iPhone11,1) para determinar a disponibilidade do seu Neural Engine. Veja o código para mais detalhes. Alternativamente, você pode implementar seu próprio conjunto de dispositivos de lista de bloqueio usando outras bibliotecas, como DeviceKit .

Usando uma versão mais antiga do Core ML

Embora o iOS 13 suporte 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 como 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 de delegação para uma versão mais antiga.

Operações suportadas

As operações a seguir são suportadas pelo delegado Core ML.

  • Adicionar
    • Apenas certas formas podem ser transmitidas. No layout do tensor 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] .
  • MédiaPool2D
  • Concat
    • A concatenação deve ser feita ao longo do eixo do canal.
  • Conv2D
    • Os pesos e o viés devem ser constantes.
  • ProfundidadeConv2D
    • Os pesos e o viés devem ser constantes.
  • FullyConnected (também conhecido como Dense ou InnerProduct)
    • Os pesos e as tendências (se presentes) devem ser constantes.
    • Suporta apenas casos de lote único. As dimensões de entrada devem ser 1, exceto a última dimensão.
  • Desejo duro
  • Logística (também conhecida como Sigmóide)
  • MaxPool2D
  • EspelhoPad
    • Somente a entrada 4D com modo REFLECT é suportada. O preenchimento deve ser constante e só é permitido para dimensões H e W.
  • Mul
    • Apenas certas formas podem ser transmitidas. No layout do tensor 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 dimensões H e W.
  • Relu
  • ReluN1To1
  • Relu6
  • Remodelar
    • Compatível apenas quando a versão de destino do Core ML é 2, não compatível com o destino do Core ML 3.
  • Redimensionar Bilinear
  • SoftMax
  • Tanh
  • TransporConv
    • Os pesos devem ser constantes.

Opinião

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

Perguntas frequentes

  • O delegado CoreML suporta fallback para CPU se um gráfico contiver operações não suportadas?
    • 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 em relação à CPU.
  • O delegado TensorFlow Lite e CoreML é compatível com MacOS?
    • O TensorFlow Lite é testado apenas em iOS, mas não em 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.

APIs