TensorRT-優化-原理


TensorRT-優化-原理

一.優化方式

TentsorRT 優化方式:

 

TensorRT優化方法主要有以下幾種方式,最主要的是前面兩種。

  • 層間融合或張量融合(Layer & Tensor Fusion)

如下圖左側是GoogLeNetInception模塊的計算圖。這個結構中有很多層,在部署模型推理時,這每一層的運算操作都是由GPU完成的,但實際上是GPU通過啟動不同的CUDA(Compute unified device architecture)核心來完成計算的,CUDA核心計算張量的速度是很快的,但是往往大量的時間是浪費在CUDA核心的啟動和對每一層輸入/輸出張量的讀寫操作上面,這造成了內存帶寬的瓶頸和GPU資源的浪費。TensorRT通過對層間的橫向或縱向合並(合並后的結構稱為CBR,意指 convolution, bias, and ReLU layers are fused to form a single layer),使得層的數量大大減少。橫向合並可以把卷積、偏置和激活層合並成一個CBR結構,只占用一個CUDA核心。縱向合並可以把結構相同,但是權值不同的層合並成一個更寬的層,也只占用一個CUDA核心。合並之后的計算圖(圖4右側)的層次更少了,占用的CUDA核心數也少了,因此整個模型結構會更小,更快,更高效。

 

 

  •  數據精度校准(Weight &Activation Precision Calibration)

大部分深度學習框架在訓練神經網絡時網絡中的張量(Tensor)都是32位浮點數的精度(Full 32-bit precision,FP32),一旦網絡訓練完成,在部署推理的過程中由於不需要反向傳播,完全可以適當降低數據精度,比如降為FP16或INT8的精度。更低的數據精度將會使得內存占用和延遲更低,模型體積更小。

如下表為不同精度的動態范圍:

Precision

Dynamic Range

FP32

3.4×1038 +3.4×10383.4×1038 +3.4×1038

FP16

65504 +6550465504 +65504

INT8

128 +127128 +127

INT8只有256個不同的數值,使用INT8來表示 FP32精度的數值,肯定會丟失信息,造成性能下降。不過TensorRT會提供完全自動化的校准(Calibration )過程,會以最好的匹配性能將FP32精度的數據降低為INT8精度,最小化性能損失。關於校准過程,后面會專門做一個探究。

  • Kernel Auto-Tuning

網絡模型在推理計算時,是調用GPU的CUDA核進行計算的。TensorRT可以針對不同的算法,不同的網絡模型,不同的GPU平台,進行 CUDA核的調整(怎么調整的還不清楚),以保證當前模型在特定平台上以最優性能計算。

TensorRT will pick the implementation from a library of kernels that delivers the best performance for the target GPU, input data size, filter size, tensor layout, batch size and other parameters.

  • Dynamic Tensor Memory

在每個tensor的使用期間,TensorRT會為其指定顯存,避免顯存重復申請,減少內存占用和提高重復使用效率。

  • Multi-Stream Execution

Scalable design to process multiple input streams in parallel,這個應該就是GPU底層的優化了。

二.原理

TensorRT是一個高性能的深度學習推理(Inference)優化器,可以為深度學習應用提供低延遲、高吞吐率的部署推理。TensorRT可用於對超大規模數據中心、嵌入式平台或自動駕駛平台進行推理加速。TensorRT現已能支持TensorFlow、Caffe、Mxnet、Pytorch等幾乎所有的深度學習框架,將TensorRT和NVIDIA的GPU結合起來,能在幾乎所有的框架中進行快速和高效的部署推理。

TensorRT 是一個C++庫,從 TensorRT 3 開始提供C++ API和Python API,主要用來針對 NVIDIA GPU進行 高性能推理(Inference)加速。現在最新版TensorRT是4.0版本。

TensorRT 之前稱為GIE。

關於推理(Inference):

 

 

 

 

 由以上兩張圖可以很清楚的看出,訓練(training)和 推理(inference)的區別:

  • 訓練(training)包含了前向傳播和后向傳播兩個階段,針對的是訓練集。訓練時通過誤差反向傳播來不斷修改網絡權值(weights)。
  • 推理(inference)只包含前向傳播一個階段,針對的是除了訓練集之外的新數據。可以是測試集,但不完全是,更多的是整個數據集之外的數據。其實就是針對新數據進行預測,預測時,速度是一個很重要的因素。

一般的深度學習項目,訓練時為了加快速度,會使用多GPU分布式訓練。但在部署推理時,為了降低成本,往往使用單個GPU機器甚至嵌入式平台(比如 NVIDIA Jetson)進行部署,部署端也要有與訓練時相同的深度學習環境,如caffe,TensorFlow等。

由於訓練的網絡模型可能會很大(比如,inception,resnet等),參數很多,而且部署端的機器性能存在差異,就會導致推理速度慢,延遲高。這對於那些高實時性的應用場合是致命的,比如自動駕駛要求實時目標檢測,目標追蹤等。

所以為了提高部署推理的速度,出現了很多輕量級神經網絡,比如squeezenet,mobilenet,shufflenet等。基本做法都是基於現有的經典模型提出一種新的模型結構,然后用這些改造過的模型重新訓練,再重新部署。

而tensorRT 則是對訓練好的模型進行優化。 tensorRT就只是 推理優化器。當你的網絡訓練完之后,可以將訓練模型文件直接丟進tensorRT中,而不再需要依賴深度學習框架(Caffe,TensorFlow等),如下:

 

 

 

 

 可以認為tensorRT是一個只有前向傳播的深度學習框架,這個框架可以將 Caffe,TensorFlow的網絡模型解析,然后與tensorRT中對應的層進行一一映射,把其他框架的模型統一全部 轉換到tensorRT中,然后在tensorRT中可以針對NVIDIA自家GPU實施優化策略,並進行部署加速。

目前TensorRT4.0 幾乎可以支持所有常用的深度學習框架,對於caffe和TensorFlow來說,tensorRT可以直接解析他們的網絡模型;對於caffe2,pytorch,mxnet,chainer,CNTK等框架則是首先要將模型轉為 ONNX 的通用深度學習模型,然后對ONNX模型做解析。而tensorflow和MATLAB已經將TensorRT集成到框架中去了。

ONNX(Open Neural Network Exchange )是微軟和Facebook攜手開發的開放式神經網絡交換工具,也就是說不管用什么框架訓練,只要轉換為ONNX模型,就可以放在其他框架上面去inference。這是一種統一的神經網絡模型定義和保存方式,上面提到的除了tensorflow之外的其他框架官方應該都對onnx做了支持,而ONNX自己開發了對tensorflow的支持。從深度學習框架方面來說,這是各大廠商對抗谷歌tensorflow壟斷地位的一種有效方式;從研究人員和開發者方面來說,這可以使開發者輕易地在不同機器學習工具之間進行轉換,並為項目選擇最好的組合方式,加快從研究到生產的速度。

上面圖中還有一個 Netwok Definition API 這個是為了給那些使用自定義的深度學習框架訓練模型的人提供的TensorRT接口。舉個栗子:比如 YOLO 作者使用的darknet要轉tensorrt估計得使用這個API,不過一般網上有很多使用其他框架訓練的YOLO,這就可以使用對應的caffe/tensorflow/onnx API了。

ONNX / TensorFlow / Custom deep-learning frame模型的工作方式:

 

 

 現在tensorRT支持的層有:

  • Activation: ReLU, tanh and sigmoid
  • Concatenation : Link together multiple tensors across the channel dimension.
  • Convolution: 3D,2D
  • Deconvolution
  • Fully-connected: with or without bias
  • ElementWise: sum, product or max of two tensors
  • Pooling: max and average
  • Padding
  • Flatten
  • LRN: cross-channel only
  • SoftMax: cross-channel only
  • RNN: RNN, GRU, and LSTM
  • Scale: Affine transformation and/or exponentiation by constant values
  • Shuffle: Reshuffling of tensors , reshape or transpose data
  • Squeeze: Removes dimensions of size 1 from the shape of a tensor
  • Unary: Supported operations are exp, log, sqrt, recip, abs and neg
  • Plugin: integrate custom layer implementations that TensorRT does not natively support.

基本上比較經典的層比如,卷積,反卷積,全連接,RNN,softmax等,在tensorRT中都是有對應的實現方式的,tensorRT是可以直接解析的。

但是由於現在深度學習技術發展日新月異,各種不同結構的自定義層(比如:STN)層出不窮,所以tensorRT是不可能全部支持當前存在的所有層的。那對於這些自定義的層該怎么辦?

tensorRT中有一個 Plugin 層,這個層提供了 API 可以由用戶自己定義tensorRT不支持的層。 如下圖:

 

 

 這就解決了適應不同用戶的自定義層的需求。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM