该部分列出了常用的trtexec命令行标志。
2.1.1 构建阶段的标志 --onnx=<model> :指定输入 ONNX 模型。--deploy=<caffe_prototxt> :指定输入的 Caffe prototxt 模型。--uff=<model> :指定输入 UFF 模型。--output=<tensor> :指定输出张量名称。仅当输入模型为 UFF 或 Caffe 格式时才需要。--maxBatch=<BS> :指定构建引擎的最大批量大小。仅当输入模型为 UFF 或 Caffe 格式时才需要。如果输入模型是 ONNX 格式,请使用--minShapes 、 --optShapes 、 --maxShapes标志来控制输入形状的范围,包括批量大小。--minShapes=<shapes> , --optShapes=<shapes> , --maxShapes=<shapes> :指定用于构建引擎的输入形状的范围。仅当输入模型为 ONNX 格式时才需要。--workspace=<size in MB>:指定策略允许使用的最大工作空间大小。该标志已被弃用。您可以改用--memPoolSize=<pool_spec>标志。--memPoolSize=<pool_spec> :指定策略允许使用的工作空间的最大大小,以及 DLA 将分配的每个可加载的内存池的大小。--saveEngine=<file> :指定保存引擎的路径。--fp16 、 --int8 、 --noTF32 、 --best :指定网络级精度。--sparsity=[disable|enable|force] :指定是否使用支持结构化稀疏的策略。
disable :使用结构化稀疏禁用所有策略。这是默认设置。
enable :使用结构化稀疏启用策略。只有当 ONNX 文件中的权重满足结构化稀疏性的要求时,才会使用策略。
force :使用结构化稀疏启用策略,并允许 trtexec 覆盖 ONNX 文件中的权重,以强制它们具有结构化稀疏模式。请注意,不会保留准确性,因此这只是为了获得推理性能。
--timingCacheFile=<file> :指定要从中加载和保存的时序缓存。--verbose :打开详细日志记录。--buildOnly :在不运行推理的情况下构建并保存引擎。--profilingVerbosity=[layer_names_only|detailed|none]:指定用于构建引擎的分析详细程度。--dumpLayerInfo , --exportLayerInfo=<file>:打印/保存引擎的层信息。--precisionConstraints=spec :控制精度约束设置。
none :没有限制。
prefer :如果可能,满足--layerPrecisions / --layerOutputTypes设置的精度约束。
obey:满足由--layerPrecisions / --layerOutputTypes设置的精度约束,否则失败。
--layerPrecisions=spec :控制每层精度约束。仅当PrecisionConstraints设置为服从或首选时才有效。规范是从左到右阅读的,后面的会覆盖前面的。 “ _ ”可以用作layerName来指定所有未指定层的默认精度。 例如: `—layerPrecisions=_:fp16,layer_1:fp32将所有层的精度设置为FP16,除了layer_1将设置为FP32。—layerOutputTypes=spec:控制每层输出类型约束。仅当PrecisionConstraints设置为服从或首选时才有效。规范是从左到右阅读的,后面的会覆盖前面的。 “ * ”可以用作layerName来指定所有未指定层的默认精度。如果一个层有多个输出,则可以为该层提供用“ + ”分隔的多种类型。
例如:—layerOutputTypes=*:fp16,layer_1:fp32+fp16将所有层输出的精度设置为FP16,但 layer_1除外,其第一个输出将设置为FP32,其第二个输出将设置为FP16`。
2.1.2 推理阶段的标志 --loadEngine=<file> :从序列化计划文件加载引擎,而不是从输入 ONNX、UFF 或 Caffe 模型构建引擎。--batch=<N> :指定运行推理的批次大小。仅当输入模型为 UFF 或 Caffe 格式时才需要。如果输入模型是 ONNX 格式,或者引擎是使用显式批量维度构建的,请改用—shapes 。--shapes=<shapes> :指定要运行推理的输入形状。--warmUp=<duration in ms> , --duration=<duration in seconds> , --iterations=<N> : 指定预热运行的最短持续时间、推理运行的最短持续时间和推理运行的迭代。例如,设置--warmUp=0 --duration=0 --iterations允许用户准确控制运行推理的迭代次数。--useCudaGraph :将推理捕获到 CUDA 图并通过启动图来运行推理。当构建的 TensorRT 引擎包含 CUDA 图捕获模式下不允许的操作时,可以忽略此参数。--noDataTransfers :关闭主机到设备和设备到主机的数据传输。--streams=<N> :并行运行多个流的推理。--verbose :打开详细日志记录。--dumpProfile, --exportProfile=<file> :打印/保存每层性能配置文件。
有关所有受支持的标志和详细说明,请参阅trtexec --help 。
cmake -B build
cd build
如果已安装的tensorRT库未添加环境变量,上述编译过程会报错,提示找不到文件,我们可以直接在CMakeLists.txt文件中指定TensorRT库路径,如下图所示 另外,官方提供的cmakelists默认编译parser,plugin,还有sample。自定义算子不需要编译sample,可以将它关闭了。
option(BUILD_PLUGINS "Build TensorRT plugin" ON)
option(BUILD_PARSERS "Build TensorRT parsers" ON)
option(BUILD_SAMPLES "Build TensorRT samples" OFF)
导出结果如下图:
out文件夹存储了编译后的各种链接库,将其复制到tensorRT/lib目录下,替换原本的链接库文件。 进行到这一步已经可以了,我们可以看到TensorRT本质编译过后就是动态链接库的.so的形式。
2.2.2 常用的plugin插件 随着tensorRT的不断发展(v5->v6->v7),TensorRT的插件的使用方式也在不断更新。插件接口也在不断地变化,由v5版本的IPluginV2Ext,到v6版本的IPluginV2IOExt和IPluginV2DynamicExt。未来不知道会不会出来新的API,不过这也不是咱要考虑的问题,因为TensorRT的后兼容性做的很好,根本不用担心你写的旧版本插件在新版本上无法运行。
TensorRT插件的存在目的,主要是为了让我们实现TensorRT目前还不支持的算子 ,毕竟众口难调嘛,我们在转换过程中肯定会有op不支持的情况。这个时候就需要使用TensorRT的plugin去实现我们的自己的op。此时我们需要通过TensorRT提供的接口去实现自己的op,因此这个plugin的生命周期也需要遵循TensorRT的规则 。我们常用的plugin,主要有两个plugin插件,即TensorRT的官方plugin 库 以及open-mmlab的plugin 插件库。 官方提供的插件已经相当多,而且TensorRT开源了plugin部分。并且可以看到其源码,通过模仿源码来学习plugin是如何写的。
2.2.3 添加自己的算子 如果要添加自己的算子,可以在官方的plugin库里头进行修改添加,然后编译官方的plugin库。将生成的libnvinfer_plugin.so.7替换原本的.so文件即可。或者自己写一个类似于官方plugin的组件,将名称替换一下,同样生成.so,在TensorRT的推理项目中引用这个动态链接库即可。有兴趣的可以先看看TensorRT的官方文档 。下面我们将整个流程分为几个步骤。
打开TRT源代码仓库
复制LeakyReluPlugin文件将其改成CustomPlugin,里面的头文件还有cpp文件统统改为自己想要的名字,顺便把代码里面的类型名也改了,见下图。
为了后续方便注册,自定义插件Custom类需要继承nvinfer1::IPluginV2DynamicExt接口,另外需要增加一些重写方法和属性(插件类继承IPluginV2DynamicExt才可以支持动态尺寸,其他插件类接口例如IPluginV2IOExt和前者大部分是相似的。)
CustomPlugin,继承IPluginV2DynamicExt,是插件类,用于写插件具体的实现
CustomPluginCreator,继承BaseCreator,是插件工厂类,用于根据需求创建该插件 下面是对应的cpp实现
void Custom::setPluginNamespace(const char* pluginNamespace) noexcept
mPluginNamespace = pluginNamespace;
const char* Custom::getPluginNamespace() const noexcept
return mPluginNamespace.c_str();
nvinfer1::DataType Custom::getOutputDataType(
int index, const nvinfer1::DataType* inputTypes, int nbInputs) const noexcept
ASSERT(inputTypes && nbInputs > 0 && index == 0);
return inputTypes[0];
// Attach the plugin object to an execution context and grant the plugin the access to some context resource.
void Custom::attachToContext(
cudnnContext* cudnnContext, cublasContext* cublasContext, IGpuAllocator* gpuAllocator) noexcept
// Detach the plugin object from its execution context.
void Custom::detachFromContext() noexcept {}
void Custom::configurePlugin(const nvinfer1::DynamicPluginTensorDesc* in, int nbInputs,
const nvinfer1::DynamicPluginTensorDesc* out, int nbOutputs) noexcept
// Not support dynamic shape in C dimension
ASSERT(nbInputs == 1 && in[0].desc.dims.d[1] != -1);
其他需要实现的方法参考IReluPlugin
另外还需要写一个创建CustomPluginCreator插件的类
class CustomPluginCreator : public BaseCreator
public:
CustomPluginCreator();
~CustomPluginCreator() override = default;
const char* getPluginName() const noexcept override;
const char* getPluginVersion() const noexcept override;
const PluginFieldCollection* getFieldNames() noexcept override;
IPluginV2DynamicExt* createPlugin(const char* name, const PluginFieldCollection* fc) noexcept override;
IPluginV2DynamicExt* deserializePlugin(const char* name, const void* serialData, size_t serialLength) noexcept override;
private:
static PluginFieldCollection mFC;
static std::vector<PluginField> mPluginAttributes;
方法实现参考IReluPlugin。详细的对每个代码的解释可以参照TensorRT自定义插件(plugin)开发(详细)
2.2.4 注册plugin 首先在inferplugin.cpp文件中添加初始化插件的接口,在加载NvInferRuntimeCommon.h头文件的时候会得到一个getPluginRegistry,这里类中包含了所有已经注册了的IPluginCreator,在使用的时候我们通过getPluginCreator函数得到相应的IPluginCreator 其次在cmake文件中添加编译Custom插件的选项 最后需要实现onnx结点和TRT插件的映射关系,改动如下: 回到TRT源代码主目录,使用如下命令编译
cmake -B build
cd build
提示如下即代表编译成功 然后将out文件夹下的库复制到TRT安装目录lib文件夹里。 最后使用官方工具trtexec进行编译,编译成功。
https://blog.csdn.net/HW140701/article/details/120360642
https://developer.nvidia.com/zh-cn/blog/tensorrt-trtexec-cn/
https://zhuanlan.zhihu.com/p/492144628
https://github.com/NVIDIA/TensorRT/tree/master/plugin
https://blog.csdn.net/bluebelfast/article/details/125073598
https://github.com/open-mmlab/mmdeploy/tree/master/csrc/mmdeploy
深度学习 CUDA加速 tensorrt
原创文章 作者:敢敢のwings。如若转载,请注明出处:古月居
http://www.guyuehome.com/43437
中国大陆 中国香港 中国澳门 中国台湾 马来西亚 印度尼西亚 菲律宾 新加坡 泰国 日本 韩国 塔吉克斯坦 哈萨克斯坦 越南 土耳其 印度 巴基斯坦 阿富汗 斯里兰卡 缅甸 伊朗 亚美尼亚 东帝汶 文莱 朝鲜 柬埔寨 老挝 孟加拉国 马尔代夫 黎巴嫩 约旦 叙利亚 伊拉克 科威特 沙特阿拉伯 也门 阿曼 巴勒斯坦 阿联酋 以色列 巴林 卡塔尔 不丹 蒙古 尼泊尔 土库曼斯坦 阿塞拜疆 乔治亚 吉尔吉斯斯坦 乌兹别克斯坦 英国 德国 意大利 法国 俄罗斯 希腊 荷兰 比利时 西班牙 匈牙利 罗马尼亚 瑞士 奥地利 丹麦 瑞典 挪威 波兰 圣马力诺 匈牙利 南斯拉夫 直布罗陀 葡萄牙 卢森堡 爱尔兰 冰岛 阿尔巴尼亚 马耳他 塞浦路斯 芬兰 保加利亚 立陶宛 拉脱维亚 爱沙尼亚 摩尔多瓦 安道尔共和国 乌克兰 南斯拉夫 克罗地亚 斯洛文尼亚 波黑 马其顿 梵蒂冈 捷克 斯洛伐克 列支敦士登 秘鲁 墨西哥 古巴 阿根廷 巴西 智利 哥伦比亚 委内瑞拉 福克兰群岛 伯利兹 危地马拉 萨尔瓦多 洪都拉斯 尼加拉瓜 哥斯达黎加 巴拿马 圣彼埃尔 海地 瓜德罗普 玻利维亚 圭亚那 厄瓜多尔 法属圭亚那 巴拉圭 马提尼克 苏里南 乌拉圭 埃及 南非 摩洛哥 阿尔及利亚 突尼斯 利比亚 冈比亚 塞内加尔 毛里塔尼亚 马里 几内亚 科特迪瓦 布基拉法索 尼日尔 多哥 贝宁 毛里求斯 利比里亚 塞拉利昂 加纳 尼日利亚 乍得 中非 喀麦隆 佛得角 圣多美 普林西比 赤道几内亚 加蓬 刚果 扎伊尔 安哥拉 几内亚比绍 阿森松 塞舌尔 苏丹 卢旺达 埃塞俄比亚 索马里 吉布提 肯尼亚 坦桑尼亚 乌干达 布隆迪 莫桑比克 赞比亚 马达加斯加 留尼旺岛 津巴布韦 纳米比亚 马拉维 莱索托 博茨瓦纳 斯威士兰 科摩罗 圣赫勒拿 厄立特里亚 阿鲁巴岛 法罗群岛 摩纳哥 澳大利亚 新西兰 关岛 瑙鲁 汤加 所罗门群岛 瓦努阿图 斐济 科克群岛 纽埃岛 东萨摩亚 西萨摩亚 基里巴斯 图瓦卢 科科斯岛 诺福克岛 圣诞岛 美国 加拿大 夏威夷 阿拉斯加 格陵兰岛 中途岛 威克岛 维尔京群岛 波多黎各 巴哈马 安圭拉岛 圣卢西亚 巴巴多斯 牙买加 南极洲
中国大陆 中国香港 中国澳门 中国台湾 马来西亚 印度尼西亚 菲律宾 新加坡 泰国 日本 韩国 塔吉克斯坦 哈萨克斯坦 越南 土耳其 印度 巴基斯坦 阿富汗 斯里兰卡 缅甸 伊朗 亚美尼亚 东帝汶 文莱 朝鲜 柬埔寨 老挝 孟加拉国 马尔代夫 黎巴嫩 约旦 叙利亚 伊拉克 科威特 沙特阿拉伯 也门 阿曼 巴勒斯坦 阿联酋 以色列 巴林 卡塔尔 不丹 蒙古 尼泊尔 土库曼斯坦 阿塞拜疆 乔治亚 吉尔吉斯斯坦 乌兹别克斯坦 英国 德国 意大利 法国 俄罗斯 希腊 荷兰 比利时 西班牙 匈牙利 罗马尼亚 瑞士 奥地利 丹麦 瑞典 挪威 波兰 圣马力诺 匈牙利 南斯拉夫 直布罗陀 葡萄牙 卢森堡 爱尔兰 冰岛 阿尔巴尼亚 马耳他 塞浦路斯 芬兰 保加利亚 立陶宛 拉脱维亚 爱沙尼亚 摩尔多瓦 安道尔共和国 乌克兰 南斯拉夫 克罗地亚 斯洛文尼亚 波黑 马其顿 梵蒂冈 捷克 斯洛伐克 列支敦士登 秘鲁 墨西哥 古巴 阿根廷 巴西 智利 哥伦比亚 委内瑞拉 福克兰群岛 伯利兹 危地马拉 萨尔瓦多 洪都拉斯 尼加拉瓜 哥斯达黎加 巴拿马 圣彼埃尔 海地 瓜德罗普 玻利维亚 圭亚那 厄瓜多尔 法属圭亚那 巴拉圭 马提尼克 苏里南 乌拉圭 埃及 南非 摩洛哥 阿尔及利亚 突尼斯 利比亚 冈比亚 塞内加尔 毛里塔尼亚 马里 几内亚 科特迪瓦 布基拉法索 尼日尔 多哥 贝宁 毛里求斯 利比里亚 塞拉利昂 加纳 尼日利亚 乍得 中非 喀麦隆 佛得角 圣多美 普林西比 赤道几内亚 加蓬 刚果 扎伊尔 安哥拉 几内亚比绍 阿森松 塞舌尔 苏丹 卢旺达 埃塞俄比亚 索马里 吉布提 肯尼亚 坦桑尼亚 乌干达 布隆迪 莫桑比克 赞比亚 马达加斯加 留尼旺岛 津巴布韦 纳米比亚 马拉维 莱索托 博茨瓦纳 斯威士兰 科摩罗 圣赫勒拿 厄立特里亚 阿鲁巴岛 法罗群岛 摩纳哥 澳大利亚 新西兰 关岛 瑙鲁 汤加 所罗门群岛 瓦努阿图 斐济 科克群岛 纽埃岛 东萨摩亚 西萨摩亚 基里巴斯 图瓦卢 科科斯岛 诺福克岛 圣诞岛 美国 加拿大 夏威夷 阿拉斯加 格陵兰岛 中途岛 威克岛 维尔京群岛 波多黎各 巴哈马 安圭拉岛 圣卢西亚 巴巴多斯 牙买加 南极洲