TensorRT 介紹與安裝教學

李謦伊
謦伊的閱讀筆記
10 min readDec 15, 2020

TensorRT 是 Nvidia 提出的深度學習推論平台,能夠在 GPU 上實現低延遲、高吞吐量的部屬。基於 TensorRT 的推論運行速度會比僅使用 CPU 快40倍,提供精度 INT8 和 FP16 優化,支援 TensorFlow、Caffe、Mxnet、Pytorch 等深度學習框架,其中 Mxnet、Pytorch 需先轉換為 ONNX 格式

📚 何謂延遲、吞吐量

  • 延遲 (Latency): 指執行一個操作所需要花費的時間
  • 吞吐量 (Throughput): 在單位時間內,可執行運算的次數
NVIDIA TensorRT

TensorRT API

TensorRT 函式庫以 C++撰寫,提供 C++ 和 Python API,這邊介紹 7.1.3 TensorRT API

📝 7.1.3 TensorRT API 官方文件: https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-713/developer-guide/index.html#c_topics

📝 其他版本 TensorRT API官方文件: https://docs.nvidia.com/deeplearning/tensorrt/archives/index.html

🔹 API 使用流程

  • 創造一個全局對象 ILogger,很多的 TensorRT API 需要輸入這個參數
  • 將網路定義至 TensorRT,首先要創建 builder 及 network,TensorRT 7.0.0 之後都是使用 createNetworkV2 的 API

定義網路的方式有兩種:

→ 使用 API 創建網路,可參考: https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-713/developer-guide/index.html#create_network_python

→ Parser API 導入網路模型 (支援 ONNX, UFF, Caffe),流程有三步驟:

🔖 創建 TensorRT builder 跟 network

🔖 根據模型格式 ( ONNX, UFF, Caffe) 創建 TensorRT parser

🔖 解析導入的模型

📚 在 C++ API 中會需要使用到 using namespace nvinfer1;

NvInfer.h 等 header 檔位於 jetson nano /usr/include/aarch64-linux-gnu/、本機 /usr/include/x86_64-linux-gnu

TensorRT Nv header: https://github.com/NVIDIA/TensorRT/tree/master/include

  • 建立 Engine 進行優化

調用 TensorRT builder 對於推論進行優化。在建立 engine 時,會搜索其 CUDA 空間進行分配,以獲取最佳的效能

在建立 Engine 會使用到 IBuilderConfig,其擁有很多屬性,可以用這些屬性控制量化精度以及自動調整參數等,其中有兩個重要的屬性為 maximum batch sizemaximum workspace size:

🔖 setMaxBatchSize 表示 TensorRT 進行優化的最大 batch size

🔖 setMaxWorkspaceSize 表示網路中的任一層能夠使用的最大空間

# Python 用法
builder.create_builder_config()
// C++ 用法
IBuilderConfig* config = builder->createBuilderConfig();

因為 IBuilderConfig 需要為網路中的每個層搜索其使用的內核,因此建立 Engine 較花費時間。在 C++ API 中可以通過 setFlag 設定,將具有相同輸入輸出的張量 (tensor) 跳過分析,將緩存的結果重複使用於這些層

// C++ 用法
config->setFlag(BuilderFlag::kDISABLE_TIMING_CACHE);
  • Serialize, Deserialize

在進行推論時,可以直接使用 engine 預測,也可以使用 serialize, deserialize

Serialize 就是指將 engine 存成 trt 檔,之後在推論時,再 deserialize 還原回 engine 做預測。由於創建 engine 需要花費較多時間,這樣的方式可以避免每次重新預測時,都要去建構 engine 的過程,進而加快推論速度

❗️ Serialize, Deserialize 不能跨平台或是 TensorRT 版本移植

  • Inference

通常 TensorRT 是異步 (asynchronous),因此將 kernel 加入 queue 放到 CUDA stream 計算流

# Python 用法
# 異步 (asynchronous)
context.execute_async(bindings=[int(d_input), int(d_output)], stream_handle=stream.handle)
# 同步 (synchronous)
context.execute(bindings=[int(d_input), int(d_output)])
// C++ 用法
// 異步 (asynchronous)
context->enqueue(buffers, stream, nullptr);
// 同步 (synchronous)
context->execute(buffers);

TensorRT Install

我的作業系統使用 Ubuntu 18.04.5 LTS,環境為 CUDA 10.2, cuDNN 7.6.5, python 3.7.9

TensorRT 有四種安裝方式: 使用 Debian, RPM, Tar, Zip 檔案,其中 Zip 檔案只支援 Windows

可以參考官方的安裝流程: https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-713/install-guide/index.html

依照 CUDA, cuDNN版本下載需要的 TensorRT,這裡使用TensorRT 7.1.3 版本的 Debian

TensorRT 下載網址: https://developer.nvidia.com/zh-cn/tensorrt,下載前需要先註冊 NVIDIA 會員

# 要記得換成剛下載的 deb 安裝包
$ sudo dpkg -i nv-tensorrt-repo-ubuntu1804-cuda10.2-trt7.1.3.4-ga-20200617_1–1_amd64.deb
$ sudo apt-key add /var/nv-tensorrt-repo-cuda10.2-trt7.1.3.4-ga-20200617/7fa2af80.pub# 安裝 tensorrt
$ sudo apt-get update
$ sudo apt-get install tensorrt# 下載 tensorrt 依賴包
$ sudo apt-get install python3-libnvinfer-dev
驗證安裝
$ dpkg -l | grep TensorRT

看到以下輸出內容代表安裝成功

❗️ 如果要在 TensorFlow中用 TensorRT

$ sudo apt-get install uff-converter-tf

❓ anaconda 中找不到 TensorRT → No module named tensorrt

💬 因為剛剛安裝 TensorRT 是安裝到系統裡的 python,因此需要把 tensorrt 安裝到 anaconda 中的 python 環境

下載 TensorRT-7.1.3.4.Ubuntu-18.04.x86_64-gnu.cuda-10.2.cudnn8.0.tar.gz

$ tar -xzvf TensorRT-7.1.3.4.Ubuntu-18.04.x86_64-gnu.cuda-10.2.cudnn8.0.tar.gz$ cd TensorRT-7.1.3.4/python

下載跟 python 版本一樣的 whl

$ pip install install tensorrt-7.1.3.4-cp37-none-linux_x86_64.whl

使用 python3 查看

TensorRT sample

📝 TensorRT 官方範例: https://docs.nvidia.com/deeplearning/tensorrt/sample-support-guide/index.html

$ export CUDA_INSTALL_DIR=”/usr/local/cuda”$ export CUDNN_INSTALL_DIR=”/usr/local/cuda”
  • 安裝依賴包
$ sudo apt-get install libtiff5-dev libjpeg8-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev libharfbuzz-dev libfribidi-dev$ pip3 install Pillow$ cd /usr/src/tensorrt/samples
  • MNIST C++ 範例

https://github.com/NVIDIA/TensorRT/blob/master/samples/opensource/sampleMNIST/README.md

cd sampleMNISTsudo make

編譯完的檔案會放在 /usr/src/tensorrt/bin/

  • 下載資料
$ cd ../../data/mnist$ sudo python3 download_pgms.py

會在 /usr/src/tensorrt/data/mnist 下看到 0.pgm~9.pgm

❗️ 使用 Anaconda 可能出現以下情形

💬 修改 /usr/src/tensorrt/data/mnist/download_pgms.py

將使用的 python 改為 conda 環境裡的 python

$ sudo nano download_pgms.py

改完後會呈現下圖樣子

然後下載資料,會在 /usr/src/tensorrt/data/mnist 下看到 0.pgm~9.pgm

$ sudo ./download_pgms.py# 執行$ cd ../../bin$ ./sample_mnist

📌 若要將 ONNX 或 TensorFlow 轉換成 TensorRT,可參考: NVIDIA Jetson Nano — 04 使用 TensorRT 將模型最佳化

--

--