強強聯手!Google 和 Nvidia 帶來最優化版 TensorFlow 1.7

評論
評論

本篇來自合作媒體 雷鋒網 ,INSIDE 經授權轉載。

日前,Google 和英偉達宣布將 NVIDIA TensorRT 集成到 TensorFlow 1.7 中。在 Google 開發者部落格中,他們介紹了此次合作的詳細資訊以及整合之後的性能,編譯整理如下:

TensorRT 是一個可以用於優化深度學習模型,以進行推理,並為生產環境中的 GPU 建立運行環境的庫。它能優化 TensorFlow 中的 FP16 浮點數和 INT8 整型數,並能自動選擇針對特定平台的內核,以最大化吞吐量,並最大限度的降低 GPU 推理期間的延遲。全新的集成工作流程簡化了在 TensorFlow 中使用 TensorRT 的步驟,同時使得 TensorFlow 達到了世界一流的性能水平。

經測試,在 NVIDIA Volta Tensor 核心上,集成了 TensorRT 的 TensorFlow 運行 ResNet-50 比沒有集成 TensorRT 的 TensorFlow 執行速度提高了 8 倍。

Google 和Nvidia 強強聯手,帶來優化版TensorFlow 1.7

優化 TensorFlow 中的子圖

在 TensorFlow 1.7 中,TensorRT 可以用於優化子圖,而 TensorFlow 執行其餘未優化的部分。這個方法使得開發者既能夠使用 TensorFlow 的眾多功能來快速構建模型,同時也可以在執行推理時使用 TensorRT 獲得強大的優化能力。如果你嘗試過在之前的 TensorFlow 模型中使用 TensorRT,你應該知道,要想使用某些不受支持的 TensorFlow 層,必須手動導入,這在某些情況下可能會耗費大量時間。

從工作流程的角度來看,開發者可以使用 TensorRT 來優化 TensorFlow 的每個子圖。

Google 和Nvidia 強強聯手,帶來優化版TensorFlow 1.7

在推斷過程中,TensorFlow 先將執行所有支持區域的圖,之後調用 TensorRT 去執行那些經過 TensorRT 優化過的節點。舉個例子,如果你的圖包含 A,B,C 三段,其中 B 段被 TensorRT 優化過,B 將被一個節點代替。那麼在推理過程中,TensorFlow 將先執行 A,之後調用 TensorRT 執行 B,最後 TensorFlow 執行 C。

這個用於優化 TensorRT 的新加入的 TensorFlow API,以凍結的 TensorFlow 圖為輸入,針對該子圖進行優化,最後將優化過的推理子圖發送回 TensorFlow 中。

下面為一段示例代碼:

# Reserve memory for TensorRT inference engine

gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction = number_between_0_and_1)

... 

trt_graph = trt.create_inference_graph(

                 input_graph_def = frozen_graph_def,

                 outputs = output_node_name,

                 max_batch_size=batch_size,

                 max_workspace_size_bytes=workspace_size,

                 precision_mode=precision) # Get optimized graph

per_process_gpu_memory_fraction 這個參數定義了 TensorFlow 允許使用的 GPU 顯存的比例,剩餘的顯存將分配給 TensorRT。這個參數應該在 TensorFlow-TensorRT 進程第一次啟動的時候設定好。比如,per_process_gpu_fraction=0.67,那麼 67% 的顯存會被分配給 TensorFlow,其餘的 33% 會被分配給 TensorRT 引擎。

Create_inference_graph 函數將凍結住的 TensorFlow 圖作為輸入,返回一個經過 TensorRT 節點優化過的圖。我們看看這個函數的參數:

Input_graph_def: 凍結住的 TensorFlow 圖

Outputs: 輸出節點名字的字符串列表,比如:[“resnet_v1_50/predictions/Resape_1”]

Max_batch_size: 整數,輸入的 batch size,比如,16

Max_workspace_size_bytes: 整數,能分配給 TensorRT 的最大 GPU 顯存大小

Precision_mode: 字符串,可選的值為「FP32」,「FP16」,「INT8」

舉個例子,如果 GPU 有 12GB 顯存,想要給 TensorRT 引擎分配 4GB 顯存,那麼應該設置 per_process_gpu_memory_fraction 為(12-4)/12=0.67,max_workspace_size_bytes=4,000,000,000.

我們來試著將這個新的 API 應用在 ResNet-50 上,看看經過優化後的模型在 TensorBoard 中看起來是什麼樣的。左側的圖像是沒有經過 TensorRT 優化的 ResNet-50,右側是經過優化的。在這個設定下,大部分圖被 TensorRT 優化,並用一個單一節點代替了(圖中高亮部分)。

Google 和Nvidia 強強聯手,帶來優化版TensorFlow 1.7

經過優化的 INT8 推理性能

TensorRT 兼容單精度(FP32)和半精度(FP16)訓練的模型(也可以將它們量化為 INT8),同時能盡可能減少由精度降低而導致的準確率降低。INT8 模型能夠更快的計算,同時對帶寬的需求也會降低,但是因為可用的動態範圍降低了,這也對神經網絡的權重和啟動表示提出了很大的挑戰。

Google 和Nvidia 強強聯手,帶來優化版TensorFlow 1.7

為了解決這個問題,TensorRT 使用了一個校正過程,以盡可能減小將 FP32 網絡近似成 8-bit 整型表示時的資料損失。在使用 TensorRT 優化 TensorFlow 圖之後,可以使用下面的命令將圖傳遞給 TensorRT 進行校準,如下:

trt_graph=trt.calib_graph_to_infer_graph(calibGraph)

除此之外的網路推理流程都沒有變化。這一步的輸出為一個可以被 TensorFlow 執行的凍結圖。

在 NVIDIA Volta GPU 上自動使用 Tensor 核心

在 NVIDIA Volta GPU 的 Tensor 核心上透過 TensorRT 進行半精度 TensorFlow 模型推理,能夠提供相較於單精度模型八倍的吞吐量。相較於更高精度的 FP32 或者 FP64,半精度數據(FP16)能夠減少神經網路的顯存使用量,這使得開發者能夠訓練和部署更大規模的神經網路,同時 FP16 相比 FP32 和 FP64 有更少的傳輸時間。

如果每個 Tensor 核心執行的是 D=A*B+C,其中 A 和 B 為半精度 4*4 矩陣,D 和 C 是單精度或者半精度 4*4 矩陣,那麼 V100 上此時 Tensor 核心的峰值性能是雙精度(FP64)性能的 10 倍,是單精度(FP32)性能的 4 倍。

Google 目前已經發布了 TensorFlow 1.7,同時也將跟 NVIDIA 更緊密地合作。希望這個新的解決方案額能夠在提供最強性能的同時,保持 TensorFlow 的易用性和靈活性。隨著 TensorRT 支持越來越多的網路結構,大家只要更新就可以享受到這些好處,而無須改寫代碼。

使用標準 pip install 即可更新到 TensorFlow 1.7:

pip install tensorflow-gpu r1.7

詳細的安裝說明可在下面找到:

https://github.com/tensorflow/tensorflow/tree/r1.7/tensorflow/contrib/tensorrt


精選熱門好工作

賣家關係維護專員

樂購蝦皮股份有限公司
臺北市.台灣

獎勵 NT$20,000

Partnership Manager

樂購蝦皮股份有限公司
臺北市.台灣

獎勵 NT$20,000

Video/Image Processing Software Engineer

PicCollage 拼貼趣
臺北市.台灣

獎勵 NT$20,000

評論