1. 程式人生 > >實現TensorRT-7.0外掛自由!(如果不踩坑使用TensorRT外掛功能)

實現TensorRT-7.0外掛自由!(如果不踩坑使用TensorRT外掛功能)

本系列為新TensorRT的第一篇,為什麼叫新,因為之前已經寫了兩篇關於TensorRT的文章,是關於TensorRT-5.0版本的。好久沒寫關於TensorRT的文章了,所幸就以**新**來開頭吧~ 接下來將要講解的TensorRT,將會是基於7.0版本。 7版本開頭的TensorRT變化還是挺大的,增加了很多新特性,但是TensorRT的核心運作方式還是沒有什麼變化的,關於TensorRT的介紹可以看之前寫的這兩篇: - [利用TensorRT對深度學習進行加速 ](https://oldpan.me/archives/use-tensorrt-speed-up-deep-learning-1) - [利用TensorRT實現神經網路提速(讀取ONNX模型並執行) ](https://oldpan.me/archives/tensorrt-code-toturial-1) 本文的內容呢,主要是講解: - TensorRT自定義外掛的使用方式 - 如何新增自己的自定義運算元 看完本篇可以讓你**少踩巨多坑**,客官記得常來看啊。 # 前言 隨著tensorRT的不斷髮展(v5->v6->v7),TensorRT的外掛的使用方式也在不斷更新。外掛介面也在不斷地變化,由v5版本的`IPluginV2Ext`,到v6版本的`IPluginV2IOExt`和`IPluginV2DynamicExt`。未來不知道會不會出來新的API,不過這也不是咱要考慮的問題,因為TensorRT的後相容性做的很好,根本不用擔心你寫的舊版本外掛在新版本上無法執行。 目前的plugin-API: ![QQ20201103-101737](https://img2020.cnblogs.com/other/2304365/202102/2304365-20210220233348807-1309897715.png) TensorRT外掛的存在目的,主要是為了讓我們**實現TensorRT目前還不支援的運算元**,畢竟眾口難調嘛,我們在轉換過程中肯定會有*op*不支援的情況。這個時候就需要使用TensorRT的plugin去實現我們的自己的op。此時我們需要通過TensorRT提供的介面去實現自己的op,**因此這個plugin的生命週期也需要遵循TensorRT的規則**。 ## 一個簡單的瞭解 那麼plugin到底長啥樣,可以先看看TensorRT的官方plugin庫長啥樣,截止寫這篇文章時,master分支是7.2版本的plugin: https://github.com/NVIDIA/TensorRT/tree/master/plugin ![tensorrt-plugin](https://img2020.cnblogs.com/other/2304365/202102/2304365-20210220233349191-461444403.jpg) 官方提供的外掛已經相當多,而且TensorRT開源了plugin部分(可以讓我們白嫖!)。並且可以看到其原始碼,通過模仿原始碼來學習plugin是如何寫的。 如果要新增自己的運算元,可以在官方的plugin庫裡頭進行修改新增,然後編譯官方的plugin庫。將生成的`libnvinfer_plugin.so.7`替換原本的`.so`檔案即可。或者自己寫一個類似於官方plugin的元件,將名稱替換一下,同樣生成`.so`,在TensorRT的推理專案中引用這個動態連結庫即可。 以下介紹中,我們需要寫的`IPlugin`簡稱為外掛op。 # 開始寫外掛 有興趣的可以先看看TensorRT的[官方文件](https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html#extending),官方文件的介紹簡單意駭,不過坑是少不了的..而本文的目的,就是儘量讓你少趟坑。 首先按照官方plugin的排布方式,下面隨便挑了個官方plugin: ![instance_normalization_plugin](https://img2020.cnblogs.com/other/2304365/202102/2304365-20210220233349445-2084541208.jpg) 準備一個自己的外掛:`custom.cpp`和`custom.h`,copy並paste官方程式碼,名字替換成自己的。以最新的`IPluginV2DynamicExt`類為介面。 我們需要寫兩個類: - `MyCustomPlugin`,繼承`IPluginV2DynamicExt`,是外掛類,用於寫外掛具體的實現 - `MyCustomPluginCreator`,繼承`BaseCreator`,是外掛工廠類,用於根據需求建立該外掛 對了,外掛類繼承`IPluginV2DynamicExt`才可以支援動態尺寸,其他外掛類介面例如`IPluginV2IOExt`和前者大部分是相似的。 ```c++ // 繼承IPluginV2DynamicExt就夠啦 class MyCustomPlugin final : public nvinfer1::IPluginV2DynamicExt class MyCustomPluginCreator : public BaseCreator ``` # MyCustomPlugin 外掛類 總覽: ```c++ class MyCustomPlugin final : public nvinfer1::IPluginV2DynamicExt { public: MyCustomPlugin( int in_channel, const std