深度學習之 TensorRT

1 簡介

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

在這里插入圖片描述

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

2 優化方式

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的精度。更低的數據精度將會使得內存占用和延遲更低,模型體積更小。

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

PrecisionDynamic 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也是類似的。

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

第一步:

$ 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則安裝如下依賴

$ sudo apt-get install python-libnvinfer-doc

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

如果是python3則安裝如下依賴

$ sudo apt-get install python3-libnvinfer-doc

第三步:

$ sudo apt-get install uff-converter-tf

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

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

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

    上面提示缺少依賴包,但是實際上 libnvinfer4 的包是tensorRT安裝了之后才有的,那現在反而成了依賴包了,不管他,缺什么安裝什么,但是還是出錯,如下:

    在這里插入圖片描述

哇,還是缺少依賴包,這次是缺 cuda-cublas-8-0 ,現在知道了,缺的是cuda的相關組件。

后來把 cuda 的兩個deb包安裝之后就沒問題了,cuda 8.0 的deb包 在這里 ,如下圖,下載紅框里的兩個deb包。

在這里插入圖片描述

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

$ 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 命令檢測是否成功,輸出如下所示即為成功

在這里插入圖片描述

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

可以把 tensorrt 文件夾拷貝到用戶目錄下,方便自己修改測試例程中的代碼。

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

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

/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庫):

/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行:

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行下面添加:

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

在這里插入圖片描述

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

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

//創建一個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,比如:

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

在這里插入圖片描述

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

tensorRT的好處就是不需要安裝其他深度學習框架,就可以實現部署和推理。

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

// 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

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

在這里插入圖片描述

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

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

來自:GTC 2017,Szymon Migacz 的PPT

在這里插入圖片描述

在這里插入圖片描述

可見精度損失很少,速度提高很多。

上面還是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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453757.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453757.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453757.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

H.264筆記

H.264標準寫得比較繁復&#xff0c;所以考慮在瀏覽完Whitepaper之后就開始研讀X264代碼。X264代碼風格還是比較清晰簡潔的。根據對標準得理解&#xff0c;Picture Order Count在Slice解碼的一開始就被提及&#xff1a;I0 B1 B2 P3 B4 B5 P6I0 P3 B1 B2 P6 B4 B5于是I0的POC是0&…

進制轉換中dbho是什么意思_什么是網段?二進制十進制如何互相轉換?看完這篇,你就全明白了...

之前的文章講了ip&#xff0c;子網掩碼&#xff0c;網關的關系&#xff0c;今天著重講一下網段。我們用傻瓜交換機通訊時&#xff0c;一個網段的設備才能互相通訊&#xff0c;怎么能判斷兩個ip是同一個網段呢&#xff1f;今天就簡單的說一下。(這篇文章用語音聽可以起到催眠作用…

【網絡流24題】星際轉移問題(最大流)

【網絡流24題】星際轉移問題&#xff08;最大流&#xff09; 題面 Cogs 題解 因為天數是未知的&#xff0c;所以我們要想辦法處理天數 可以選擇二分或者依次累加天數 因為數據范圍較小&#xff0c;使用二分可能反而復雜度會增高 所以使用不斷累加天數 那么&#xff0c;把所有的…

使用 gunicorn 部署flask項目

1、WSGI協議 Web框架致力于如何生成HTML代碼&#xff0c;而Web服務器用于處理和響應HTTP請求。Web框架和Web服務器之間的通信&#xff0c;需要一套雙方都遵守的接口協議。WSGI協議就是用來統一這兩者的接口的。 2、WSGI容器 常用的WSGI容器有Gunicorn和uWSGI&#xff0c;但G…

軟件需求與問題解決

&#xff08;一&#xff09; 小滿當上項目經理后不久&#xff0c;參與了一個大項目。當時市場簽下來的時候&#xff0c;公司里面是歡天喜地的。項目做了一年多。到了交付的時候&#xff0c;用戶卻很不滿意&#xff0c;當初說好的東西&#xff0c;好多都變了卦。用戶是上帝&…

flex 換主軸后子元素占滿_Chrome72 嵌套 flex 布局修改,你的網站可能會發生布局錯亂...

起源2019 年 1 月 29 日&#xff0c;Chrome72 正式版(72.0.3626.81)發布&#xff0c;本次發布帶來了一個改變&#xff0c;且沒有在更新日志中提及&#xff0c;該改變導致某些網站發生了布局錯亂。該改變主要針對的是嵌套的flex布局&#xff0c;下面我們一起看下是怎么回事。問題…

使用 Django + Wusgi + Nginx 部署 Django

如何在生產上部署Django? Django的部署可以有很多方式&#xff0c;采用 nginxuwsgi 的方式是其中比較常見的一種方式。 uwsgi介紹 uWSGI是一個Web服務器&#xff0c;它實現了WSGI協議、uwsgi、http等協議。Nginx中HttpUwsgiModule的作用是與uWSGI服務器進行交換。 WSGI / …

網絡學習網址

網絡之路博客 http://ccieh3c.com/ 轉載于:https://www.cnblogs.com/changha0/p/8179801.html

路由到另外一個頁面_Nextjs使用解讀一(項目搭建與路由系統)

文章說明&#xff1a;1. 之前想搭建個人博客&#xff0c;由于學習的是react技術棧&#xff0c;所以就到處搜羅資料學了nextjs&#xff0c;配合koa就把博客搭起來了。該系列文章基于我的學習筆記&#xff0c;重新整理了一遍&#xff0c;如果有錯誤之處&#xff0c;還請指正。2. …

微信獲取token -1000

最終翻看微信開發api找到需要去配置IP白名單。只需要配置訪問來源IP即可。 轉載于:https://www.cnblogs.com/yangjinqiang/p/8184663.html

產品技術和管理

為啥純粹為消費者傳遞體驗的活動可以價格不菲&#xff0c;幾為暴利&#xff1f;——談客戶體驗作為客戶價值提升之源 不論產品還是服務&#xff0c;如果能夠為消費者傳遞有益的體驗&#xff0c;其價值就可以在一般的產品服務之上得以體現&#xff1b;附加了體驗的產品&#xff…

Linux 修改系統編碼

linux服務器的字符集設置可能影響到網站頁面出現 “&#xff1f;&#xff1f;&#xff1f;” 等問號亂碼&#xff0c;還有可能導致文件中的漢字部分出現亂碼。有兩個原因 服務器沒有安裝 zh_CN.UTF-8 字符集&#xff0c;導致不支持中文&#xff01;服務器雖然裝了 zh_CN.UTF-8…

jquery ztree 設置勾選_047 JAVA-jQuery

jQuery操作元素屬性的值表單:<body><input type"button" name"" id"but1" value"測試獲得屬性值" /><hr />賬號&#xff1a;<input type"text" name"sxtzh" id"zhanghao" value&q…

Opencv undefined reference to `cv::imread() Ubuntu編譯

Ubuntu下編譯一個C文件&#xff0c;C源程序中使用了opencv&#xff0c;opencv的安裝沒有問題&#xff0c;但是在編譯的過程中出現如下錯誤&#xff1a; undefined reference to cv::imread(std::string const&, int)undefined reference to cv::noArray()undefined referen…

深度學習目標檢測之 YOLO v1

這是繼 RCNN&#xff0c;fast-RCNN 和 faster-RCNN 之后&#xff0c;rbg&#xff08;RossGirshick&#xff09;針對DL目標檢測速度問題提出的另外一種框架。YOLO V1 增強版本GPU中能跑45fps&#xff0c;簡化版本155fps。 論文名&#xff1a; 《You Only Look Once&#xff1a;…

編程珠璣番外篇

1.Plan 9 的八卦 在 Windows 下喜歡用 FTP 的同學抱怨 Linux 下面沒有如 LeapFTP 那樣的方便的工具. 在蘋果下面用慣了 Cyberduck 的同學可能也會抱怨 Linux 下面使用 FTP 和 SFTP 是一件麻煩的事情. 其實一點都不麻煩, 因為在 LINUX 系統上壓根就不需要用 FTP. 為什么呢? 因…

BT下載原理分析

版權聲明&#xff1a;本文為博主原創文章&#xff0c;未經博主允許不得轉載。 BitTorrent協議。 BT全名為BitTorrent,是一個p2p軟件,你在下載download的同時&#xff0c;也在為其他用戶提供上傳upload&#xff0c;因為大家是“互相幫助”&#xff0c;所以不會隨著用戶數的增加而…

表格列求和_excel表格制作,Excel表格的基本操作,包含制作一個表格10方面的知識...

創建表格&#xff0c;插入與刪除一行一列或多行多行&#xff0c;一次移動一行一列或多行多列&#xff0c;拆分與合并單元格&#xff0c;單元格內換行&#xff0c;表格求和與求平均值是Excel表格的基本操作&#xff1b;除此之外&#xff0c;Excel表格的基本操作還包括調整行高列…

深度學習之 FPN (Feature Pyramid Networks)

論文題目&#xff1a;Feature Pyramid Networks for Object Detection論文鏈接&#xff1a;https://arxiv.org/abs/1612.03144論文代碼&#xff1a;Caffe版本 https://github.com/unsky/FPN 《Feature Pyramid Networks for Object Detection》這篇論文主要解決的問題是目標檢…

ISLR—第二章 Statistical Learning

Statistical Learning Y 和X的關系why estimate f 用來預測 預測的時候可以將f^當成一個black box來用&#xff0c;目的主要是預測對應x時候的y而不關系它們之間的關系。用來推斷 推斷的時候&#xff0c;f^不能是一個black box&#xff0c;因為我們想知道predictor和response之…