TensorFlow Lite 委派

簡介

委派可運用裝置上的加速器 (例如 GPU 和 數位訊號處理器 (DSP)),為 TensorFlow Lite 模型啟用硬體加速。

根據預設,TensorFlow Lite 會使用針對 ARM Neon 指令集最佳化的 CPU 核心。然而,CPU 是多用途處理器,不一定針對機器學習模型中常見的大量算術運算 (例如,卷積層和密集層中涉及的矩陣數學運算) 進行最佳化。

另一方面,大多數現代手機都包含更擅長處理這些繁重運算的晶片。將這些晶片用於神經網路運算,在延遲和能源效率方面帶來巨大的優勢。例如,GPU 可以提供高達 5 倍的延遲加速,而 Qualcomm® Hexagon DSP 在我們的實驗中已顯示可減少高達 75% 的功耗。

每個加速器都有相關聯的 API,可啟用自訂運算,例如行動 GPU 的 OpenCLOpenGL ES,以及 DSP 的 Qualcomm® Hexagon SDK。一般來說,您必須編寫大量自訂程式碼才能透過這些介面執行神經網路。當您考慮到每個加速器都有其優缺點,且無法執行神經網路中的每個運算時,情況會變得更加複雜。TensorFlow Lite 的委派 API 透過充當 TFLite 執行階段與這些較低層級 API 之間的橋樑來解決此問題。

runtime with delegates

選擇委派

TensorFlow Lite 支援多個委派,每個委派都針對特定平台和特定類型的模型進行最佳化。通常,根據兩個主要條件,將有多個委派適用於您的使用案例:您目標鎖定的平台 (Android 還是 iOS?) 以及您嘗試加速的模型類型 (浮點或量化?)。

依平台劃分的委派

跨平台 (Android 和 iOS)

  • GPU 委派 - GPU 委派可用於 Android 和 iOS。它經過最佳化,可在 GPU 可用的情況下執行 32 位元和 16 位元浮點模型。它也支援 8 位元量化模型,並提供與浮點版本相當的 GPU 效能。如需 GPU 委派的詳細資訊,請參閱GPU 上的 TensorFlow Lite。如需在 Android 和 iOS 上使用 GPU 委派的逐步教學課程,請參閱TensorFlow Lite GPU 委派教學課程

Android

  • 適用於較新 Android 裝置的 NNAPI 委派 - NNAPI 委派可用於加速具有 GPU、DSP 和/或 NPU 可用的 Android 裝置上的模型。它適用於 Android 8.1 (API 27+) 或更高版本。如需 NNAPI 委派的總覽、逐步說明和最佳做法,請參閱TensorFlow Lite NNAPI 委派
  • 適用於較舊 Android 裝置的 Hexagon 委派 - Hexagon 委派可用於加速具有 Qualcomm Hexagon DSP 的 Android 裝置上的模型。它可用於執行不支援 NNAPI 的較舊 Android 版本的裝置。如需更多詳細資訊,請參閱TensorFlow Lite Hexagon 委派

iOS

  • 適用於較新 iPhone 和 iPad 的 Core ML 委派 - 對於具有 Neural Engine 的較新 iPhone 和 iPad,您可以使用 Core ML 委派來加速 32 位元或 16 位元浮點模型的推論。Neural Engine 適用於配備 A12 SoC 或更高版本的 Apple 行動裝置。如需 Core ML 委派的總覽和逐步說明,請參閱TensorFlow Lite Core ML 委派

依模型類型劃分的委派

每個加速器都設計為考慮到特定的資料位元寬度。如果您將浮點模型提供給僅支援 8 位元量化運算的委派 (例如 Hexagon 委派),它將拒絕其所有運算,並且模型將完全在 CPU 上執行。為了避免這種意外情況,下表概述了基於模型類型的委派支援

模型類型 GPU NNAPI Hexagon CoreML
浮點 (32 位元)
後訓練 float16 量化
後訓練動態範圍量化
後訓練整數量化
量化感知訓練

驗證效能

本節中的資訊可作為縮小可改善應用程式的委派範圍的粗略指南。但是,重要的是要注意,每個委派都有一組預先定義的其支援的運算,並且可能會根據模型和裝置而表現不同;例如,NNAPI 委派可能會選擇在 Pixel 手機上使用 Google 的 Edge-TPU,同時在另一部裝置上使用 DSP。因此,通常建議您執行一些基準測試,以評估委派對您的需求有多大用處。這也有助於證明與將委派附加到 TensorFlow Lite 執行階段相關聯的二進位檔大小增加是合理的。

TensorFlow Lite 具有廣泛的效能和準確度評估工具,可以讓開發人員對在其應用程式中使用委派充滿信心。這些工具將在下一節中討論。

評估工具

延遲和記憶體佔用量

TensorFlow Lite 的 基準測試工具 可以與合適的參數一起使用,以估計模型效能,包括平均推論延遲、初始化管理費用、記憶體佔用量等。此工具支援多個標誌,以找出模型的最佳委派組態。例如,可以使用 --use_gpu 指定 --gpu_backend=gl,以測量使用 OpenGL 的 GPU 執行。支援的委派參數的完整清單在 詳細文件中定義。

以下是透過 adb 使用 GPU 執行量化模型的範例

adb shell /data/local/tmp/benchmark_model \
  --graph=/data/local/tmp/mobilenet_v1_224_quant.tflite \
  --use_gpu=true

您可以從 這裡 下載此工具的 Android、64 位元 ARM 架構的預先建置版本 (更多詳細資訊)。

準確度和正確性

委派通常以與 CPU 對應項不同的精確度執行運算。因此,使用委派進行硬體加速會產生 (通常很小的) 準確度權衡。請注意,這並非總是如此;例如,由於 GPU 使用浮點精度來執行量化模型,因此可能會略微提高精度 (例如,ILSVRC 影像分類中 Top-5 準確度提高 <1%)。

TensorFlow Lite 有兩種類型的工具來衡量委派對於給定模型的行為準確程度:基於任務與任務無關。本節中描述的所有工具都支援前一節中基準測試工具使用的 進階委派參數。請注意,以下小節重點介紹委派評估 (委派的效能是否與 CPU 相同?) 而不是模型評估 (模型本身是否適用於任務?)。

基於任務的評估

TensorFlow Lite 具有用於評估兩個基於影像的任務的正確性的工具

這些工具 (Android,64 位元 ARM 架構) 的預先建置二進位檔以及文件可以在這裡找到

以下範例示範使用 NNAPI 在 Pixel 4 上利用 Google 的 Edge-TPU 進行的 影像分類評估

adb shell /data/local/tmp/run_eval \
  --model_file=/data/local/tmp/mobilenet_quant_v1_224.tflite \
  --ground_truth_images_path=/data/local/tmp/ilsvrc_images \
  --ground_truth_labels=/data/local/tmp/ilsvrc_validation_labels.txt \
  --model_output_labels=/data/local/tmp/model_output_labels.txt \
  --output_file_path=/data/local/tmp/accuracy_output.txt \
  --num_images=0 # Run on all images. \
  --use_nnapi=true \
  --nnapi_accelerator_name=google-edgetpu

預期輸出是從 1 到 10 的前 K 名指標清單

Top-1 Accuracy: 0.733333
Top-2 Accuracy: 0.826667
Top-3 Accuracy: 0.856667
Top-4 Accuracy: 0.87
Top-5 Accuracy: 0.89
Top-6 Accuracy: 0.903333
Top-7 Accuracy: 0.906667
Top-8 Accuracy: 0.913333
Top-9 Accuracy: 0.92
Top-10 Accuracy: 0.923333

與任務無關的評估

對於沒有已建立的裝置上評估工具的任務,或者如果您正在試驗自訂模型,TensorFlow Lite 具有 推論差異工具。(Android,64 位元 ARM 二進位架構二進位檔 在此)

推論差異比較兩種設定中的 TensorFlow Lite 執行 (在延遲和輸出值偏差方面)

  • 單執行緒 CPU 推論
  • 使用者定義的推論 - 由 這些參數定義

為此,該工具產生隨機高斯資料,並將其傳遞到兩個 TFLite Interpreter - 一個執行單執行緒 CPU 核心,另一個由使用者的引數參數化。

它測量兩者的延遲,以及每個 Interpreter 的輸出張量之間在每個元素基礎上的絕對差異。

對於具有單一輸出張量的模型,輸出可能如下所示

Num evaluation runs: 50
Reference run latency: avg=84364.2(us), std_dev=12525(us)
Test run latency: avg=7281.64(us), std_dev=2089(us)
OutputDiff[0]: avg_error=1.96277e-05, std_dev=6.95767e-06

這表示對於索引為 0 的輸出張量,CPU 輸出的元素與委派輸出平均相差 1.96e-05

請注意,解釋這些數字需要更深入地了解模型,以及每個輸出張量代表的意義。如果它是確定某種分數或嵌入的簡單迴歸,則差異應該很小 (否則委派會出現錯誤)。但是,像 SSD 模型中的「偵測類別」這樣的輸出有點難以解釋。例如,它可能會使用此工具顯示差異,但這可能並不表示委派真的有問題:考慮兩個 (假的) 類別:「電視 (ID: 10)」、「螢幕 (ID: 20)」 - 如果委派稍微偏離黃金真理,並顯示螢幕而不是電視,則此張量的輸出差異可能高達 20-10 = 10。