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.gradle을 프로젝트의 app 디렉터리에 복사하고 앱의 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의 경우 tflite_cc_api 패키지를 추가해야 합니다. 이 두 패키지는 모두 AAR에서 가져와 CMake 스크립트에 종속 항목으로 추가해야 합니다.

C

``` find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG) # 앱에 번들로 제공된 일반 TFLite가 아닌 Play 서비스에서 TFLite를 사용할 수 있도록 C/C++ 컴파일러 플래그를 설정합니다. 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 # your target for other deps log) ```

C++

``` # Play 서비스 C API (tensorflowlite_jni_gms_client) 종속 항목에서 TFLite를 설정합니다. find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG) # Play 서비스 C++ API (tflite_cc_api) 종속 항목에서 TFLite를 설정합니다. 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) # 앱에 번들로 제공된 일반 TFLite가 아닌 Play 서비스에서 TFLite를 사용할 수 있도록 C/C++ 컴파일러 플래그를 설정합니다. 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 # your target for other deps log) ```

LiteRT 런타임 초기화

LiteRT Native API를 호출하기 전에 Java 또는 Kotlin 코드에서 TfLiteNative 런타임을 초기화해야 합니다.

자바

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

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

네이티브 코드 구현

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

  • Java 코드에서 C 또는 C++ 함수를 호출하는 새 JNI 함수 선언
  • 기존 C 또는 C++ 코드에서 LiteRT Native 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

```c++ TfLiteModel* model = TfLiteModelCreate(model_asset, model_asset_length); // ... TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate(); // ... TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options); ```

C++

```c++ // 모델을 로드합니다. auto model = tflite::FlatBufferModel::VerifyAndBuildFromBuffer( model_asset, model_asset_length); ... // 인터프리터를 초기화합니다. BuiltinOpResolver op_resolver; InterpreterBuilder interpreter_builder(*model, op_resolver); interpreter_builder(&interpreter); std::unique_ptr<Interpreter>` interpreter; interpreter_builder(&interpreter); ```

지원되는 API

C

Google Play 서비스 네이티브 API 헤더가 포함된 LiteRT는 지원 중단되었거나 실험적인 기능을 제외하고 일반 [LiteRT C API](../../api/tflite/c)와 동일한 API를 제공합니다. 현재 다음 헤더의 함수와 유형을 사용할 수 있습니다. 모델을 로드하고 실행하기 위한 TensorFlow Lite API : ```none tensorflow/lite/c/c_api.h tensorflow/lite/c/c_api_types.h ``` 맞춤 연산자 및 대리자를 정의하기 위한 TensorFlow Lite 확장 프로그램 API (예: 하드웨어 가속): ```none 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: ```none tensorflow/lite/acceleration/configuration/c/gpu_plugin.h tensorflow/lite/acceleration/configuration/c/xnnpack_plugin.h ``` `c_api_experimental.h` 헤더의 함수는 지원되지 않습니다. `tensorflow/lite/abi/tflite.h`를 포함하여 Google Play 서비스에서 LiteRT용 함수를 사용할 수 있습니다.

C++

Google Play 서비스 네이티브 API 헤더가 포함된 LiteRT는 지원 중단되었거나 실험적인 기능을 제외하고 일반 [LiteRT C++ API](../../api/tflite/cc)와 동일한 API를 제공하며, 이 섹션 뒷부분에 언급된 몇 가지 사소한 예외가 있습니다. 다음 헤더의 기능을 사용할 수 있습니다. ```none 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` 의 일부 멤버를 제외합니다. ```c++ 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) ```