Google Play 서비스 C 및 C++ API의 LiteRT

Google Play 서비스 런타임의 LiteRT를 사용하면 앱에 LiteRT 라이브러리를 정적으로 번들로 묶지 않고도 머신러닝 (ML) 모델을 실행할 수 있습니다. 이 가이드에서는 Google Play 서비스의 C 또는 C++ API를 사용하는 방법을 설명합니다.

Google Play 서비스 C API 또는 C++ API에서 LiteRT를 사용하기 전에 CMake 빌드 도구가 설치되어 있는지 확인하세요.

빌드 구성 업데이트

(1) LiteRT용 Play 서비스 API에 액세스하려면 앱 프로젝트 코드에 다음 종속 항목을 추가합니다.

implementation "com.google.android.gms:play-services-tflite-java:16.4.0"

패키지 이름이 -java로 끝나지만 이 패키지에는 C 및 C++ API도 포함되어 있습니다.

(2) 그런 다음 모듈의 build.gradle 파일의 android 블록을 업데이트하여 CMake 스크립트에서 C API에 액세스할 수 있도록 Prefab 기능을 사용 설정합니다.

buildFeatures {
  prefab = true
}

(3) [C++ API만 해당] C++ API를 사용하는 경우 tflite-java-extract-cpp-sdk.gradleapp 디렉터리의 프로젝트에 복사하고 앱의 Gradle 스크립트 (예: app/build.gradle) 시작 부분에 다음을 추가합니다.

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

여기에는 play-services-tflite-java의 AAR 파일에서 C++ SDK를 자동으로 압축 해제하는 Gradle 코드가 포함되어 있습니다.

(4) [C++ API만 해당] C++ API를 사용하는 경우 앱의 CMake 구성 파일 (일반적으로 CMakeLists.txt)이 포함된 디렉터리를 찾습니다. 이 디렉터리는 일반적으로 app/src/main/cpp 디렉터리입니다. 그런 다음 Findtflite_cc_api.cmake를 해당 디렉터리의 새 Modules 하위 디렉터리에 프로젝트로 복사합니다. 여기에는 이전 단계에서 Gradle 스크립트로 압축 해제된 C++ SDK를 찾는 코드가 포함되어 있습니다.

(5) 마지막으로 패키지 tensorflowlite_jni_gms_client를 추가해야 하며 C++ API의 경우 AAR에서 가져온 패키지 tflite_cc_api도 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를 호출하기 전에 Java 또는 Kotlin 코드에서 TfLiteNative 런타임을 초기화해야 합니다.

자바

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

Google Play 서비스 작업 API를 사용하여 TfLiteNative.initialize Google Play 서비스에서 LiteRT 런타임을 애플리케이션의 런타임 프로세스에 비동기적으로 로드합니다. addOnSuccessListener()를 사용하여 LiteRT API에 액세스하는 코드를 실행하기 전에 TfLite.initialize() 작업이 완료되는지 확인합니다. 작업이 성공적으로 완료되면 사용 가능한 모든 LiteRT 네이티브 API를 호출할 수 있습니다.

네이티브 코드 구현

C/C++ 코드와 함께 Google Play 서비스에서 LiteRT를 사용하려면 다음 중 하나 또는 둘 다를 실행하면 됩니다.

  • Java 코드에서 C 또는 C++ 함수를 호출하는 새 JNI 함수를 선언합니다.
  • 기존 C 또는 C++ 코드에서 LiteRT 네이티브 API를 호출합니다.

JNI 함수

다음과 같이 새 JNI 함수를 선언하여 C/C++ 코드에 선언된 LiteRT 런타임을 Java/Kotlin 코드에서 액세스할 수 있도록 할 수 있습니다.

자바

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.
}
        

다음 loadModelrunInference 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

그런 다음 Java/Kotlin 코드에서 C/C++ 함수를 호출할 수 있습니다.

자바

tfLiteHandleTask.onSuccessTask(unused -> {
    TfLiteJni jni = new TfLiteJni();
    jni.loadModel(getAssets(), "add.bin");
    //...
});
    

Kotlin

tfLiteHandleTask.onSuccessTask {
    val jni = TfLiteJni()
    jni.loadModel(assets, "add.bin")
    // ...
}
      

네이티브 코드의 LiteRT

Google Play 서비스 API와 함께 LiteRT를 포함하려면 적절한 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

Google Play 서비스 C API 헤더가 포함된 LiteRT는 지원 중단되거나 실험적인 기능을 제외하고 일반 LiteRT C API와 동일한 API를 제공합니다. 현재 다음 헤더의 함수와 유형을 사용할 수 있습니다.

모델 로드 및 실행을 위한 TensorFlow Lite API:

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

맞춤 작업 및 대리자 (예: 하드웨어 가속)를 정의하기 위한 TensorFlow Lite 확장 프로그램 API:

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 헤더의 함수는 지원되지 않습니다.

다음 헤더를 포함하여 Google Play 서비스와 함께 LiteRT에 특화된 함수를 사용할 수 있습니다.

tensorflow/lite/abi/tflite.h
.

C++

Google Play 서비스 C++ API 헤더가 포함된 LiteRT는 지원 중단되거나 실험적인 기능을 제외하고 일반 LiteRT C++ API와 동일한 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의 경우 Play 서비스에서 지원되는 API에는 LiteRT가 안정적인 ABI를 제공하지 않는 tflite::Interpreter의 일부 멤버가 제외됩니다.

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)