TensorRT 是 Nvidia 提出的深度學習推論平台,能夠在 GPU 上實現低延遲、高吞吐量的部屬。基於 TensorRT 的推論運行速度會比僅使用 CPU 快40倍,提供精度 INT8 和 FP16 優化,支援 TensorFlow、Caffe、Mxnet、Pytorch 等深度學習框架,其中 Mxnet、Pytorch 需先轉換為 ONNX 格式
📚 何謂延遲、吞吐量
- 延遲 (Latency): 指執行一個操作所需要花費的時間
- 吞吐量 (Throughput): 在單位時間內,可執行運算的次數
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 size 與 maximum 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 將模型最佳化