一、 TensorRT基本介紹
TensorRT是一種高性能深度學習推理優化器和運行時加速庫,可以為深度學習應用提供低延遲、高吞吐率的部署推理。
TensorRT可用於對超大規模數據中心、嵌入式平台或自動駕駛平台進行推理加速。
TensorRT現已能支持TensorFlow、Caffe、Mxnet、Pytorch等幾乎所有的深度學習框架,將TensorRT和NVIDIA的GPU結合起來,能在幾乎所有的框架中進行快速和高效的部署推理。
一般的深度學習項目,訓練時為了加快速度,會使用多GPU分布式訓練。但在部署推理時,為了降低成本,往往使用單個GPU機器甚至嵌入式平台(比如 NVIDIA Jetson)進行部署,部署端也要有與訓練時相同的深度學習環境,如caffe,TensorFlow等。
由於訓練的網絡模型可能會很大(比如,inception,resnet等),參數很多,而且部署端的機器性能存在差異,就會導致推理速度慢,延遲高。這對於那些高實時性的應用場合是致命的,比如自動駕駛要求實時目標檢測,目標追蹤等。
為了提高部署推理的速度,出現了很多模型優化的方法,如:模型壓縮、剪枝、量化、知識蒸餾等,這些一般都是在訓練階段實現優化。
而TensorRT 則是對訓練好的模型進行優化,通過優化網絡計算圖提高模型效率。
當網絡訓練完之后,可以將訓練模型文件直接丟進tensorRT中,而不再需要依賴深度學習框架(Caffe,TensorFlow等),如下:
二、優化方式
TensorRT優化方法主要有以下幾種方式,最主要的是前面兩種。
-
層間融合或張量融合(Layer & Tensor Fusion)
制約計算速度的CUDA核心計算張量,往往大量的時間也是浪費在CUDA核心的啟動和對每一層輸入/輸出張量的讀寫操作上面,這造成了內存帶寬的瓶頸和GPU資源的浪費。
TensorRT通過對層間的橫向或縱向合並,使得層的數量大大減少,這樣就可以一定程度的減少kernel launches和內存讀寫。
橫向合並可以把卷積、偏置和激活層合並成一個CBR結構(convolution, bias, and ReLU layers are fused to form a single layer),只占用一個CUDA核心。
縱向合並可以把結構相同,但是權值不同的層合並成一個更寬的層,也只占用一個CUDA核心。
另外,對於多分支合並的情況,TensorRT完全可以實現直接接到需要的地方,不用專門做concat的操作,所以這一層也可以取消掉。
合並之后的計算圖(右側)的層次更少了,占用的CUDA核心數也少了,因此整個模型結構會更小,更快,更高效。
-
數據精度校准(Weight &Activation Precision Calibration)
大部分深度學習框架在訓練神經網絡時網絡中的張量(Tensor)都是32位浮點數的精度(Full 32-bit precision,FP32),一旦網絡訓練完成,在部署推理的過程中由於不需要反向傳播,完全可以適當降低數據精度,比如降為FP16或INT8的精度。更低的數據精度將會使得內存占用和延遲更低,模型體積更小。
如下表為不同精度的動態范圍:
Precision |
Dynamic Range |
FP32 |
−3.4×1038 +3.4×1038−3.4×1038 +3.4×1038 |
FP16 |
−65504 +65504−65504 +65504 |
INT8 |
−128 +127−128 +127 |
INT8只有256個不同的數值,使用INT8來表示 FP32精度的數值,肯定會丟失信息,造成性能下降。不過TensorRT會提供完全自動化的校准(Calibration )過程,會以最好的匹配性能將FP32精度的數據降低為INT8精度,最小化性能損失。關於校准過程,后面會專門做一個探究。
-
Kernel Auto-Tuning內核自動調整
網絡模型在推理計算時,是調用GPU的CUDA核進行計算的。TensorRT可以針對不同的算法,不同的網絡模型,不同的GPU平台,進行 一些Kernel層面的優化,以保證當前模型在特定平台上以最優性能計算。
-
Dynamic Tensor Memory動態張量顯存
在每個tensor使用期間,TensorRT會為其指定顯存,避免顯存重復申請,減少內存占用和提高內存的重復使用效率(reuse)。
-
Multi-Stream Execution多流執行
使用CUDA中的stream技術,對於同一輸入的多個分支可以進行並行運算,還可以根據不同batchsize優化。
三、使用Tensorrt的一般步驟
基本流程:
1、訓練神經網絡,
2、優化得到推理引擎plan,序列化到磁盤
3、使用時反序列化,使用優化后的推理引擎進行加速
1、創建builder:構造器。包含tensorrt所有組件,及推理的整個流程,網絡、解析器、輸入輸出的buffer地址,推理優化的引擎,輸入輸出結果的維度等
2、創建network。保存訓練好的神經網絡。
3、創建parser:用來解析網絡。caffe、tensorflow、onnx……也可自定義
4、綁定:gpu的輸入、輸出地址、自定義組件
輸入:訓練好的神經網絡模型及其結構。支持所有框架。
輸出:一個可執行的推理引擎。
5、序列化反序列化
6、傳輸計算數據:CPU到GPU
7、執行計算
8、傳輸計算結果:GPU到CPU
四、運用場景
嵌入式、自動駕駛、數據中心
五、其他
1,插件支持
我們在做模型結構設計時,有時候自己會設計一些layer來滿足任務需求,但是這些layer在使用Tensorrt優化時,TensorRT可能並不支持,如ROI Align,這時候就需要通過Plugin的形式自己去實現,如上圖所示的custom layer。實現過程包括如下兩個步驟:
首先需要重載一個IPlugin的基類,生成自己的Plugin的實現,告訴GPU或TensorRT需要做什么操作,要構建的Plugin是什么樣子,其實就是類似於開發一個應用軟件的插件,需要在上面實現什么功能。
其次要將插件替換網絡中自己實現的layer。
現在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不支持的層。 如下圖:
這就解決了適應不同用戶的自定義層的需求。
build engine:創建解析器、工作空間、數據類型,序列化,釋放
不同的設備引擎不通用,只能在同一個設備使用。例如:在服務器優化引擎,放到nano設備上,不行
pluginfoctory:如果網絡層並不是直接支持的,自定義網絡層
plugin:輸入輸出,初始化
2、實用工具Netron:
Netron是神經網絡,深度學習和機器學習模型的可視化工具(viewer)。
Netron 支持目前大多數主流深度學習框架的模型,如下所示:
-
ONNX(.onnx,.pb)
-
Keras(.h5,.keras)
-
CoreML(.mlmodel)
-
TensorFlow Lite(.tflite)
-
Netron對Caffe(.caffemodel)
-
Caffe2(predict_net.pb)
-
MXNet(.model,-symbol.json)
-
TensorFlow.js(model.json,.pb)
-
TensorFlow(.pb,.meta)
Yolov5l可視化網絡結構圖: