Ś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 loadModel i runInference 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
tensorflow/lite/c/c_api.h tensorflow/lite/c/c_api_types.h
Interfejsy API rozszerzeń 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
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)