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 seu app. Este guia fornece instruções sobre como usar as APIs C ou C++ para o Google Play Services.
Antes de trabalhar com o LiteRT nas APIs C ou C++ do Google Play Services, verifique se a ferramenta de build CMake está instalada.
Atualizar a configuração da compilação
(1) Adicione as seguintes dependências ao código do projeto do app para acessar a API do 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 seu script 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 seu 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 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 geralmente é 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 do C++ descompactado pelo script do Gradle na etapa anterior.
(5) Por fim, adicione o pacote tensorflowlite_jni_gms_client e, para a API C++, o pacote tflite_cc_api. Ambos são importados do AAR como dependências no script CMake:
C
find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG) # Set up C/C++ compiler flags to enable use of LiteRT in Play services # (rather than regular LiteRT bundled with the 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++
# Set up LiteRT in Play services C API (tensorflowlite_jni_gms_client) dependency. find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG) # Set up LiteRT in Play services C++ API (tflite_cc_api) dependency. 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) # Set up C/C++ compiler flags to enable use of LiteRT in Play services # (rather than regular LiteRT bundled with the 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 LiteRT C ou C++, inicialize o
tempo de execução TfLiteNative no seu 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 de forma assíncrona o tempo de execução do LiteRT do Google Play Services no processo de tempo de execução do
aplicativo. Use addOnSuccessListener() para garantir que a tarefa
TfLite.initialize() seja concluída antes de executar o código que acessa
APIs LiteRT. Depois que a tarefa for concluída, você poderá invocar
todas as APIs nativas do LiteRT 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 as duas) das seguintes ações:
- declarar novas funções JNI para chamar funções C ou C++ do seu código Java
- chamar a API nativa do LiteRT no seu código C ou C++ atual.
Funções JNI
Você pode declarar novas funções JNI para tornar o tempo de execução do LiteRT declarado em código C/C++ acessível ao seu 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. }
Correspondência com as seguintes funções loadModel e runInference em C ou C++:
#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 a 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
TfLiteModel* model = TfLiteModelCreate(model_asset, model_asset_length); // ... TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate(); // ... TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options);
C++
// Load the model. auto model = tflite::FlatBufferModel::VerifyAndBuildFromBuffer( model_asset, model_asset_length); ... // Initialize the interpreter. 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 C do LiteRT com Google Play Services fornecem a mesma API que a API C do LiteRT normal, exceto recursos descontinuados ou experimentais. Por enquanto, as funções e os tipos dos seguintes cabeçalhos estão disponíveis.
APIs do TensorFlow Lite
tensorflow/lite/c/c_api.h tensorflow/lite/c/c_api_types.h
APIs de extensão do TensorFlow Lite
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 delegadas para usar delegados atuais:
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 são compatíveis.
Para usar funções específicas do LiteRT com o Google Play Services, inclua o seguinte cabeçalho:
tensorflow/lite/abi/tflite.h
C++
Os cabeçalhos da API C++ do LiteRT com os serviços do Google Play fornecem a mesma API que a API C++ do LiteRT normal, exceto recursos descontinuados ou experimentais, e com algumas pequenas exceções observadas mais adiante nesta seção. A funcionalidade dos seguintes cabeçalhos está disponível:
tensorflow/lite/model_builder.h tensorflow/lite/interpreter_builder.h tensorflow/lite/interpreter.h tensorflow/lite/signature_runner.h tensorflow/lite/acceleration/configuration/delegate_registry.h tensorflow/lite/kernels/builtin_op_kernels.h tensorflow/lite/kernels/register.h tensorflow/lite/tools/verifier.h
Para tensorflow/lite/interpreter.h, a API compatível com os serviços do
Play exclui alguns membros de tflite::Interpreter para os quais
o LiteRT não oferece uma ABI estável:
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)