LiteRT w interfejsach API usług Google Play w językach C i C++

Środowisko wykonawcze LiteRT w usługach Google Play umożliwia uruchamianie modeli uczenia maszynowego bez statycznego dołączania bibliotek LiteRT do aplikacji. Ten przewodnik zawiera instrukcje korzystania z interfejsów API usług Google Play w językach C i C++.

Przed rozpoczęciem pracy z LiteRT w interfejsie C API lub C++ API usług Google Play sprawdź, czy masz zainstalowane narzędzie do kompilacji CMake.

Aktualizowanie konfiguracji kompilacji

(1) Aby uzyskać dostęp do interfejsu Play Services API dla LiteRT, dodaj do kodu projektu aplikacji te zależności:

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

Pamiętaj, że chociaż nazwa pakietu kończy się na -java, pakiet ten zawiera też interfejsy C i C++.

(2) Następnie włącz funkcję Prefab, aby uzyskać dostęp do interfejsu C API ze skryptu CMake, aktualizując blok android w pliku build.gradle modułu:

buildFeatures {
  prefab = true
}

(3) [Tylko interfejs C++] Jeśli używasz interfejsu C++, skopiuj plik tflite-java-extract-cpp-sdk.gradle do katalogu app w projekcie i dodaj ten kod na początku skryptu Gradle aplikacji (np. app/build.gradle):

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

Zawiera kod Gradle, który automatycznie rozpakowuje pakiet SDK C++ z pliku AAR dla play-services-tflite-java.

(4) [Tylko interfejs C++] Jeśli używasz interfejsu C++, znajdź katalog, który zawiera plik konfiguracyjny CMake aplikacji (zwykle CMakeLists.txt); ten katalog to zwykle katalog app/src/main/cpp. Następnie skopiuj plik Findtflite_cc_api.cmake do projektu, do nowego podkatalogu Modules w tym katalogu. Zawiera kod, który znajduje rozpakowany przez skrypt Gradle pakiet SDK C++ z poprzedniego kroku.

(5) Na koniec musisz dodać pakiet tensorflowlite_jni_gms_client, a w przypadku interfejsu C++ API także pakiet tflite_cc_api, które są importowane z pliku AAR, jako zależności w skrypcie 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)
      

Inicjowanie środowiska wykonawczego LiteRT

Przed wywołaniem interfejsu LiteRT C lub C++ API musisz zainicjować TfLiteNativeśrodowisko wykonawcze w kodzie Java lub Kotlin.

Java

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

Za pomocą interfejsu Task API w usługach Google Play TfLiteNative.initializeasynchronicznie wczytuje środowisko wykonawcze LiteRT z usług Google Play do procesu środowiska wykonawczego aplikacji. Użyj addOnSuccessListener(), aby upewnić się, że zadanie TfLite.initialize() zostało wykonane przed uruchomieniem kodu, który uzyskuje dostęp do interfejsów LiteRT API. Po pomyślnym zakończeniu zadania możesz wywołać wszystkie dostępne interfejsy LiteRT Native API.

Implementacja kodu natywnego

Aby używać LiteRT w Usługach Google Play z kodem C/C++, możesz wykonać jedną z tych czynności (lub obie):

  • deklarować nowe funkcje JNI, aby wywoływać funkcje C lub C++ z kodu Java;
  • wywoływać interfejs LiteRT Native API z dotychczasowego kodu w języku C lub C++;

Funkcje JNI

Możesz zadeklarować nowe funkcje JNI, aby środowisko wykonawcze LiteRT zadeklarowane w kodzie C/C++ było dostępne dla kodu Java/Kotlin w ten sposób:

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

Dopasowywanie do tych funkcji loadModelrunInference w językach C lub 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

Następnie możesz wywoływać funkcje C/C++ z kodu 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 w kodzie natywnym

Dołącz odpowiedni plik nagłówkowy interfejsu API, aby uwzględnić interfejs LiteRT z usługami Google Play:

C

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

C++

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

Możesz wtedy użyć zwykłego interfejsu LiteRT C lub C++ API:

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

Obsługiwane interfejsy API

C

Pliki nagłówkowe interfejsu C LiteRT z usługami Google Play udostępniają ten sam interfejs API co zwykły interfejs C LiteRT, z wyjątkiem funkcji, które zostały wycofane lub są eksperymentalne. Obecnie dostępne są funkcje i typy z tych nagłówków:

Interfejsy API TensorFlow Lite do wczytywania i wykonywania modeli:

tensorflow/lite/c/c_api.h
tensorflow/lite/c/c_api_types.h
      

Interfejsy API rozszerzeń TensorFlow Lite do definiowania niestandardowych operacji i delegatów (np. na potrzeby akceleracji sprzętowej):

tensorflow/lite/c/c_api_opaque.h
tensorflow/lite/c/common.h
tensorflow/lite/c/builtin_op_data.h
tensorflow/lite/builtin_ops.h
      

Interfejsy API wtyczek do delegowania zadań umożliwiające korzystanie z dotychczasowych przedstawicieli:

tensorflow/lite/acceleration/configuration/c/gpu_plugin.h
tensorflow/lite/acceleration/configuration/c/xnnpack_plugin.h
      

Pamiętaj, że funkcje z nagłówka c_api_experimental.h nie są obsługiwane.

Aby korzystać z funkcji specyficznych dla LiteRT w Usługach Google Play, dodaj ten nagłówek:

tensorflow/lite/abi/tflite.h
.

C++

Pliki nagłówkowe interfejsu C++ API LiteRT z usługami Google Play udostępniają ten sam interfejs API co zwykły interfejs C++ API LiteRT, z wyjątkiem funkcji, które zostały wycofane lub są eksperymentalne, oraz z kilkoma drobnymi wyjątkami, o których mowa w dalszej części tej sekcji. Dostępne są funkcje z tych nagłówków:

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
      

W przypadku tensorflow/lite/interpreter.h obsługiwany interfejs API z Usługami Play wyklucza kilka elementów tflite::Interpreter, dla których LiteRT nie oferuje stabilnego interfejsu ABI:

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)