AI開源十五:TensorFlow Lite GPU 代理

TensorFlow Lite 支持多種硬件加速器。本文檔描述瞭如何在 Android 和 iOS 設備上使用 TensorFlow Lite 的代理 APIs 來預覽實驗性的 GPU 後端功能。

GPU 是設計用來完成高吞吐量的大規模並行工作的。因此,它們非常適合用在包含大量運算符的神經網絡上,一些輸入張量可以容易的被劃分為更小的工作負載且可以同時執行,通常這會導致更低的延遲。在最佳情況下,用 GPU 在實時應用程序上做推理運算已經可以運行的足夠快,而這在以前是不可能的。

不同於 CPU 的是,GPU 可以計算 16 位浮點數或者 32 位浮點數並且 GPU 不需要量化來獲得最佳的系統性能。

使用 GPU 做推理運算還有一個好處就是它的能源效率。GPU 可以以非常高效和優化的方式下進行計算,所以 GPU 在完成和 CPU 一樣的任務時可以消耗更少的電力和產生更少的熱量。

演示應用程序教程

最簡單的嘗試實驗 GPU 代理的方法就是跟著下面的教程,教程將貫串我們整個使用 GPU 構建的分類演示應用程序。GPU 代碼現在只有二進制的形式,但是很快就會開源。一旦你理解了如何把我們的演示程序運行起來,你就可以在你自己的模型上嘗試。

Android(使用 Android Studio)

如果需要一個分步教程, 請觀看 適用於 Android 的實驗性 GPU 代理 的視頻。

注意:這需要 OpenGL ES 3.1或者更高版本

第一步 克隆 TensorFlow 的源代碼並在 Android Studio 中打開

<code>git clone https://github.com/tensorflow/tensorflow/<code>

第二步 編輯 app/build.gradle 文件來使用 nightly 版本的 GPU AAR

在現有的 dependencies 模塊已有的 tensorflow-lite 包的位置下添加 tensorflow-lite-gpu 包。

<code>dependencies {    ...    implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly'    implementation 'org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly'}/<code>

第三步. 編譯和運行

點擊 Run 按鈕來運行應用程序。當你運行應用程序的時候你會看到一個啟用 GPU 的按鈕。將應用程序從量化模式改為浮點模式後點擊 GPU 按鈕後,程序將在 GPU 上運行。


AI開源十五:TensorFlow Lite GPU 代理


iOS (使用 XCode)

如果需要一個分步教程, 請觀看 適用於 iOS 的實驗性 GPU 代理 的視頻。

注意:這需要 XCode 10.1 或者更高版本

第一步. 獲取演示應用程序的源碼並確保它已被編譯

遵照我們的 iOS 演示應用程序教程。這會告訴你沒有修改的iOS相機應用程序是如何在我們的手機上運行的。

第二部. 修改 Podfile 文件來使用 TensorFlow Lite GPU CocoaPod

我們構建了一個包含 GPU 代理的二進制 CocoaPod 文件。如果需要切換到工程並使用它,修改 tensorflow/tensorflow/lite/examples/ios/camera/Podfile 文件來使用 TensorFlowLiteGpuExperimental 的 pod 替代 TensorFlowLite。

<code>target 'YourProjectName'  # pod 'TensorFlowLite', '1.12.0'  pod 'TensorFlowLiteGpuExperimental'/<code>

第三步. 啟用 GPU 代理

為了確保代碼會使用 GPU 代理,你需要將 CameraExampleViewController.h 的 TFLITE_USE_GPU_DELEGATE 從 0 修改為 1 。

<code>#define TFLITE_USE_GPU_DELEGATE 1/<code>

第四步. 編譯和運行演示應用程序

如果你完成了上面的步驟,你應該已經可以運行這個應用程序了。

第五步. 發佈模式

你在第四步是在調試模式下運行的應用程序,為了獲得更好的性能表現,你應該使用適當的最佳 Metal 設置將應用程序改為發佈版本。特別需要注意的是,需要修改這些設置 Product > Scheme > Edit Scheme...,選擇 Run,在 Info 一欄,修改 Build Configuration,從 Debug 改為 Release,取消選擇 Debug executable。


AI開源十五:TensorFlow Lite GPU 代理


然後點擊 Options 欄然後將 GPU Frame Capture 修改成 Disabled,並將 Metal API Validation 修改成 Disabled。


AI開源十五:TensorFlow Lite GPU 代理


最後需要確保發佈版本只能在 64 位系統上構建。在 Project navigator -> tflite_camera_example -> PROJECT -> tflite_camera_example -> Build Settings 上將 Build Active Architecture Only > Release選擇為 Yes。


AI開源十五:TensorFlow Lite GPU 代理


在你自己的模型上使用GPU代理

Android

查看演示應用程序來了解如何添加代理。在你的應用程序中,像上面一樣添加 AAR ,導入org.tensorflow.lite.gpu.GpuDelegate 模塊,並使用 addDelegate 功能將GPU代理註冊到解釋器中。

<code>import org.tensorflow.lite.Interpreter;import org.tensorflow.lite.gpu.GpuDelegate;// 初始化使用 GPU 代理的解釋器GpuDelegate delegate = new GpuDelegate();Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);Interpreter interpreter = new Interpreter(model, options);// 進行推理while (true) {  writeToInput(input);  interpreter.run(input, output);  readFromOutput(output);}// 清理delegate.close();/<code>

iOS

在你的應用程序代碼中,引入 GPU 代理頭文件來讓Interpreter::ModifyGraphWithDelegate 功能將 GPU 代理註冊到解釋器中。

<code>#import "tensorflow/lite/delegates/gpu/metal_delegate.h"// 初始化使用 GPU 代理的解釋器std::unique_ptr<Interpreter> interpreter;InterpreterBuilder(*model, resolver)(&interpreter);auto* delegate = NewGpuDelegate(nullptr);  // default configif (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;// 進行推理 while (true) {  WriteToInputTensor(interpreter->typed_input_tensor<float>(0));  if (interpreter->Invoke() != kTfLiteOk) return false;  ReadFromOutputTensor(interpreter->typed_output_tensor<float>(0));}// 清理interpreter = nullptr;DeleteGpuDelegate(delegate);/<code>

支持的模型和 Ops

在 GPU 代理發佈後,我們提供了少數可以在後端運行的模型:

  • MobileNet v1 (224x224)圖像分類 [下載]
    (為移動和嵌入式視覺應用設計的圖像分類模型)
  • DeepLab 分割 (257x257) [下載]
    (將輸入圖像的每個像素指定語義標籤(例如,狗,貓。汽車的圖像分割模型)
  • MobileNet SSD 物體檢測 [下載]
    (用於檢測多個帶有邊框的對象的圖像分類模型)
  • PoseNet用於姿勢估計 [下載]
    (用於估計圖像或視頻中人物的姿勢的視覺模型)

如果需要完整的支持的 Ops 的列表,請看進階文檔。

不支持的模型和 ops

如果一些 ops 並不支持 GPU 代理,框架只會在 GPU 上運行圖形的一部分,剩下的部分會在 CPU 上運行。因為這會導致 CPU/GPU 同時出現很高的使用率,像這樣的分開執行模式會導致運行起來比整個網絡在 CPU 上運行要慢。在這種情況下,用戶會收到一個像這樣的警告:

<code>WARNING: op code #42 cannot be handled by this delegate./<code>
<code>警告:此代理無法處理#42操作碼/<code>

我們沒有為這種失敗提供回調,因為這不是真的運行錯誤,但是這個錯誤是開發者可以注意到的,他們可以嘗試將整個網絡在代理上運行。

優化建議

一些在 CPU 上的瑣碎的的操作可能在 GPU 上會有很高的佔用。其中的一種操作就是很多形式的 reshape 操作,像 BATCH_TO_SPACE, SPACE_TO_BATCH, SPACE_TO_DEPTH 等等。如果這些 ops 只是為了方便網絡構架師的邏輯思考而放置在網絡中,為了更好的性能將他們在網絡中移除是值得的。

在 GPU 上,張量數據被分成4個通道。因此,計算一個 [B,H,W,5] 的張量和計算 [B,H,W,8]的效果是一樣的,但是它們都比運行 [B,H,W,4] 的性能要差的多。

從這個意義上講,如果相機硬件支持 RGBA 形式圖像幀,4 通道輸入明顯更快因為可以避免內存複製(從 3 通道 RGB 轉變到 4 通道 RGBX)。

為了獲得最佳性能,請不要猶豫,使用移動優化的網絡架構來重新訓練您的分類器。這是優化設備推斷性能的重要部分。


分享到:


相關文章: