天天看點

jetson tx2 上部署TensorRT模型推理

參考:https://arleyzhang.github.io/articles/7f4b25ce/

1. Jetson tx2 是什麼?

Jetson tx2簡而言之就是AI計算終端,采用 NVIDIA Pascal™ 構架,外形小巧、節能高效,非常适合機器人、無人機、智能錄影機和便攜醫療裝置等智能邊緣終端裝置。

2. TensorRT是什麼?

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

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

jetson tx2 上部署TensorRT模型推理
jetson tx2 上部署TensorRT模型推理

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

訓練(training): 包含了前向傳播和後向傳播兩個階段,針對的是訓練集。訓練時通過誤差反向傳播來不斷修改網絡權值(weights)。

推理(inference): 隻包含前向傳播一個階段,針對的是除了訓練集之外的新資料。可以是測試集,但不完全是,更多的是整個資料集之外的資料。其實就是針對新資料進行預測,預測時,速度是一個很重要的因素。

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

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

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

而tensorRT 則是對訓練好的模型進行優化。 tensorRT就隻是 推理優化器。當你的網絡訓練完之後,可以将訓練模型檔案直接丢進tensorRT中,而不再需要依賴深度學習架構(Caffe,TensorFlow等),如下:

jetson tx2 上部署TensorRT模型推理
jetson tx2 上部署TensorRT模型推理

可以認為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模型的工作方式:

jetson tx2 上部署TensorRT模型推理

現在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不支援的層。 如下圖:

jetson tx2 上部署TensorRT模型推理

這就解決了适應不同使用者的自定義層的需求。

3 TensotRT優化方式

jetson tx2 上部署TensorRT模型推理

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核心數也少了,是以整個模型結構會更小,更快,更高效。

jetson tx2 上部署TensorRT模型推理

資料精度校準(Weight &Activation Precision Calibration)

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

如下表為不同精度的動态範圍:

Precision Dynamic Range

FP32 −3.4×1038 +3.4×1038

FP16 −65504 +65504

INT8 −128 +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底層的優化了。

4.用TensorRT部署模型

github開源教程:

https://github.com/NVIDIA-AI-IOT/tf_trt_models

5.github牛人部落格

https://jkjung-avt.github.io/tf-trt-models/

繼續閱讀