נציג TensorFlow Lite Hexagon, Delegate TensorFlow Lite Hexagon

מסמך זה מסביר כיצד להשתמש ב- TensorFlow Lite Hexagon Delegate ביישום שלך באמצעות Java ו/או C API. הנציג ממנף את ספריית Qualcomm Hexagon כדי לבצע גרעינים כמותיים ב-DSP. שים לב שהנציג נועד להשלים את הפונקציונליות של NNAPI, במיוחד עבור מכשירים שבהם האצת NNAPI DSP אינה זמינה (למשל, במכשירים ישנים יותר, או מכשירים שעדיין אין להם מנהל התקן DSP NNAPI).

מכשירים נתמכים:

נכון לעכשיו, ארכיטקטורת המשושים הבאה נתמכת, כולל אך לא מוגבל ל:

  • משושה 680
    • דוגמאות SoC: Snapdragon 821, 820, 660
  • משושה 682
    • דוגמאות SoC: Snapdragon 835
  • משושה 685
    • דוגמאות SoC: Snapdragon 845, Snapdragon 710, QCS410, QCS610, QCS605, QCS603
  • משושה 690
    • דוגמאות SoC: Snapdragon 855, RB5

דגמים נתמכים:

הנציג של Hexagon תומך בכל הדגמים התואמים למפרט הקוונטיזציה הסימטרית של 8 סיביות שלנו, כולל אלו שנוצרו באמצעות קוונטיזציה של מספרים שלמים לאחר אימון . מודלים של UInt8 שהוכשרו עם נתיב ההכשרה המודע לכימות מדור קודם נתמכים גם הם, למשל, גרסאות כמותיות אלו בדף המודלים המתארחים שלנו.

ממשושה נציג 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 כדי להשתמש ב-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_nn_skel.run. זה צריך לספק 3 ספריות משותפות שונות "libhexagon_nn_skel.so", "libhexagon_nn_skel_v65.so", "libhexagon_nn_skel_v66.so"

שלב 3. צור נציג ואתחול מתורגמן TensorFlow Lite

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();
}

משושה נציג 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 כדי להשתמש ב-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_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 delegate AAR.

שלב 4. צור נציג ואתחול מתורגמן TensorFlow Lite

  • בקוד שלך, ודא שספריית ה-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-bit: app/src/main/jniLibs/arm64-v8a
    • ARM 32-bit: app/src/main/jniLibs/armeabi-v7a
  • שים את ה-.so שלך בספרייה התואמת לארכיטקטורה.

מָשׁוֹב

לבעיות, אנא צור בעיית GitHub עם כל פרטי ה-repro הנחוצים, כולל דגם הטלפון והלוח בשימוש ( adb shell getprop ro.product.device ו- adb shell getprop ro.board.platform ).

שאלות נפוצות

  • אילו פעולות נתמכות על ידי הנציג?
  • איך אני יכול לדעת שהדגם משתמש ב-DSP כשאני מפעיל את הנציג?
    • שתי הודעות יומן יודפסו כאשר תפעיל את הנציג - אחת כדי לציין אם הנציג נוצר ואחרת כדי לציין כמה צמתים פועלים באמצעות הנציג.
      Created TensorFlow Lite delegate for Hexagon.
      Hexagon delegate: X nodes delegated out of Y nodes.
  • האם אני צריך שכל האופציות במודל יהיו נתמכות כדי להפעיל את הנציג?
    • לא, המודל יחולק לתת-גרפים על סמך הפעולות הנתמכות. כל פעולות לא נתמכות יפעלו על המעבד.
  • איך אני יכול לבנות את ה-Hexagon delegate AAR ממקור?
    • השתמש bazel build -c opt --config=android_arm64 tensorflow/lite/delegates/hexagon/java:tensorflow-lite-hexagon .
  • מדוע נציג Hexagon לא מצליח לאתחל למרות שלמכשיר האנדרואיד שלי יש SoC נתמך?
    • ודא אם למכשיר שלך אכן יש SoC נתמך. הפעל את adb shell cat /proc/cpuinfo | grep Hardware וראה אם ​​זה מחזיר משהו כמו "Hardware : Qualcomm Technologies, Inc MSMXXXX".
    • יצרני טלפונים מסוימים משתמשים ב-SoCs שונים עבור אותו דגם טלפון. לכן, נציג משושה עשוי לעבוד רק בחלק מהמכשירים, אך לא בכל המכשירים מאותו דגם טלפון.
    • חלק מיצרני הטלפונים מגבילים בכוונה את השימוש ב- Hexagon DSP מאפליקציות אנדרואיד שאינן מערכתיות, מה שגורם לנציג Hexagon לא לעבוד.
  • הטלפון שלי ננעל גישת DSP. שורשתי את הטלפון ועדיין לא יכול להפעיל את הנציג, מה לעשות?
    • הקפד להשבית את אכיפת SELinux על ידי הפעלת adb shell setenforce 0