LiteRT nas APIs C e C++ do Google Play Services

O LiteRT no ambiente de execução do Google Play Services permite executar modelos de aprendizado de máquina (ML) sem agrupar estaticamente as bibliotecas do LiteRT no app. Este guia fornece instruções sobre como usar as APIs C ou C++ para os serviços do Google Play.

Antes de trabalhar com o LiteRT na API C ou C++ do Google Play Services, instale a ferramenta de build CMake.

Atualizar a configuração da compilação

(1) Adicione as seguintes dependências ao código do projeto do app para acessar a API Play Services para LiteRT:

implementation "com.google.android.gms:play-services-tflite-java:16.4.0"

Embora o nome do pacote termine em -java, ele também contém as APIs C e C++.

(2) Em seguida, ative o recurso Prefab para acessar a API C do script do CMake atualizando o bloco android do arquivo build.gradle do módulo:

buildFeatures {
  prefab = true
}

(3) [Somente API C++] Se você estiver usando a API C++, copie tflite-java-extract-cpp-sdk.gradle para o projeto, no diretório app, e adicione o seguinte ao início do script do gradle do app (por exemplo, app/build.gradle):

apply from: 'tflite-java-extract-cpp-sdk.gradle'

Ele contém o código do Gradle para descompactar automaticamente o SDK C++ do arquivo AAR para play-services-tflite-java.

(4) [Somente API C++] Se você estiver usando a API C++, encontre o diretório que contém o arquivo de configuração do CMake do app (normalmente CMakeLists.txt). Esse diretório normalmente é o app/src/main/cpp. Em seguida, copie Findtflite_cc_api.cmake para o projeto, em um novo subdiretório Modules desse diretório. Ele contém o código que encontra o SDK C++ descompactado pelo script do Gradle na etapa anterior.

(5) Por fim, é necessário adicionar o pacote tensorflowlite_jni_gms_client e, para a API C++, também o pacote tflite_cc_api, ambos importados do AAR, como dependências no script do CMake:

C

``` find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG) # Configurar sinalizadores do compilador C/C++ para permitir o uso do TFLite no Google Play Services # (em vez do TFLite regular incluído no app). add_compile_definitions(TFLITE_IN_GMSCORE) add_compile_definitions(TFLITE_WITH_STABLE_ABI) target_link_libraries(tflite-jni # your JNI lib target tensorflowlite_jni_gms_client::tensorflowlite_jni_gms_client android # other deps for your target log) ```

C++

``` # Configurar a dependência do TFLite na API C do Google Play (tensorflowlite_jni_gms_client). find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG) # Configurar a dependência do TFLite na API C++ do Play Services (tflite_cc_api). list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Modules") find_package(tflite_cc_api REQUIRED MODULE) include_directories(${tflite_cc_api_INCLUDE_DIR}) add_subdirectory(${tflite_cc_api_DIR} tflite_cc_api_build) # Configurar flags do compilador C/C++ para permitir o uso do TFLite no Play Services # (em vez do TFLite regular incluído no app). add_compile_definitions(TFLITE_IN_GMSCORE) add_compile_definitions(TFLITE_WITH_STABLE_ABI) target_link_libraries(tflite-jni # your JNI lib target tflite_cc_api::tflite_cc_api tensorflowlite_jni_gms_client::tensorflowlite_jni_gms_client android # other deps for your target log) ```

Inicializar o ambiente de execução do LiteRT

Antes de chamar a API nativa LiteRT, é necessário inicializar o ambiente de execução TfLiteNative no código Java ou Kotlin.

Java

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

Usando a API Task do Google Play Services, TfLiteNative.initialize carrega assíncronamente o ambiente de execução do TFLite do Google Play Services no processo de execução do seu app. Use addOnSuccessListener() para garantir que a tarefa TfLite.initialize() seja concluída antes de executar o código que acessa as APIs LiteRT. Depois que a tarefa for concluída, você poderá invocar todas as APIs nativas do TFLite disponíveis.

Implementação de código nativo

Para usar o LiteRT nos serviços do Google Play com seu código C/C++, faça uma ou ambas as seguintes ações:

  • declarar novas funções JNI para chamar funções C ou C++ do código Java
  • chame a API Native do LiteRT do seu código C ou C++.

Funções JNI

É possível declarar novas funções JNI para tornar o ambiente de execução LiteRT declarado em código C/C++ acessível ao código Java/Kotlin da seguinte maneira:

Java

package com.google.samples.gms.tflite.c;

public class TfLiteJni {
  static {
    System.loadLibrary("tflite-jni");
  }
  public TfLiteJni() { /**/ };
  public native void loadModel(AssetManager assetManager, String assetName);
  public native float[] runInference(float[] input);  // For example.
}
      

Kotlin

package com.google.samples.gms.tflite.c

class TfLiteJni() {
  companion object {
    init {
      System.loadLibrary("tflite-jni")
    }
  }
  external fun loadModel(assetManager: AssetManager, assetName: String)
  external fun runInference(input: FloatArray): FloatArray  // For example.
}
        

Correspondem às seguintes funções C ou C++ loadModel e runInference:

#ifdef __cplusplus
extern "C" {
#endif

void Java_com_google_samples_gms_tflite_c_loadModel(
  JNIEnv *env, jobject tflite_jni, jobject asset_manager, jstring asset_name){
  //...
}

jfloatArray Java_com_google_samples_gms_tflite_c_TfLiteJni_runInference(
  JNIEnv* env, jobject tfliteJni, jfloatArray input) {
  //...
}

#ifdef __cplusplus
}  // extern "C".
#endif

Em seguida, chame as funções C/C++ do código Java/Kotlin:

Java

tfLiteHandleTask.onSuccessTask(unused -> {
    TfLiteJni jni = new TfLiteJni();
    jni.loadModel(getAssets(), "add.bin");
    //...
});
    

Kotlin

tfLiteHandleTask.onSuccessTask {
    val jni = TfLiteJni()
    jni.loadModel(assets, "add.bin")
    // ...
}
      

LiteRT em código nativo

Inclua o arquivo de cabeçalho da API apropriado para incluir o LiteRT com a API do Google Play Services:

C

``` #include "tensorflow/lite/c/c_api.h" ```

C++

``` #include "tensorflow/lite/interpreter.h" #include "tensorflow/lite/model_builder.h" ```

Em seguida, use a API LiteRT C ou C++ normal:

C

```c++ TfLiteModel* model = TfLiteModelCreate(model_asset, model_asset_length); // ... TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate(); // ... TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options); ```

C++

```c++ // Carregar o modelo. auto model = tflite::FlatBufferModel::VerifyAndBuildFromBuffer( model_asset, model_asset_length); ... // Inicialize o intérprete. BuiltinOpResolver op_resolver; InterpreterBuilder interpreter_builder(*model, op_resolver); interpreter_builder(&interpreter); std::unique_ptr<Interpreter>` interpreter; interpreter_builder(&interpreter); ```

APIs compatíveis

C

Os cabeçalhos da API nativa do LiteRT com os serviços do Google Play fornecem a mesma API que a [API C do LiteRT](../../api/tflite/c) (link em inglês) normal, excluindo recursos descontinuados ou experimentais. Por enquanto, as funções e os tipos dos cabeçalhos a seguir estão disponíveis. APIs do TensorFlow Lite para carregar e executar modelos: ```none tensorflow/lite/c/c_api.h tensorflow/lite/c/c_api_types.h ``` APIs de extensão do TensorFlow Lite para definir operações e delegados personalizados (por exemplo, para aceleração de hardware): ```none tensorflow/lite/c/c_api_opaque.h tensorflow/lite/c/common.h tensorflow/lite/c/builtin_op_data.h tensorflow/lite/builtin_ops.h ``` APIs de plug-in delegados para usar delegados existentes: ```none tensorflow/lite/acceleration/configuration/c/gpu_plugin.h tensorflow/lite/acceleration/configuration/c/xnnpack_plugin.h ``` As funções do cabeçalho "c_api_experimental.h" não têm suporte. É possível usar funções específicas do LiteRT com o Google Play Services incluindo "tensorflow/lite/abi/tflite.h".

C++

Os cabeçalhos da API nativa do LiteRT com o Google Play Services fornecem a mesma API que a [API C++ do LiteRT](../../api/tflite/cc), exceto recursos descontinuados ou experimentais, e com algumas exceções menores mencionadas mais adiante nesta seção. A API com suporte em "tensorflow/lite/interpreter.h" com os Serviços do Google Play exclui alguns membros de "tflite::Interpreter" para os quais o LiteRT não oferece uma ABI estável: ```c++ Interpreter::variables() Interpreter::nodes_size() Interpreter::node_and_registration(int node_index) Interpreter::kTensorsReservedCapacity Interpreter::kTensorsCapacityHeadroom Interpreter::OpProfilingString(const TfLiteRegistration&, const TfLiteNode*) Interpreter::SetExternalContext(TfLiteExternalContextType type, TfLiteExternalContext* ctx) ```