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

LiteRT w czasie działania usług Google Play umożliwia uruchamianie modeli uczenia maszynowego bez stałego wiązania bibliotek LiteRT w aplikacji. W tym przewodniku znajdziesz instrukcje korzystania z interfejsów API C lub C++ dla usług Google Play.

Zanim zaczniesz korzystać z LiteRT w usługach Google Play w interfejsie C API lub C++, upewnij się, że masz zainstalowane narzędzie do kompilacji CMake.

Aktualizowanie konfiguracji kompilacji

(1) Aby uzyskać dostęp do interfejsu Play Services API w 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, zawiera on też interfejsy API C i C++.

(2) Następnie włącz funkcję Prefab, aby uzyskać dostęp do interfejsu C API ze skryptu CMake. W tym celu zaktualizuj 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 swojej aplikacji i dodaj do początku skryptu Gradle aplikacji (np. app/build.gradle) ten fragment kodu:

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

Zawiera on 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 zawierający plik konfiguracji CMake aplikacji (zwykle CMakeLists.txt). Zazwyczaj jest to katalog app/src/main/cpp. Następnie skopiuj plik Findtflite_cc_api.cmake do swojego projektu w nowym podkatalogu Modules w tym katalogu. Zawiera on kod, który znajduje pakiet SDK C++, rozpakowany przez skrypt Gradle w poprzednim kroku.

(5) Na koniec musisz dodać pakiet tensorflowlite_jni_gms_client, a w przypadku interfejsu API C++ także pakiet tflite_cc_api. Oba 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 TFLite in Play services
# (rather than regular TFLite 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 TFLite in Play services C API (tensorflowlite_jni_gms_client) dependency.

find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG)

# Set up TFLite 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 TFLite in Play services
# (rather than regular TFLite 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 API LiteRT C lub C++ musisz zainicjować środowisko wykonawcze TfLiteNative w kodzie Java lub Kotlin.

Java

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

Korzystając z interfejsu API zadań usług Google Play, TfLiteNative.initialize asewerycznie wczytuje środowisko wykonawcze TFLite z usług Google Play do procesu wykonawczego aplikacji. Użyj addOnSuccessListener(), aby mieć pewność, że zadanie TfLite.initialize() zostanie ukończone przed wykonaniem kodu, który uzyskuje dostęp do interfejsów API LiteRT. Po zakończeniu zadania możesz wywołać wszystkie dostępne interfejsy TFLite 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):

  • zadeklarować nowe funkcje JNI, aby wywoływać funkcje C lub C++ z kodu Java;
  • wywołać interfejs LiteRT Native API z dotychczasowego kodu C lub C++.

Funkcje JNI

Aby udostępnić środowisko wykonawcze LiteRT zadeklarowane w kodzie C/C++ Twojemu kodowi Java/Kotlin, możesz zadeklarować nowe funkcje JNI 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.
}
        

Dopasowuje do tych funkcji C lub C++: loadModelrunInference:

#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 lub 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łówka interfejsu API, aby uwzględnić interfejs API usług Google Play w LiteRT:

C

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

C++

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

Następnie możesz użyć zwykłego interfejsu LiteRT C lub C++:

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

Nagłówki interfejsu LiteRT z usługami Google Play w języku C zapewniają ten sam interfejs API co zwykły interfejs LiteRT C API, z wyjątkiem funkcji wycofanych lub eksperymentalnych. 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. do 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 wtyczki przedstawiciela do korzystania z istniejących 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.

Funkcji przeznaczonych do LiteRT z Usługami Google Play możesz używać, dodając ten nagłówek:

tensorflow/lite/abi/tflite.h
.

C++

Nagłówki interfejsu API C++ LiteRT z usługami Google Play udostępniają ten sam interfejs API co zwykły interfejs API C++ LiteRT, z wyjątkiem funkcji wycofanych lub eksperymentalnych oraz kilku drobnych wyjątków wymienionych w tej sekcji. Dostępne są te 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ługiwane interfejsy API w usługach Google Play nie obejmują kilku 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)