LiteRT ใน Google Play Services C และ C++ API

LiteRT ในรันไทม์ของบริการ Google Play ช่วยให้คุณเรียกใช้โมเดลแมชชีน เลิร์นนิง (ML) ได้โดยไม่ต้องรวมไลบรารี LiteRT แบบคงที่ไว้ใน แอปของคุณ คู่มือนี้จะให้วิธีการใช้ API ของ C หรือ C++ สำหรับบริการ Google Play

ก่อนที่จะใช้ LiteRT ใน C API หรือ C++ API ของบริการ Google Play โปรดตรวจสอบว่าคุณได้ติดตั้งเครื่องมือบิลด์ CMake แล้ว

อัปเดตการกำหนดค่าบิลด์

(1) เพิ่มทรัพยากร Dependency ต่อไปนี้ลงในโค้ดโปรเจ็กต์แอปเพื่อเข้าถึง API ของบริการ Google Play สำหรับ 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) [API ของ C++ เท่านั้น] หากคุณใช้ API ของ C++ ให้คัดลอก 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) [API ของ C++ เท่านั้น] หากคุณใช้ API ของ C++ ให้ค้นหาไดเรกทอรีที่มี ไฟล์การกำหนดค่า 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 ด้วย โดยทั้ง 2 แพ็กเกจจะนำเข้า จาก AAR เป็นทรัพยากร Dependency ในสคริปต์ 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

ก่อนเรียกใช้ LiteRT C หรือ C++ API คุณต้องเริ่มต้น TfLiteNativeรันไทม์ในโค้ด Java หรือ Kotlin

Java

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

เมื่อใช้ Task API ของบริการ Google Play TfLiteNative.initialize จะโหลดรันไทม์ LiteRT จากบริการ Google Play ลงในกระบวนการรันไทม์ของแอปพลิเคชัน แบบอะซิงโครนัส ใช้ addOnSuccessListener() เพื่อให้แน่ใจว่างาน TfLite.initialize() เสร็จสมบูรณ์ก่อนที่จะเรียกใช้โค้ดที่เข้าถึง LiteRT API เมื่อดำเนินการเสร็จสมบูรณ์แล้ว คุณจะเรียกใช้ API ดั้งเดิมของ LiteRT ที่พร้อมใช้งานทั้งหมดได้

การติดตั้งใช้งานโค้ดเนทีฟ

หากต้องการใช้ LiteRT ในบริการ Google Play กับโค้ด C/C++ คุณสามารถทำอย่างใดอย่างหนึ่ง (หรือทั้ง 2 อย่าง) ต่อไปนี้

  • ประกาศฟังก์ชัน 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.
}
        

การจับคู่ฟังก์ชัน loadModel และ runInference C หรือ 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

จากนั้นคุณจะเรียกใช้ฟังก์ชัน 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 ในโค้ดแบบเนทีฟ

รวมไฟล์ส่วนหัว API ที่เหมาะสมเพื่อรวม LiteRT กับ Google Play services 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

ส่วนหัวของ C API ของ LiteRT ที่มีบริการ Google Play จะมี API เดียวกันกับ LiteRT C API ปกติ ยกเว้นฟีเจอร์ที่เลิกใช้งานแล้วหรือเป็นเวอร์ชันทดลอง ขณะนี้ฟังก์ชันและประเภท จากส่วนหัวต่อไปนี้พร้อมใช้งานแล้ว

API ของ TensorFlow Lite สำหรับการโหลดและเรียกใช้โมเดล

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

API ส่วนขยาย TensorFlow Lite สำหรับการกำหนด Op และ Delegate ที่กำหนดเอง (เช่น สำหรับการเร่งด้วยฮาร์ดแวร์)

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 ได้โดย รวมส่วนหัวต่อไปนี้

tensorflow/lite/abi/tflite.h

C++

ส่วนหัวของ LiteRT ที่มี C++ API ของบริการ Google Play มี 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 services จะไม่รวมสมาชิกบางรายของ 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)