C# 部署 tensorRT resnet分类模型 deploy TensorRT model with C#

news/2025/2/23 5:08:48/文章来源:https://www.cnblogs.com/luoliasyns/p/18718689

基于生态的优势,一般都是用pytorch写模型;但是工业现场的部署,目前比较方便的还是onnx;当下为了追求效率,使用了TensorRT

C#: .net8
GPU: A2000 / 4070Ti
OS: windows
Cuda: 11.8
预处理:Emgu.CV

  1. install v11.8 Cuda
    默认安装,会生成以下路径 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8
  2. 下载 v8.1.6 TensorRT
    我随便放到了一个路径,解压一下就好
  3. copy files from TensorRT to cuda
    · 把TensorRT文件夹里的 include 和 lib 文件夹复制,粘贴到cuda文件夹里
    · 把cuda/lib 文件夹里的.dll 文件,全部剪切,放到 cuda/bin 文件夹中
  4. git clone TensorRTSharp 项目
    https://github.com/guojin-yan/TensorRT-CSharp-API.git
  5. 按照 https://www.cnblogs.com/guojin-blogs/p/18108220 设置
    其中,在附加依赖项目录时,我这边报错了,所以去除了 nvJitLink.lib nvJitLink_static.lib
  6. 新建一个测试项目,引用TensorRTSharp.dll,把TensorRtExtern生成的4个文件也copy过来
  7. 测试项目核心代码,其中 'input' 'output' 是模型的input/output layer,如果使用了onnx,在onnx导出时,有输入相关参数,需要保持一致
string modelPath = string.Empty;
Nvinfer nvinfer = new Nvinfer(modelPath );float[] inputData = imagePreProc20250212(img);nvinfer.LoadInferenceData("input", inputData);
nvinfer.infer();List<float> results = nvinfer.GetInferenceResult("output").ToList();//这一段是在根据最后的output,以最大confidence的index作为结果,并归一化,也就是概率
float maxProb = results.Max();
float minProb = results.Min();
int index = results.IndexOf(maxProb);double sum = results.Sum(x => Math.Pow(Math.E, x));float prob = float.Parse((Math.Pow(Math.E, maxProb) / sum).ToString("f4"));
  1. Emgu.CV的预处理
    TensorRT的输入是float[],项目的输入是图片,所以需要进行一些处理;这里的核心就是,图片需要遵循NCHW格式;我的batch size是1,所以不需要考虑N
 private float[] imagePreProc20250212(Image<Rgb, float> image){image = image.Resize(224, 224, Emgu.CV.CvEnum.Inter.Nearest);int chLen = 224 * 224;float[] data = new float[3 * chLen];float[] mean = new[] { 0.485f, 0.456f, 0.406f };float[] stddev = new[] { 0.229f, 0.224f, 0.225f };for (int y = 0; y < image.Cols; y++){for (int x = 0; x < image.Rows; x++){image.Data[x, y, 0] = ((image.Data[x, y, 0] / 255.0f) - mean[0]) / stddev[0];image.Data[x, y, 1] = ((image.Data[x, y, 1] / 255.0f) - mean[1]) / stddev[1];image.Data[x, y, 2] = ((image.Data[x, y, 2] / 255.0f) - mean[2]) / stddev[2];}}// 因为image是  image<RGB, float>, 所以channel的顺序就是R,G,Bfor (int c =0; c < 3;c++){Emgu.CV.Mat chMat = new Emgu.CV.Mat();CvInvoke.ExtractChannel(image.Mat, chMat, c);float[] chFloat = new float[chLen];Marshal.Copy(chMat.DataPointer, chFloat, 0, chLen);Array.Copy(chFloat, 0, data, c * chLen, chLen);}return data;}
  1. 测试结果
    在4070ti 上测试,单张图片分类,速度约为onnx的1.6倍
    其中onnx因为是线程安全的,我用了多线程,trt是用的单线程
    时间包含了加载模型,数据库拿image,image的preprocess,所以单张速度应该在2倍左右,batch size如果大一点,提升能更大
model cycle per second
onnx 96.02
TensorRT 158.81

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自然语言处理入门【第6章】:自然语言处理的应用

搜广推业务 信息检索 搜索、广告和推荐是很多互联网大厂赖以生存的命脉。比如,百度的搜索引擎、京东淘宝的推荐系统、腾讯的广告业务等。这一节我们就看看搜广推业务当中的自然语言处理方法。 1. 什么是信息检索 信息检索(Information Retrieval,IR)是指从大量的非结构化或…

提取东京食尸鬼主题曲

钢琴的声音实在是太好听了,这演奏者的指法真的逆天了! 利用IE缓存来提取视频文件是屡试不爽啊,只要视频不是经过加密的,均能提取成功。打开IE浏览器,关闭所有标签,仅留下一个空白标签,并打开Internet选项删除浏览历史记录点设置,查看文件,打开缓存文件夹,删除文件夹内…

树梅派XBMC解决方案比较

本文是Raspberry Pi XBMC Solutions Compared: Raspbmc vs OpenELEC vs XBian的译文,可能已经过时。XMBC是我们最喜欢的媒体中心解决方案之一。Raspberry Pi使得打造一台豪华的XMBC机器仅需35$。有三个为Pi定制的版本,但是,你该选择哪一个呢?这些版本略有差异,各有长短。本…

deepseek破限的一种方法

起因是https://www.south-plus.net/read.php?tid=2455666这篇帖子的作者在B22F提到他的Deepseek的破甲关键词和使用流程,咱直接复制粘贴直接被deepseek拒绝了呜呜呜 失败案例: 我大致提取了一段不会被办的话,试了一下可以和其他的混合使用破甲效果极佳(但是荤段子得靠其他…

实体机双系统

本文年代久远,可能已经不再适用。仅供参考首先说一下,双系统并不会影响两个系统各自的速度。两个系统都是独立的,分别位于硬盘的不同位置,独立运行。也就是说,当一个系统在运行时,另一个系统只是储存在硬盘上的文件,这自然不会对系统的速度有影响。 另外,安装双系统是有…

2024.1.17web HTTP协议基础

2.1 HTTP的基本概念与交互模型 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写。它是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。 HTTP 协议的特点 1.无连接—限制每次连接只处理一个请求 2.无状态—协议对于事务…

173 词转换成向量形式

介绍一下\(\text{Skip-Gram}\)算法。非常简单的一个算法,训练集由\(\text{context}\)和\(\text{target}\)组成,前者是一个句子中的某一个单词,后者是这个句子中这个单词临近的某个词。举例如下我们获得单词的嵌入向量后,就放入神经网络中去跑,再利用\(\text{Softmax}\)如下…

对象

Array:数组 定义 var 变量名 = new Array(元素) var arr = new Array(1,2,3); var 变量名 = [元素] var arr = [1,2,3]; arr[索引]=值; 可以变长变类型

《操作系统真相还原》实验记录2.9——完善内存管理系统

本文章实现内容如下: ① 完成了更细粒度的内存分配机制——arena机制的建立 ② 完成了内存分配系统调用 malloc() 的实现 ③ 完成了内存释放系统调用 free() 的实现一、malloc 底层原理之前我们虽然已经实现了内存管理,但显得过于粗糙,分配的内存都是以 4KB 大小的页框为单位…

智能化客户画像构建管理:AI视频监控在大型商场的技术方案介绍(part5)

前言:某商家为了优化卖场服务与营销策略,希望通过非侵入式手段获取客户画像,不仅可以帮助卖场提升服务质量、优化营销策略,还能通过数据驱动的方式提升销售业绩和顾客满意度,为卖场的长期发展奠定坚实的基础。具体需求 1、性别分析:识别顾客的性别比例,为产品布局和服务…

169 使用词嵌入

以判断人名为例。如果我们只使用独热编码,那么我们的训练集不能太大(否则维度爆炸),所以遇到了下面这种情况我们没有在训练集中坚果durian和cultivator,导致我们没有判断出来Robert Lin是人名 但是如果我们使用词嵌入,我们的训练集就可以很大(从网上下载即可),然后通过…

简单的Java程序 HelloWorld

HelloWorld谁便新建一个文件,存放代码 新建一个Java文件文件后缀名为.java Hello.java 系统可能没有显示文件后缀名,需要手动打开编写代码 public class Hello{public static void main(String[] args){System.out.print("Hello,World");} }1. 编译 javac java文…