雖然手機的發展日新月異,我們更換手機的頻率也加快,但不可否認的是,手機效能相比PC還是有很大的差距。對於機器學習來說,我們可以在電腦上訓練模型,在手機上應用模型,但某些複雜的模型,在手機上進行推斷,依然很慢。前一段時間曾經研究過在手機瀏覽器中加入鑑黃的功能,使用yahoo的open_nsfw模型,實際測試下來,速度仍然太慢,只得放棄。
手機是人工智慧應用的絕佳載體,我一直在關注著機器學習在移動端的最新進展,特別是TensorFlow Lit。這是一篇翻譯的文章,原文標題:TensorFlow Lite Now Faster with Mobile GPUs (Developer Preview),點選閱讀原文,可以跳轉到原文連結,需要翻牆哦!
由於處理器效能和電池容量有限,在移動裝置上使用計算密集的機器學習模型進行推斷是非常耗資源的。 雖然可以採用一種加速途徑:轉換為定點數模型,但使用者已經要求作為一種選項,為加速原始浮點模型推理提供GPU支援,而不會產生額外的複雜性和潛在的量化精度損失。
我們聽取了使用者的心聲,很高興地宣佈,您現在可以使用最新發布的TensorFlow Lite GPU端開發人員預覽版,利用移動GPU為特定模型(在後面列出)加速; 對於不支援的部分模型,則回退到CPU推斷。在接下來的幾個月中,我們將繼續增加額外的操作(ops)並整體改進GPU端。
這個新的後端利用了:
今天,我們釋出了新GPU後端的預編譯二進位制預覽版,使開發人員和機器學習研究人員有機會嘗試這種令人興奮的新技術。我們計劃在2019年晚些時候釋出一個完整的開源版本,包含從您們試驗中收集的反饋。
今天我們使用TensorFlow Lite CPU浮點推斷進行面部輪廓檢測(並非面部識別),未來利用新的GPU後端,在Pixel 3和Samsung S9上的推理速度可以提升~4倍,iPhone7上可以加速到~6倍。
GPU與CPU效能對比
在谷歌,我們已經在產品中使用了好幾個月的新GPU後端,加速了計算密集型網路,為我們的使用者提供了重要的用例。
在Pixel 3上的縱向模式下,Tensorflow Lite GPU推理相比具有浮點精度的CPU推斷,將前景 - 背景分割模型加速4倍以上,新的深度估計模型加速10倍以上。 在YouTube Stories和Playground Stickers中,我們的實時視訊分割模型在各種手機上的速度提高了5-10倍。
我們發現,對於各種各樣的深度神經網路模型,新的GPU後端通常比浮點CPU實現快2-7倍。下面,我們對4個公開模型和2個內部模型進行了基準測試,涵蓋了開發人員和研究人員在Android和Apple裝置中遇到的常見用例:
公開模型:
- MobileNet v1(224x224)影象分類[下載] (為移動和嵌入式視覺應用設計的影象分類模型)
- 用於姿勢估計的PoseNet[下載] (判斷影象或視訊中人物姿勢的視覺模型)
- [DeepLab分割模型(257x257)]ai.googleblog.com/2018/03/sem…)[下載] (將語義標籤(例如,狗、貓、汽車)分配給輸入影象中的畫素級影象分割模型)
- MobileNet SSD目標檢測[下載] (使用邊界框檢測多個物件的影象分類模型)
Google私有案例:
- MLKit中使用的面部輪廓
- Playground Stickers和YouTube Stories中使用的實時視訊分割
表1. 與各種Android和Apple裝置上的6種模型的基準CPU效能相比,GPU的平均效能加倍。倍數越高,效能越佳。
神經網路模型越複雜,GPU加速越重要,這些模型可以更好地利用GPU,例如計算密集的預測、分段或分類任務。在非常小的模型上,可能沒什麼加速,使用CPU反而更有利,可以避免記憶體傳輸中固有的延遲代價。
我該如何使用它?
教程
最簡單的入門方法是按照我們的教程,使用帶GPU支援的TensorFlow Lite演示應用程式。以下簡要概述它們的使用。更多的資訊,請參閱我們的完整文件。
手把手的指導教程,請觀看視訊:
使用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後端目前支援選擇操作(參見文件)。如果你的模型僅包含這些操作,將執行得最快,而不受支援的GPU操作將自動回退到CPU。
它是如何工作的?
深度神經網路按順序執行數百個操作,使它們非常適合GPU,這些GPU的設計考慮了面向吞吐量的並行工作負載。
在Objective-C++中呼叫Interpreter::ModifyGraphWithDelegate()時,或者在Java中帶Interpreter.Options呼叫Interpreter的建構函式,初始化GPU代理。在該初始化階段,基於從框架接收的執行計劃構建輸入神經網路的規範表示。使用此新表示,將應用一組轉換規則,包括但不限於:
- 剔除不必要的ops
- 用其他具有更好效能的等效ops替換ops
- 合併ops以減少最終生成的著色器程式的數量
基於此優化圖,生成並編譯計算著色器。目前,我們在Android上使用OpenGL ES 3.1 Compute Shaders,在iOS上使用Metal Compute Shaders。在建立這些計算著色器時,我們還採用了各種特定於體系結構的優化,例如:
- 應用某些ops的特化而不是它們(較慢)的通用實現
- 減少暫存器的壓力
- 選擇最佳工作組的大小
- 安全的減少精度
- 重新排序顯式的數學運算
在這些優化結束時,著色器程式被編譯,可能需要幾毫秒到半秒,就像手機遊戲一樣。一旦著色器程式編譯出來,新的GPU推斷引擎就可以工作了。
在推斷每個輸入時:
- 如有必要,輸入將移至GPU:輸入張量,如果尚未儲存為GPU記憶體,可由框架通過建立GL緩衝區/紋理或MTLBuffers進行GPU訪問,同時還可能複製資料。由於GPU在4通道資料結構中效率最高,因此通道大小不等於4的張量將重新整形為更加GPU友好的佈局。
- 執行著色器程式:將上述著色器程式插入命令緩衝區佇列,GPU將這些程式輸出。在此步驟中,我們還為中間張量管理GPU記憶體,以儘可能減少後端的記憶體佔用。
- 必要時將輸出移動到CPU:一旦深度神經網路完成處理,框架將結果從GPU記憶體複製到CPU記憶體,除非網路輸出可以直接在螢幕上呈現並且不需要這種傳輸。
為獲得最佳體驗,我們建議優化輸入/輸出的張量複製和/或網路架構。有關此類優化的詳細資訊,請參閱TensorFlow Lite GPU文件。有關效能的最佳實踐,請閱讀這篇指南。
它有多大?
GPU代理將為Android armeabi-v7a APK新增大約270KB,為iOS的每個所包含架構新增212KB。但是,後端是可選的,因此如果您不使用GPU代理,則無需包含它。
未來的工作
這只是我們GPU支援工作的開始。除了社群反饋,我們還打算進行以下改進:
- 擴大ops的範圍
- 進一步優化效能
- 演進並最終固定API
我們鼓勵您將您的想法和評論留在我們的GitHub和StackOverflow頁面上。
注:本文中包含有大量連結,但是微信公眾號不能包含外鏈,請訪問我在掘金上的這篇專欄文章。文中的連結需要翻牆才能訪問。