TensorFlow團隊近日在博客上發佈了TensorFlow Lite開發者預覽版,據介紹,新的版本可以讓模型推理速度提升至原來的4~6倍。
以下爲博客全文
由於設備的處理和能力有限,在移動設備上的計算密集型機器學習模型上運行推理,對資源的要求很高。雖然轉換爲定點模型是一種加速的方法,但我們的用戶已經要求我們提供GPU支持作爲加速原始浮點模型推理的選項,且不增加量化的額外複雜性和潛在的準確性損失。
我們很高興地宣佈,隨着TensorFlow Lite GPU後端開發者預覽版的發佈,你將能夠利用移動GPU來選擇模型訓練(如下所示),對於不支持的部分,將自動使用CPU進行推理。在未來的幾個月裏,我們將繼續增加額外的操作系統,並改善GPU整體的後端產品。
新的後端利用了:
- OpenGL ES 3.1在Android設備上計算着色器
- iOS設備上的金屬計算着色器
今天,我們發佈了新的GPU後端的預編譯二進制預覽版,讓開發人員和機器學習研究人員可以儘早嘗試這種令人興奮的新技術。我們計劃在2019年晚些時候發佈一個完整的開源版本,包含我們從開發者的經驗中收集的反饋。
目前TensorFlow Lite 仍使用CPU浮點推斷進行人臉輪廓檢測(非人臉識別)。未來我們會利用新的GPU後端,可以將Pixel 3和三星S9的推理速度提升4~6倍。
GPU與CPU性能
我們已經在谷歌的產品中進行了幾個月新的GPU後端測試,加速了計算密集型網絡,爲我們的用戶提供了重要的用例。
對於Pixel 3的人像模式,Tensorflow Lite GPU讓前景-背景分割模型的速度提高了4倍以上,新的深度預估模型的推理速度提高了10倍以上,同時還對CPU推理浮點精度提高。在YouTube上的YouTube Stories和Playground Stickers中,實時視頻分割模型在各種手機上的測試加速5~10倍。
我們發現,對於各種深度神經網絡模型,新的GPU後端通常比浮點CPU速度快2~7倍。我們對4個公共模型和2個內部模型進行了基準測試,涵蓋了開發人員和研究人員在一系列Android和Apple設備上遇到的常見用例:
公共模型:
(基於移動和嵌入式視覺應用的圖像分類模型)
(圖像或視頻中估計人體姿勢的視覺模型)
(圖像分割模型,將語義標籤(如狗、貓、車)分配給輸入圖像中的每個像素)
(檢測帶有邊框的多個對象的圖像分類模型)
谷歌專有用例:
1.MLKit
2.實時視頻分割
在更加複雜的神經網絡模型上GPU加速效果最顯著,這些模型本身更有利於GPU的利用,例如密集的預測/分割或分類任務。在小型模型中,加速效果效果可能略差,但CPU的使用可以降低內存傳輸固有的延遲成本。
如何使用?
教程
最簡單的入門方法是按照我們的教程使用帶有GPU委託的TensorFlow Lite演示應用程序。下面簡要介紹了這種方法。有關更多信息,請參閱我們的完整文檔:https://www.tensorflow.org/lite/performance/gpu_advanced。
使用Java for Android
我們已經準備了一個完整的Android存檔(AAR),包括帶有GPU後端的TensorFlow Lite。編輯gradle文件替換當前版本,以包含這個AAR,並將此代碼片段添加到Java初始化代碼中。
// Initialize interpreter with GPU delegate.
GpuDelegate delegate = new GpuDelegate();
Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
Interpreter interpreter = new Interpreter(model, options);
// Run inference.
while (true) {
writeToInputTensor(inputTensor);
interpreter.run(inputTensor, outputTensor);
readFromOutputTensor(outputTensor);
}
// Clean up.
delegate.close();
使用C ++ for iOS
步驟1.下載TensorFlow Lite的二進制版本。
步驟2.更改代碼,以便在創建模型之後調用ModifyGraphWithDelegate()。
// Initialize interpreter with GPU delegate.
std::unique_ptr<Interpreter> interpreter;
InterpreterBuilder(model, op_resolver)(&interpreter);
auto* delegate = NewGpuDelegate(nullptr); // default config
if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
// Run inference.
while (true) {
WriteToInputTensor(interpreter->typed_input_tensor<float>(0));
if (interpreter->Invoke() != kTfLiteOk) return false;
ReadFromOutputTensor(interpreter->typed_output_tensor<float>(0));
}
// Clean up.
interpreter = nullptr;
DeleteGpuDelegate(delegate);
如何加速?
GPU後端目前支持select操作(請參閱文檔)。當只包含這些操作時,你的模型運行速度將最快;不支持的GPU操作將自動退回到CPU進行操作。
它是如何工作的?
深度神經網絡按順序運行數百個操作,這使得它們非常適合針對吞吐量的並行工作負載而設計的GPU。
Objective-C++可通過調用Interpreter::ModifyGraphWithDelegate(),或者通過Interpreter.Options間接調用Interpreter的構造函數來初始化GPU。在初始化階段,基於從框架接收的執行計劃,構建輸入神經網絡的規範表示。使用此新表示,可應用一組轉換規則,包括但不限於:
- 剔除不需要的ops
- 將ops替換爲性能更好的等效ops
- 合併ops,以減少最終生成的着色程序的數量
基於此優化圖(optimized graph),生成並編譯計算着色器。我們目前在Android上使用OpenGL ES 3.1 計算着色器,在iOS上使用Metal 計算着色器。在創建這些計算着色器時,我們還採用了各種特定於體系結構的優化,例如:
- 進行某些操作特殊化而不是較慢的通用實現
- 釋放寄存器壓力
- 選擇最佳工作組大小
- 安全地調整精度
- 重新排序顯式數學操作
在這些優化結束後,編譯着色程序可能需要幾毫秒到半秒,就像手機遊戲一樣。一旦着色程序編譯完成,新的GPU推理引擎就可以開始工作了。
在推斷每個輸入時:
- 如有必要,輸入將移至GPU:如果輸入張量還沒有存儲爲GPU內存,那麼通過創建GL緩衝區/texture或mtlbuffer(同時還可能複製數據),GPU可以訪問輸入張量。由於GPU在4通道數據結構中效率最高,因此通道大小不等於4的張量將被重新塑造成更適合GPU的佈局。
- 執行着色器程序:將上述着色器程序插入命令緩衝區隊列中,GPU將這些程序輸出。在這一步中,我們還爲中間張量管理GPU內存,以儘可能減少後端的內存佔用。
- 必要時將輸出移動到CPU:一旦深度神經網絡完成處理,框架就會將結果從GPU內存複製到CPU內存,除非網絡的輸出可以直接在屏幕上呈現,不需要這樣的傳輸。
爲了獲得最佳體驗,我們建議優化輸入/輸出張量副本和/或網絡架構。有關此類優化的詳細信息,可以在TensorFlow Lite GPU文檔中找到。有關性能最佳實踐,請閱讀本指南。
它有多大?
GPU委託將爲Android armeabi-v7a APK增加270KB的內存,爲iOS增加212KB的內存。但後端是可選的,因此,如果不使用GPU委託,就不需要包含它。
未來的工作
這只是我們GPU支持工作的開始。除了社區反饋外,我們還打算進行以下改進:
- 擴大運營範圍
- 進一步優化性能
- 發展並最終確定API
我們歡迎你在GitHub和StackOverflow頁面上留下你的想法和評論。
原文鏈接: