TensorRT 介紹

引用:https://arleyzhang.github.io/articles/7f4b25ce/

1 簡介

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

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

TensorRT 以前稱爲GIE。linux

關於推理(Inference):git

Training-vs-Inference-Graphic

ai_difference_between_deep_learning_training_inference

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

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

通常的深度學習項目,訓練時爲了加快速度,會使用多GPU分佈式訓練。但在部署推理時,爲了下降成本,每每使用單個GPU機器甚至嵌入式平臺(好比 NVIDIA Jetson)進行部署,部署端也要有與訓練時相同的深度學習環境,如caffe,TensorFlow等。算法

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

因此爲了提升部署推理的速度,出現了不少輕量級神經網絡,好比squeezenet,mobilenet,shufflenet等。基本作法都是基於現有的經典模型提出一種新的模型結構,而後用這些改造過的模型從新訓練,再從新部署。編程

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

1517972547350

1535458358489

能夠認爲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模型的工做方式:

1535458389523

如今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不支持的層。 以下圖:

pasted-image-0-1-625x519

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

2 優化方式

TentsorRT 優化方式:

1535459793419

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

    1517973035996

  • 數據精度校準(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平臺,進行 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底層的優化了。

3 安裝

這裏 是英偉達提供的安裝指導,若是有仔細認真看官方指導,基本上按照官方的指導確定能安裝成功。

問題是確定有不少人不肯意認真看英文指導,好比說我就是,我看那個指導都是直接找到命令行所在,直接敲命令,而後就出了不少問題,而後搜索好長時間,最後才發現,原來官方install guide裏是有說明的。

這裏使用的是 deb 包安裝的方式,如下是安裝過程,我是cuda 8.0 ,cuda9.0也是相似的。

進行下面三步時最好先將後面記錄的遇到的問題仔細看看,而後回過頭來按照 一二三 步來安裝。

第一步:

1
2
3
4
$ sudo dpkg -i nv-tensorrt-repo-ubuntu1604-ga-cuda8.0-trt3.0-20171128_1-1_amd64.deb
 
$ sudo apt-get update
$ sudo apt-get install tensorrt

其中的deb包要換成與本身 cuda和系統 對應的版本。

第二步:

使用python2則安裝以下依賴

1
$ sudo apt-get install python-libnvinfer-doc

這個是爲了安裝一些依賴的:好比 python-libnvinfer python-libnvinfer-dev swig3.0

若是是python3則安裝以下依賴

1
$ sudo apt-get install python3-libnvinfer-doc

第三步:

1
$ sudo apt-get install uff-converter-tf

這個是安裝通用文件格式轉換器,主要用在 TensorRT 與TensorFlow 交互使用的時候。

不過我安裝的時候仍是出問題了:

  • 安裝tensorRT以前要將cuda的兩個deb包添加上,由於TensorRT依賴好多cuda的一些東西好比 cuda-cublas-8-0 ,我以前cuda是用runfile安裝的,因此TensorRT安裝時有些依賴庫找不到致使出錯,以下圖:

    1522849270135

    上面提示缺乏依賴包,可是實際上 libnvinfer4 的包是tensorRT安裝了以後纔有的,那如今反而成了依賴包了,無論他,缺什麼安裝什麼,可是仍是出錯,以下:

    1522849521910

哇,仍是缺乏依賴包,此次是缺 cuda-cublas-8-0 ,如今知道了,缺的是cuda的相關組件。

後來把 cuda 的兩個deb包安裝以後就沒問題了,cuda 8.0 的deb包 在這裏 ,以下圖,下載紅框裏的兩個deb包。

1522849425693

若是用的是 runfile 的方式安裝的cuda的話,很容易出錯,由於網上大部分cuda安裝教程都是用runfile的方式安裝的。因此若是cuda就是用deb包安裝的話,就沒有這個問題,若是使用runfile安裝的話,安裝tensorRT以前要把這兩個deb包安裝上,安裝方式以下:

1
2
$ sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-cublas-performance-update_8.0.61-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64.deb

以上是本身摸索出來的,折騰了一番以後才發現原來官方的 install guide已經說明了,以下:

The debian installation automatically installs any dependencies, but:

  • requires sudo root privileges to install
  • provides no flexibility as to which location TensorRT is installed into
  • requires that the CUDA Toolkit has also been installed with a debian package.

注意最後一條,意思是若是用deb包安裝TensorRT,那麼前提是 你的CUDA也是用deb包安裝的。

怪本身沒有認真看,要是多花個5分鐘仔細看一下,就不用折騰這麼久了,由此深有感觸,文檔仍是官方英文原版的最好,並且要認真看。

不過不知道用 runfile cuda+Tar File Installation tensorRT的組合安裝方式是怎麼樣的,沒試過。

  • tensorRT 3 支持CUDA 8 和 CUDA 9,可是隻支持 cuDNN 7,我第一次安裝的時候cuDNN是5.1的,結果老是出錯,錯誤是啥忘記了,反正換成cuDNN 7就行了,這個官方指導也有說明,不過比較隱蔽,他是放在 4.2 Tar File Installation 一節說明的:

    1. Install the following dependencies, if not already present:
      ‣ Install the CUDA Toolkit v8.0, 9.0 or 9.2
      ‣ cuDNN 7.1.3
      ‣ Python 2 or Python 3

    我試過只要大版本是 cudnn7就能夠。這個也容易忽略。

安裝好後,使用 $ dpkg -l | grep TensorRT 命令檢測是否成功,輸出以下所示即爲成功

1522850610735

安裝後會在 /usr/src 目錄下生成一個 tensorrt 文件夾,裏面包含 bin , data , python , samples 四個文件夾, samples 文件夾中是官方例程的源碼; data , python 文件中存放官方例程用到的資源文件,好比caffemodel文件,TensorFlow模型文件,一些圖片等;bin 文件夾用於存放編譯後的二進制文件。

能夠把 tensorrt 文件夾拷貝到用戶目錄下,方便本身修改測試例程中的代碼。

進入 samples 文件夾直接 make,會在 bin 目錄中生成可執行文件,能夠一一進行測試學習。

另外tensorRT是不開源的, 它的頭文件位於 /usr/include/x86_64-linux-gnu 目錄下,共有七個,分別爲:

1
2
3
4
5
6
7
/usr/include/x86_64-linux-gnu/NvCaffeParser.h
/usr/include/x86_64-linux-gnu/NvInfer.h
/usr/include/x86_64-linux-gnu/NvInferPlugin.h
/usr/include/x86_64-linux-gnu/NvOnnxConfig.h
/usr/include/x86_64-linux-gnu/NvOnnxParser.h
/usr/include/x86_64-linux-gnu/NvUffParser.h
/usr/include/x86_64-linux-gnu/NvUtils.h

TensorRT4.0相比於3.0新增了對ONNX的支持。

tensorRT的庫文件位於 /usr/lib/x86_64-linux-gnu 目錄下,以下(篩選出來的,摻雜了一些其餘nvidia庫):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/usr/lib/x86_64-linux-gnu/libnvinfer.so
/usr/lib/x86_64-linux-gnu/libnvToolsExt.so
/usr/lib/x86_64-linux-gnu/libnvinfer_plugin.a
/usr/lib/x86_64-linux-gnu/libnvinfer_plugin.so.4
/usr/lib/x86_64-linux-gnu/libnvcaffe_parser.so
/usr/lib/x86_64-linux-gnu/libnvparsers.so.4.1.2
/usr/lib/x86_64-linux-gnu/stubs/libnvrtc.so
/usr/lib/x86_64-linux-gnu/libnvcaffe_parser.a
/usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.1
/usr/lib/x86_64-linux-gnu/libnvvm.so
/usr/lib/x86_64-linux-gnu/libnvinfer.a
/usr/lib/x86_64-linux-gnu/libnvvm.so.3
/usr/lib/x86_64-linux-gnu/libnvToolsExt.so.1
/usr/lib/x86_64-linux-gnu/libnvrtc.so.7.5
/usr/lib/x86_64-linux-gnu/libnvparsers.a
/usr/lib/x86_64-linux-gnu/libnvblas.so.7.5
/usr/lib/x86_64-linux-gnu/libnvToolsExt.so.1.0.0
/usr/lib/x86_64-linux-gnu/libnvcaffe_parser.so.4.1.2
/usr/lib/x86_64-linux-gnu/libnvinfer_plugin.so
/usr/lib/x86_64-linux-gnu/libnvrtc-builtins.so
/usr/lib/x86_64-linux-gnu/libnvparsers.so
/usr/lib/x86_64-linux-gnu/libnvrtc-builtins.so.7.5.18
/usr/lib/x86_64-linux-gnu/libnvblas.so.7.5.18
/usr/lib/x86_64-linux-gnu/libnvvm.so.3.0.0
/usr/lib/x86_64-linux-gnu/libnvrtc.so
/usr/lib/x86_64-linux-gnu/libnvrtc-builtins.so.7.5
/usr/lib/x86_64-linux-gnu/libnvinfer.so.4.1.2
/usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.390.30
/usr/lib/x86_64-linux-gnu/libnvrtc.so.7.5.17
/usr/lib/x86_64-linux-gnu/libnvblas.so
/usr/lib/x86_64-linux-gnu/libnvinfer.so.4
/usr/lib/x86_64-linux-gnu/libnvparsers.so.4
/usr/lib/x86_64-linux-gnu/libnvinfer_plugin.so.4.1.2
/usr/lib/x86_64-linux-gnu/libnvcaffe_parser.so.4

編譯

將 /usr/src/tensorrt 文件夾拷貝到用戶目錄下,假設路徑爲 <tensorrt_srcpath> 。

第一個問題:

在 <tensorrt_srcpath>/tensorrt/samples 文件夾中有個 Makefile.config 文件,裏面第4行:

1
CUDA_VER?=cuda- $(shell dpkg-query -f '$${version}\n' -W 'cuda-cudart-[0-9]*' | cut -d . -f 1,2 | sort -n | tail -n 1)

這一句是爲了獲取cuda版本的,個人機器是 CUDA 8.0 。我記得我第一次安裝時,後面dpkg命令 輸出的不是8.0,是一個很奇怪的數字,致使我不能編譯 tensorRT 例程。 後來我直接在這句後面添加了一句: CUDA_VER=cuda-8.0 ,簡單粗暴解決問題了。

這個問題好像是仍是由於我以前安裝 cuda 時是用 runfile 的方式安裝的,用這種方式安裝的cuda不會安裝cuda的deb包,因此上面語句輸出的是不對的,致使找不到cuda庫目錄,編譯不能進行。

可使用命令sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64.deb ,安裝deb包,就能夠了。或者像我那樣添加 CUDA_VER=cuda-8.0 也能夠。

若是安裝cuda就是使用deb包安裝的話,就不會出現這個問題。

第二個問題:

若是機器上安裝了多個cuda版本,像我這個機器上 cuda8.0,9.0,9.1都裝上了,上面語句獲得的就只是 CUDA_VER=9.1,若是安裝的是其餘版本cuda的TensorRT的話確定是不對的。

能夠直接在第4行下面添加:

1
CUDA_INSTALL_DIR=/usr/local/cuda-9.0

3 TensorRT 使用流程

這是個很簡單的流程,先簡單瞭解一下,之後會深刻研究更高級的用法。

在使用tensorRT的過程當中須要提供如下文件(以caffe爲例):

  1. A network architecture file (deploy.prototxt), 模型文件
  2. Trained weights (net.caffemodel), 權值文件
  3. A label file to provide a name for each output class. 標籤文件

前兩個是爲了解析模型時使用,最後一個是推理輸出時將數字映射爲有意義的文字標籤。

tensorRT的使用包括兩個階段, build and deployment:

  • build:Import and optimize trained models to generate inference engines

pasted-image-0-5-625x140

build階段主要完成模型轉換(從caffe或TensorFlow到TensorRT),在模型轉換時會完成前述優化過程當中的層間融合,精度校準。這一步的輸出是一個針對特定GPU平臺和網絡模型的優化過的TensorRT模型,這個TensorRT模型能夠序列化存儲到磁盤或內存中。存儲到磁盤中的文件稱之爲 plan file。

下面代碼是一個簡單的build過程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//建立一個builder
IBuilder* builder = createInferBuilder(gLogger);
 
// parse the caffe model to populate the network, then set the outputs
// 建立一個network對象,不過這時network對象只是一個空架子
INetworkDefinition* network = builder->createNetwork();
 
//tensorRT提供一個高級別的API:CaffeParser,用於解析Caffe模型
//parser.parse函數接受的參數就是上面提到的文件,和network對象
//這一步以後network對象裏面的參數才被填充,才具備實際的意義
CaffeParser parser;
auto blob_name_to_tensor = parser.parse(「deploy.prototxt」,
trained_file.c_str(),
*network,
DataType::kFLOAT);
 
// 標記輸出 tensors
// specify which tensors are outputs
network->markOutput(*blob_name_to_tensor->find( "prob"));
 
// Build the engine
// 設置batchsize和工做空間,而後建立inference engine
builder->setMaxBatchSize( 1);
builder->setMaxWorkspaceSize( 1 << 30);
//調用buildCudaEngine時纔會進行前述的層間融合或精度校準優化方式
ICudaEngine* engine = builder->buildCudaEngine(*network);

上面的過程使用了一個高級別的API:CaffeParser,直接讀取 caffe的模型文件,就能夠解析,也就是填充network對象。解析的過程也能夠直接使用一些低級別的C++API,好比:

1
2
ITensor* in = network->addInput(「input」, DataType::kFloat, Dims3{…});
IPoolingLayer* pool = network->addPooling(in, PoolingType::kMAX, …);

解析caffe模型以後,必需要指定輸出tensor,設置batchsize,和設置工做空間。設置batchsize就跟使用caffe測試是同樣的,設置工做空間是進行前述層間融合和張量融合的必要措施。層間融合和張量融合的過程是在調用builder->buildCudaEngine時才進行的。

  • deploy:Generate runtime inference engine for inference

pasted-image-0-6-625x129

deploy階段主要完成推理過程,Kernel Auto-Tuning 和 Dynamic Tensor Memory 應該是在這裏完成的。將上面一個步驟中的plan文件首先反序列化,並建立一個 runtime engine,而後就能夠輸入數據(好比測試集或數據集以外的圖片),而後輸出分類向量結果或檢測結果。

tensorRT的好處就是不須要安裝其餘深度學習框架,就能夠實現部署和推理。

如下是一個簡單的deploy代碼:這裏面沒有包含反序列化過程和測試時的batch流獲取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// The execution context is responsible for launching the
// compute kernels 建立上下文環境 context,用於啓動kernel
IExecutionContext *context = engine->createExecutionContext();
 
// In order to bind the buffers, we need to know the names of the
// input and output tensors. //獲取輸入,輸出tensor索引
int inputIndex = engine->getBindingIndex(INPUT_LAYER_NAME),
int outputIndex = engine->getBindingIndex(OUTPUT_LAYER_NAME);
 
//申請GPU顯存
// Allocate GPU memory for Input / Output data
void* buffers = malloc(engine->getNbBindings() * sizeof(void*));
cudaMalloc(&buffers[inputIndex], batchSize * size_of_single_input);
cudaMalloc(&buffers[outputIndex], batchSize * size_of_single_output);
 
//使用cuda 流來管理並行計算
// Use CUDA streams to manage the concurrency of copying and executing
cudaStream_t stream;
cudaStreamCreate(&stream);
 
//從內存到顯存,input是讀入內存中的數據;buffers[inputIndex]是顯存上的存儲區域,用於存放輸入數據
// Copy Input Data to the GPU
cudaMemcpyAsync(buffers[inputIndex], input,
batchSize * size_of_single_input,
cudaMemcpyHostToDevice, stream);
 
//啓動cuda覈計算
// Launch an instance of the GIE compute kernel
context.enqueue(batchSize, buffers, stream, nullptr);
 
//從顯存到內存,buffers[outputIndex]是顯存中的存儲區,存放模型輸出;output是內存中的數據
// Copy Output Data to the Host
cudaMemcpyAsync(output, buffers[outputIndex],
batchSize * size_of_single_output,
cudaMemcpyDeviceToHost, stream));
 
//若是使用了多個cuda流,須要同步
// It is possible to have multiple instances of the code above
// in flight on the GPU in different streams.
// The host can then sync on a given stream and use the results
cudaStreamSynchronize(stream);

可見使用了挺多的CUDA 編程,因此要想用好tensorRT仍是要熟練 GPU編程。

4 Performance Results

來看一看使用以上優化方式以後,能得到怎樣的加速效果:

pasted-image-0-2-1024x1007

可見使用tensorRT與使用CPU相比,得到了40倍的加速,與使用TensorFlow在GPU上推理相比,得到了18倍的加速。效果仍是很明顯的。

如下兩圖,是使用了INT8低精度模式進行推理的結果展現:包括精度和速度。

來自:GTC 2017,Szymon Migacz 的PPT

1517974926920

1517974951882

可見精度損失不多,速度提升不少。

上面仍是17年 TensorRT2.1的性能,這裏 是一個最新的TensorRT4.0.1的性能表現,有很詳細的數據展現來講明TensorRT在inference時的強勁性能。

後面的博客中會進一步學習 tensorRT,包括官方例程和作一些實用的優化。

參考資料

    1. What’s the Difference Between Deep Learning Training and Inference?
    2. Discover the Difference Between Deep Learning Training and Inference
    3. GTC 2017,Szymon Migacz 的PPT
    4. NVIDIA TensorRT | NVIDIA Developer
    5. Deploying Deep Neural Networks with NVIDIA TensorRT
    6. TensorRT 3: Faster TensorFlow Inference and Volta Support
    7. tensorRT installation guide
    8. cuda installation guide
    9. NVIDIA TensorRT Performance Guide
    10. TensorRT 4 Accelerates Neural Machine Translation, Recommenders, and Speech
    11. ONNX
相關文章
相關標籤/搜索