TensorFlow Lite Hexagon 委派

本文件說明如何在您的應用程式中使用 Java 和/或 C API 來使用 TensorFlow Lite Hexagon 委派。此委派利用 Qualcomm Hexagon 函式庫在 DSP 上執行量化核心。請注意,此委派旨在輔助 NNAPI 功能,特別是針對 NNAPI DSP 加速無法使用的裝置(例如,較舊的裝置或尚未具備 DSP NNAPI 驅動程式的裝置)。

支援的裝置

目前支援以下 Hexagon 架構,包括但不限於

  • Hexagon 680
    • SoC 範例:Snapdragon 821、820、660
  • Hexagon 682
    • SoC 範例:Snapdragon 835
  • Hexagon 685
    • SoC 範例:Snapdragon 845、Snapdragon 710、QCS410、QCS610、QCS605、QCS603
  • Hexagon 690
    • SoC 範例:Snapdragon 855、RB5

支援的模型

Hexagon 委派支援所有符合我們 8 位元對稱量化規格的模型,包括使用事後訓練整數量化產生的模型。也支援使用舊版量化感知訓練路徑訓練的 UInt8 模型,例如,我們「託管模型」頁面上的這些量化版本

Hexagon 委派 Java API

public class HexagonDelegate implements Delegate, Closeable {

  /*
   * Creates a new HexagonDelegate object given the current 'context'.
   * Throws UnsupportedOperationException if Hexagon DSP delegation is not
   * available on this device.
   */
  public HexagonDelegate(Context context) throws UnsupportedOperationException


  /**
   * Frees TFLite resources in C runtime.
   *
   * User is expected to call this method explicitly.
   */
  @Override
  public void close();
}

使用範例

步驟 1. 編輯 app/build.gradle 以使用每晚建置的 Hexagon 委派 AAR

dependencies {
  ...
  implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly-SNAPSHOT'
  implementation 'org.tensorflow:tensorflow-lite-hexagon:0.0.0-nightly-SNAPSHOT'
}

步驟 2. 將 Hexagon 函式庫新增至您的 Android 應用程式

  • 下載並執行 hexagon_nn_skel.run。它應該會提供 3 個不同的共用函式庫「libhexagon_nn_skel.so」、「libhexagon_nn_skel_v65.so」、「libhexagon_nn_skel_v66.so」

步驟 3. 建立委派並初始化 TensorFlow Lite Interpreter

import org.tensorflow.lite.HexagonDelegate;

// Create the Delegate instance.
try {
  hexagonDelegate = new HexagonDelegate(activity);
  tfliteOptions.addDelegate(hexagonDelegate);
} catch (UnsupportedOperationException e) {
  // Hexagon delegate is not supported on this device.
}

tfliteInterpreter = new Interpreter(tfliteModel, tfliteOptions);

// Dispose after finished with inference.
tfliteInterpreter.close();
if (hexagonDelegate != null) {
  hexagonDelegate.close();
}

Hexagon 委派 C API

struct TfLiteHexagonDelegateOptions {
  // This corresponds to the debug level in the Hexagon SDK. 0 (default)
  // means no debug.
  int debug_level;
  // This corresponds to powersave_level in the Hexagon SDK.
  // where 0 (default) means high performance which means more power
  // consumption.
  int powersave_level;
  // If set to true, performance information about the graph will be dumped
  // to Standard output, this includes cpu cycles.
  // WARNING: Experimental and subject to change anytime.
  bool print_graph_profile;
  // If set to true, graph structure will be dumped to Standard output.
  // This is usually beneficial to see what actual nodes executed on
  // the DSP. Combining with 'debug_level' more information will be printed.
  // WARNING: Experimental and subject to change anytime.
  bool print_graph_debug;
};

// Return a delegate that uses Hexagon SDK for ops execution.
// Must outlive the interpreter.
TfLiteDelegate*
TfLiteHexagonDelegateCreate(const TfLiteHexagonDelegateOptions* options);

// Do any needed cleanup and delete 'delegate'.
void TfLiteHexagonDelegateDelete(TfLiteDelegate* delegate);

// Initializes the DSP connection.
// This should be called before doing any usage of the delegate.
// "lib_directory_path": Path to the directory which holds the
// shared libraries for the Hexagon NN libraries on the device.
void TfLiteHexagonInitWithPath(const char* lib_directory_path);

// Same as above method but doesn't accept the path params.
// Assumes the environment setup is already done. Only initialize Hexagon.
Void TfLiteHexagonInit();

// Clean up and switch off the DSP connection.
// This should be called after all processing is done and delegate is deleted.
Void TfLiteHexagonTearDown();

使用範例

步驟 1. 編輯 app/build.gradle 以使用每晚建置的 Hexagon 委派 AAR

dependencies {
  ...
  implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly-SNAPSHOT'
  implementation 'org.tensorflow:tensorflow-lite-hexagon:0.0.0-nightly-SNAPSHOT'
}

步驟 2. 將 Hexagon 函式庫新增至您的 Android 應用程式

  • 下載並執行 hexagon_nn_skel.run。它應該會提供 3 個不同的共用函式庫「libhexagon_nn_skel.so」、「libhexagon_nn_skel_v65.so」、「libhexagon_nn_skel_v66.so」

步驟 3. 包含 C 標頭檔

  • 標頭檔 "hexagon_delegate.h" 可以從 GitHub 下載,或從 Hexagon 委派 AAR 解壓縮。

步驟 4. 建立委派並初始化 TensorFlow Lite Interpreter

  • 在您的程式碼中,請確保已載入原生 Hexagon 函式庫。這可以透過呼叫 System.loadLibrary("tensorflowlite_hexagon_jni"); 來完成
    在您的 Activity 或 Java 進入點中。

  • 建立委派範例

#include "tensorflow/lite/delegates/hexagon/hexagon_delegate.h"

// Assuming shared libraries are under "/data/local/tmp/"
// If files are packaged with native lib in android App then it
// will typically be equivalent to the path provided by
// "getContext().getApplicationInfo().nativeLibraryDir"
const char[] library_directory_path = "/data/local/tmp/";
TfLiteHexagonInitWithPath(library_directory_path);  // Needed once at startup.
::tflite::TfLiteHexagonDelegateOptions params = {0};
// 'delegate_ptr' Need to outlive the interpreter. For example,
// If your use case requires resizing the input or anything that can trigger
// re-applying delegates then 'delegate_ptr' must outlive the interpreter.
auto* delegate_ptr = ::tflite::TfLiteHexagonDelegateCreate(&params);
Interpreter::TfLiteDelegatePtr delegate(delegate_ptr,
  [](TfLiteDelegate* delegate) {
    ::tflite::TfLiteHexagonDelegateDelete(delegate);
  });
interpreter->ModifyGraphWithDelegate(delegate.get());
// After usage of delegate.
TfLiteHexagonTearDown();  // Needed once at end of app/DSP usage.

將共用函式庫新增至您的應用程式

  • 建立資料夾「app/src/main/jniLibs」,並為每個目標架構建立目錄。例如:
    • ARM 64 位元:app/src/main/jniLibs/arm64-v8a
    • ARM 32 位元:app/src/main/jniLibs/armeabi-v7a
  • 將您的 .so 檔案放入符合架構的目錄中。

意見回饋

如有問題,請建立 GitHub issue,並提供所有必要的重現詳細資訊,包括使用的手機型號和主機板 (adb shell getprop ro.product.deviceadb shell getprop ro.board.platform)。

常見問題

  • 委派支援哪些運算元?
  • 當我啟用委派時,如何判斷模型是否正在使用 DSP?
    • 當您啟用委派時,會印出兩則記錄訊息 - 一則指出是否已建立委派,另一則指出有多少節點正在使用委派執行。
      已為 Hexagon 建立 TensorFlow Lite 委派。
      Hexagon 委派:在 Y 個節點中委派了 X 個節點。
  • 我是否需要模型中的所有運算元都受到支援才能執行委派?
    • 不用,模型會根據支援的運算元分割成子圖。任何不受支援的運算元都會在 CPU 上執行。
  • 如何從原始碼建置 Hexagon 委派 AAR?
    • 使用 bazel build -c opt --config=android_arm64 tensorflow/lite/delegates/hexagon/java:tensorflow-lite-hexagon
  • 即使我的 Android 裝置具有支援的 SoC,為何 Hexagon 委派仍無法初始化?
    • 驗證您的裝置是否確實具有支援的 SoC。執行 adb shell cat /proc/cpuinfo | grep Hardware,查看是否傳回類似「Hardware : Qualcomm Technologies, Inc MSMXXXX」的內容。
    • 有些手機製造商針對相同的電話型號使用不同的 SoC。因此,Hexagon 委派可能僅適用於相同電話型號的某些裝置,而非全部裝置。
    • 有些手機製造商有意限制非系統 Android 應用程式使用 Hexagon DSP,導致 Hexagon 委派無法運作。
  • 我的手機已鎖定 DSP 存取權。我已取得手機 root 權限,但仍然無法執行委派,該怎麼辦?
    • 請務必執行 adb shell setenforce 0 以停用 SELinux 強制執行