LiteRT בסביבת זמן הריצה של Google Play Services מאפשר להריץ מודלים של למידת מכונה (ML) בלי לארוז באופן סטטי ספריות LiteRT באפליקציה. במדריך הזה מוסבר איך להשתמש בממשקי ה-API של C או C++ ל-Google Play Services.
לפני שמשתמשים ב-LiteRT ב-Google Play Services C API או ב-C++ API, צריך לוודא שכלי ה-build של CMake מותקן.
עדכון הגדרת ה-build
(1) מוסיפים את התלויות הבאות לקוד של פרויקט האפליקציה כדי לגשת ל-Play Services API בשביל LiteRT:
implementation "com.google.android.gms:play-services-tflite-java:16.4.0"
שימו לב: למרות ששם החבילה מסתיים ב--java, החבילה הזו מכילה גם את ממשקי ה-API של C ו-C++.
(2) לאחר מכן, מפעילים את התכונה Prefab כדי לגשת אל C API מסקריפט CMake על ידי עדכון הבלוק android בקובץ build.gradle של המודול:
buildFeatures {
prefab = true
}
(3) [C++ API בלבד] אם אתם משתמשים ב-C++ API, מעתיקים את tflite-java-extract-cpp-sdk.gradle לפרויקט, בספרייה app, ומוסיפים את השורה הבאה לתחילת סקריפט ה-gradle של האפליקציה (למשל app/build.gradle):
apply from: 'tflite-java-extract-cpp-sdk.gradle'
הקוד הזה מכיל קוד Gradle שפורק אוטומטית את C++ SDK מקובץ ה-AAR של play-services-tflite-java.
(4) [C++ API only] אם אתם משתמשים ב-C++ API, מחפשים את הספרייה שמכילה את קובץ התצורה של CMake של האפליקציה (בדרך כלל CMakeLists.txt). הספרייה הזו היא בדרך כלל הספרייה app/src/main/cpp. אחר כך מעתיקים את Findtflite_cc_api.cmake לפרויקט, לספריית משנה חדשה Modules של אותה ספרייה.
הקוד הזה מוצא את C++ SDK שחולץ על ידי סקריפט Gradle בשלב הקודם.
(5) לבסוף, צריך להוסיף את החבילה tensorflowlite_jni_gms_client, ואם משתמשים ב-C++ API, גם את החבילה tflite_cc_api. שתיהן מיובאות מ-AAR כתלות בסקריפט 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)
אתחול של סביבת זמן הריצה LiteRT
לפני שמבצעים קריאה ל-API של LiteRT C או C++, צריך להפעיל את זמן הריצה TfLiteNative בקוד Java או Kotlin.
Java
Task tfLiteInitializeTask = TfLiteNative.initialize(context);
Kotlin
val tfLiteInitializeTask: Task= TfLiteNative.initialize(context)
באמצעות Google Play services Task API, TfLiteNative.initialize
זמן הריצה של LiteRT נטען באופן אסינכרוני מ-Google Play Services אל תהליך זמן הריצה של האפליקציה. משתמשים ב-addOnSuccessListener() כדי לוודא שהמשימה TfLite.initialize() הושלמה לפני שמריצים קוד שנותן גישה ל-APIs של LiteRT. אחרי שהמשימה תושלם בהצלחה, תוכלו להפעיל את כל ממשקי ה-API הזמינים של LiteRT Native.
הטמעה של קוד מקורי
כדי להשתמש ב-LiteRT ב-Google Play Services עם קוד C/C++, אפשר לבצע אחת (או את שתי) הפעולות הבאות:
- להצהיר על פונקציות JNI חדשות כדי להפעיל פונקציות C או C++ מקוד Java
- להתקשר אל LiteRT Native API מהקוד הקיים של C או C++.
פונקציות JNI
אפשר להצהיר על פונקציות JNI חדשות כדי להפוך את זמן הריצה של LiteRT שהוצהר בקוד C/C++ לנגיש לקוד Java/Kotlin באופן הבא:
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. }
התאמה לפונקציות הבאות של C או C++: loadModel ו-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
לאחר מכן אפשר להפעיל את הפונקציות של C/C++ מהקוד של 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 בקוד Native
כדי לכלול את LiteRT עם Google Play Services API, צריך לכלול את קובץ הכותרת המתאים של ה-API:
C
#include "tensorflow/lite/c/c_api.h"
C++
#include "tensorflow/lite/interpreter.h" #include "tensorflow/lite/model_builder.h"
אחר כך אפשר להשתמש ב-LiteRT C או ב-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);
ממשקי API נתמכים
C
קובצי הכותרת של LiteRT עם Google Play Services C API מספקים את אותו API כמו LiteRT C API הרגיל, למעט תכונות שהוצאו משימוש או שהן ניסיוניות. בשלב הזה, הפונקציות והסוגים מהכותרות הבאות זמינים.
ממשקי TensorFlow Lite API
tensorflow/lite/c/c_api.h tensorflow/lite/c/c_api_types.h
ממשקי API של תוספים ל-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
ממשקי API של תוספים להענקת הרשאות לשימוש בבעלי גישה קיימים:
tensorflow/lite/acceleration/configuration/c/gpu_plugin.h tensorflow/lite/acceleration/configuration/c/xnnpack_plugin.h
חשוב לזכור שאין תמיכה בפונקציות מהכותרת c_api_experimental.h.
כדי להשתמש בפונקציות שספציפיות ל-LiteRT עם Google Play Services, צריך לכלול את הכותרת הבאה:
tensorflow/lite/abi/tflite.h
C++
קבצי הכותרת של LiteRT עם Google Play Services C++ API מספקים את אותו API כמו LiteRT C++ API הרגיל, למעט תכונות שהוצאו משימוש או שהן ניסיוניות, ועם כמה חריגים קלים שמפורטים בהמשך הקטע הזה. הפונקציונליות מהכותרות הבאות זמינה:
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
ב-tensorflow/lite/interpreter.h, ה-API הנתמך עם שירותי Play לא כולל כמה רכיבים של tflite::Interpreter ש-LiteRT לא מציע להם 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)