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++: loadModel
i 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
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
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 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)