5.5.tensorRT基础(2)-封装插件过程,并实现更容易的插件开发

news2024/11/27 8:22:43

目录

    • 前言
    • 1. 插件封装
    • 2. 补充知识
    • 总结

前言

杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。

本次课程学习 tensorRT 基础-封装插件过程,并实现更容易的插件开发

课程大纲可看下面的思维导图

在这里插入图片描述

1. 插件封装

这节课我们来学习集成插件,也就是简化插件的实现,因为之前的插件实现起来太过复杂了

相比于之前插件的实现多了两个 onnxplugin.cpp 和 onnxplugin.hpp 文件,这是杜老师实现的关于插件的具体封装,我们只需要实现 easy-plugin.cu 这个文件,整个过程十分简单,我们先 make run 执行一下:

在这里插入图片描述

图1-1 make run出错

博主尝试 debug 调试了一下,先定位到 builtin_op_importers.cpp 文件的 4661 行,即

LOG_INFO("Successfully created plugin: " << pluginName);

// 4661行
auto* layer = ctx->network()->addPluginV2(pluginInputs.data(), pluginInputs.size(), *plugin);

ctx->registerLayer(layer, getNodeName(node));
RETURN_ALL_OUTPUTS(layer);

然后再定位到 onnxplugin.cpp 的 307 行,当返回输出的数量时直接崩了

int TRTPlugin::getNbOutputs() const noexcept{
    return config_->num_output_;
}

调试输出:ERROR: Couldn't get registers: No such process.

博主经过一番折腾,终于发现了是导出的 onnx 存在问题,使用杜老师提供的 onnx 没有问题,使用自己导出的就存在问题,最终发现博主直接使用的上节课程导出的 onnx,这是不行的,因为封装后的插件的 g.op_type() 必须是 Plugin 才行,因此要用本节课程的 gen-onnx.py 产生 onnx,否则就会导致找不到对应的 registers 而失败,执行成功后如下所示:

在这里插入图片描述

在这里插入图片描述

图1-2 make run执行成功

可以发现执行的效果和我们上节课没有封装的效果一样,我们重点关注下杜老师是怎么对插件进行封装的吧

我们回过头来看下代码,easy-plugin.cu 的具体内容如下:


#include "onnx-tensorrt/onnxplugin.hpp"

using namespace ONNXPlugin;

static __device__ float sigmoid(float x){
    return 1 / (1 + expf(-x));
}

static __global__ void MYSELU_kernel_fp32(const float* x, float* output, int edge) {

    int position = threadIdx.x + blockDim.x * blockIdx.x;
	if(position >= edge) return;

    output[position] = x[position] * sigmoid(x[position]);
}

class MYSELU : public TRTPlugin {
public:
	SetupPlugin(MYSELU);

	virtual void config_finish() override{
		printf("\033[33minit MYSELU config: %s\033[0m\n", config_->info_.c_str());
		printf("weights count is %d\n", config_->weights_.size());
	}

	int enqueue(const std::vector<GTensor>& inputs, std::vector<GTensor>& outputs, const std::vector<GTensor>& weights, void* workspace, cudaStream_t stream) override{
		
		int n = inputs[0].count();
		const int nthreads = 512;
		int block_size = n < nthreads ? n : nthreads;
		int grid_size = (n + block_size - 1) / block_size;

		MYSELU_kernel_fp32 <<<grid_size, block_size, 0, stream>>> (inputs[0].ptr<float>(), outputs[0].ptr<float>(), n);
		return 0;
	}
};

RegisterPlugin(MYSELU);

可以发现它就实现了两个函数,一个是 config_finish() 用于打印(非必需),一个是 enqueue() 用于具体推理执行,插件的实现中很多变量都相同,因此可以给定默认值,封装起来。

那接下来我们简单了解下它具体是怎么封装的,首先是 MYSELU 继承自 TRTPlugin,通过 SetupPlugin(MYSELU) 初始化插件,RegisterPlugin(MYSELU) 来注册插件。杜老师在 builtin_op_importers.cpp 中实现了一个通用的 Plugin,那这个通用的 Plugin 可以通过解析 g.op_type() 为 Plugin 的所有插件,这也是为什么 gen-onnx.py 中的 g.op() 第一个参数必须是 Plugin,也解释了博主第一次执行报错的原因。

对于 attribute 属性我们直接用 JSON 文件来控制,解析的时候直接按照 JSON 格式解析就行,这比之前 attribute 解析要方便很多,同时我们也使用了 name_s 字符串属性来表明插件的名字 “MYSELU”,我们可以看下导出的 onnx 长什么样子

在这里插入图片描述

图1-3 demo.onnx

可以看到我们的插件节点就叫做 Plugin,它的名字叫做 MYSELU,它的属性信息全部存储在 info 这个 json 中,这个是我们导出的情况。

接下来我们看它是如何实现的,通过宏定义 RegisterPlugin(MYSELU) 来实现一个通用默认的插件,而 TRTPlugin 继承自 IPluginV2DynamicEtx,也实现了很多默认函数,比如输出类型和输入一致,默认输出数目为 1 等等,如果你的插件不是这样的,你可以直接覆盖它,非常方便,我们对 enqueue 也做了一个封装,我们对序列化和反序列化也做了一个默认实现,因此实际插件的使用只需要实现 enqueue 就能解决绝大部分问题。

更多具体细节内容需要大家自行查看相关代码实现了

2. 补充知识

关于插件的封装,你需要知道:(from 杜老师)

知识点

1. 对插件进行了封装,使用起来更简单

2. 在 onnx-tensorrt 中添加了 onnxplugin.cpp,实现对 IPluginV2DynamicExt 的封装

3. 在 onnx-tensorrt/builtin_op_importers.cpp:5095 行,添加了 Plugin 的解析支持

  • DEFINE_BUILTIN_OP_IMPORTER(Plugin)
  • 使得只要名字是 Plugin 的节点,都可以解释到该函数上
  • 在代码中,为通用插件提供了支持,使得使用者只需要继承简单的插件接口即可完成需求

4. 在 gen-onnx.py 导出时,symbolic 函数返回时,g.op 返回的永远都是 Plugin 这个名字,然后 name_s 指定为自己注册的插件名称,info_s 则传递为 json 字符串,那么复合属性就可以轻易得到支持

封装后的插件实现

1. 导出 onnx 时,按照 gen-onnx.py 在 symbolic 函数返回时,指定 g.op 的 name 为 Plugin

2. 指定 g.op 中 name_s 属性为注册的插件名称,对应后续插件类的类名

3. 指定 g.op 中 info_ 属性为需要读取的复合属性,字符串。通常可以传递 json,使得属性再复制都可以,避免使用官方的方式

4. 创建 easy-plugin.cu 文件,定义自己的类并继承自 ONNXPlugin::TRTPlugin

5. 实现需要的函数:

  • config_finish[非必要]:配置完成函数
  • 当插件配置完毕时调用,可以在其中拿到各种属性,例如 info、weights 等
  • new_config[非必要]:实例化一个配置对象
  • 可以自定义 LayerConfig 类并返回,也可以直接使用 LayerConfig 类
  • 这个函数的最大作用,是配置本插件支持的数据格式和类型。比如 fp32 和 fp16 的支持等
  • getOutputDimensions[非必要],获取该插件输出的 shape 大小,默认取第一个输入的大小
  • 对应于原始插件的 getOutputDimensions 函数
  • enqueue[必要],插件推理过程
  • 插件的实际推理过程,该函数可能在编译和推理阶段数次调用

6. 注册插件,使用 RegisterPlugin 宏

  • RegisterPlugin(MYSELU)
  • 格式是 RegisterPlugin(类名)

7. 好了,可以使用插件了

总结

本节课程学习了插件的封装。首先杜老师在 builtin_op_importers.cpp 添加了对通用插件 Plugin 的解析支持,凡是叫做 Plugin 的节点,都能被正常解析,因此在导出 onnx 的时候需要指定 g.op_type() 为 Plugin,name_s 指定为自己注册的插件名称,info_s 则传递属性值为 json 字符串。

接下来在 onnxplugin.cpp 中实现对 IPluginV2DynamicExt 的封装,由于插件的很多属性都是通用的,因此实现了默认函数,比如序列化、反序列化等等,我们只需要实现 enqueue 然后调用封装的接口就可以完成整个插件的开发工作。

那经过这么一层封装,确实省事了不少呀,具体封装的细节就没去看了,先能写个插件用起来再说吧😂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/781852.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5G的发展过程

目录 1.什么是5G 2.5G与4G的区别 3.5G的应用领域 4.5G给人类带来的福利 5.5G未来的发展趋势 1.什么是5G 5G技术是第五代移动通信技术&#xff0c;它是对之前的2G、3G和4G技术的升级和革新。5G技术具有更高的数据传输速度、更低的延迟和更大的网络容量&#xff0c;为人们提供…

Qt简单实现密码器控件

本文实例为大家分享了Qt自定义一个密码器控件的简单实现代码&#xff0c;供大家参考&#xff0c;具体内容如下 实现构思&#xff1a; 密码器的功能可以看成是计算器和登陆界面的组合&#xff0c;所以在实现功能的过程中借鉴了大神的计算器的实现代码和登陆界面实现的代码。 …

20230720在ubuntu22.04系统下载+解密+合并ts切片的步骤(STEP-BY-STEP版本)

20230720在ubuntu22.04系统下载解密合并ts切片的步骤&#xff08;STEP-BY-STEP版本&#xff09; 2023/7/20 23:06 https://app1ce7glfm1187.h5.xiaoeknow.com/v2/course/alive/l_64af6130e4b03e4b54da1681?type2&app_idapp1cE7gLFM1187&pro_idterm_645c69388953e_Nhew…

人类机器人编程的心理机制(一)

\qquad 本文中的人类机器人编程(Human Robot Programming)意指“基于创伤的脑控(trauma-based mind control, T.B.M.C)”或“基于创伤的编程(trauma-based programming)”&#xff0c;文中用英文缩写“T.B.M.C”指代。T.B.M.C的操纵主体是施加编程的个人或机构&#xff0c;文中…

个人博客系统(三)

在个人博客系统(二)中介绍了注册页面和登录页面,这两个页面比较简单,最重要的一个问题是验证码的实现,具体详情可见:http://t.csdn.cn/EyVjz​​​​​​ 接下来,本博客主要介绍的是添加博客页面和修改博客页面。 1 添加博客页面 该页面如图所示: 首先判断文章标题是…

AcWing算法提高课笔记

目录 Level2 1.动态规划——从集合角度考虑DP问题 1.1 数字三角形模型 1.1.1摘花生 1.1.2最低通行费 1.1.3方格取数 1.1.4传纸条 1.2 最长上升子序列模型 1.2.1怪盗基德的滑翔翼 1.2.2登山 1.2.3合唱队形 1.2.4好友城市 1.2.5最大上升子序列和 1.2.6拦截导弹 1.2…

MySQL下载与安装

MySQL下载与安装 一、下载 地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 当前最新是8.0版本&#xff0c;我选择上一个最新的mysql-5.7.24-winx64.zip 二、安装 MySQL安装文件分两种 .msi和.zip &#xff0c;.msi需要安装 zip格式是自己解压&#xff0c;解压缩之后…

Openlayers实战:extent介绍及实际应用

Openlayers中,extent是重要的属性,它主要目的是圈定边界。setExtent方法可以设定边界的值;fit()方法可以适配狂口的位置。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozhuanlan),还是大剑师兰特(CSDN) * @此源代码版权归大剑师兰特所有,可供学习或商业项目中借鉴,…

关于Idea/DataGrip下载的插件在那个文件夹

不止Idea和DataGrip&#xff0c;只要是JET BRAINS家的产品都实用。 路径&#xff1a;C:\Users\windows登录账户\AppData\Roaming\JetBrains\DataGrip2021.3\plugins 如果要找其他软件的插件&#xff0c;就在JetBrains目录下找到相对应的软件&#xff0c;点进去后就是插件。 针…

瑞吉外卖开发笔记 七(Linux)

为什么要学Linux ? 企业用人要求个人发展要求 学习后能干什么&#xff1f; Linux简介 不同应用领域的主流操作系统 桌面操作系统 Windows &#xff08;用户数量最多)Mac OS&#xff08;操作体验好&#xff0c;办公人士首选)Linux&#xff08;用户数量少) 服务器操作系统 UN…

Python Flask构建微信小程序订餐系统 (十一)

🔥 已经删除的会员不允许进行编辑昵称 🔥 🔥 已经删除的会员要隐藏掉会员信息的编辑按钮 🔥 🔥 创建商品表 food 🔥 CREATE TABLE `food` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`cat_id` int(11) NOT NULL DEFAULT 0 COMMENT 分类id,`name` varchar…

springboot集成logback按日志级别按天保存

演示结果 集成logback后项目启动控制台不会有日志输出 生成的日志文件路径windows上是默认D盘,linux上可自定义 代码实现 pom.xml <dependency><groupId>ch.qos.logback</groupId>

[DASCTF 2023 0X401七月暑期挑战赛] crypto

密码只有3道题&#xff0c;最后一道被卡了&#xff0c;赛后在师傅一点点提示下完成。 ezRSA 题目很短&#xff0c;分两个RSA一个用小写表示一个用大写表示&#xff0c;小写n用大写加密&#xff0c;大写的给出了P和Q>>16的提示。 from Crypto.Util.number import * from…

EMC学习笔记(十九)EMC常用元件简单介绍

EMC常用元件简单介绍 1.共模电感2.磁珠3.滤波电容器 1.共模电感 由于 EMC 所面临解决问题大多是共模干扰&#xff0c;因此共模电感也是我们常用的有力元件之一&#xff01;这里就给大家简单介绍一下共模电感的原理以及使用情况。 共模电感是一个以铁氧体为磁芯的共模干扰抑制…

C语言每日一题:3.错误的集合

题目链接&#xff1a;点击 思路一 1.1.排序遍历拿到我们重复的数值的同时去遍历数组一遍,求和重复的数字只加入一遍,和设置为sum1&#xff1b; 2.求没有消失的和&#xff0c;等差数列求和公式(1n)*n/2&#xff0c;定义为sum2&#xff1b; 3.sum2-sum1就是消失的数值。 这个方法…

【git】零基础学习git(持续更新中)

文章目录 前言git安装LinuxWindows git配置创建版本库将文件添加到版本库一次添加一个文件一次添加多个文件 查看git状态查看修改的差异查看历史记录当前版本 回退回退到上一个版本回退到某个版本如果关闭当前窗口如果关闭了当前窗口 工作区与版本库关系查看工作区和版本库里面…

记录一下trackformer的安装过程

项目地址 1、创建python环境&#xff0c;并激活 conda create -n TF python3.8 -y conda activate TF2、进入trackformer中&#xff0c;并且运行setup.py cd Desktop/MOT/trackformer/ python setup.py install3、下载pytorch pytorch官方安装法 # CUDA 11.1 pip install …

虚拟机ip地址总是改变的完美解决

在连接虚拟机进行操作时&#xff0c;第一次成功连接到虚拟机&#xff0c;但是关闭虚拟机后&#xff0c;第二天发现怎么都连接不上该虚拟机了&#xff0c;结果查询虚拟机的ip地址发现ip地址发生了改变&#xff0c;那么怎么才能让虚拟机的ip地址固定不变呢&#xff1f; 具体操作…

【vue2+element ui】添加修改共用表单的下拉框回显问题分析以及解决方案(附共用表单代码)

目录 简介问题复原问题分析共用表单代码分享 简介 本人前端水平不佳&#xff0c;本文分享在编写个人项目前端代码的时候遇到的回显问题的解决办法&#xff0c;仅供参考。 问题复原 首先展示表单中的问题代码&#xff0c;本次前端的设计是添加和修改操作共用表单&#xff0c;…

物通博联5G+工业互联网解决方案助力打造5G智能工厂

面对来自成本和市场等压力挑战&#xff0c;工业企业正通过数字化升级提升效益降低成本&#xff0c;拓展发展空间。 随着科技的不断发展&#xff0c;5G技术已经成为了全球关注的焦点。5G技术的高速度、低延迟和大连接特性为各行各业带来了巨大的变革机遇。工业和信息化部有关负…