YOLO系列和RT-DETR转onnx和tensorrt,测FPS

news2024/9/21 4:24:55

RT-DETR(RT-DETR: DETRs Beat YOLOs on Real-time Object Detection) 和YOLOv8等在最后加nms RT-DETR转onnx和tensorrt和 RT-DETR转onnx和tensorrt

步骤流程:

1. nvidia驱动,cuda,cudnn三者的版本是相互对应的,必须要确保版本匹配(https://blog.csdn.net/qq_41246375/article/details/133926272?spm=1001.2101.3001.6650.7&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-133926272-blog-120109778.235%5Ev43%5Epc_blog_bottom_relevance_base9&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-133926272-blog-120109778.235%5Ev43%5Epc_blog_bottom_relevance_base9&utm_relevant_index=13)

2.下载tensor RT,注意版本对应关系(https://developer.nvidia.com/nvidia-tensorrt-8x-download)

我自己的方法是直接下载deb的

sudo dpkg -i nv-tensorrt-local-repo-ubuntu2004-8.6.1-cuda-11.8_1.0-1_amd64.deb
sudo cp /var/nv-tensorrt-local-repo-ubuntu2004-8.6.1-cuda-11.8/nv-tensorrt-local-D7BB1B18-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get install tensorrt
dpkg-query -W tensorrt	#查看安装结果

上面是关于简单的介绍cuda,cudnn和tensorrt的方法,我就进行了简写,具体的cuda,cudnn可以看这个视频介绍
视频链接:https://www.bilibili.com/video/BV1KL411S7hw/?spm_id_from=333.880.my_history.page.click

3.下面是主要关于介绍转onnx模型和tensor模型

3.1 YOLOv8转onnx方法
尽管在ultralytics(https://github.com/ultralytics/ultralytics?tab=readme-ov-file)中的方法有详细的介绍了转onnx的方法,但是没有加nms
我根据RT-DETR(RT-DETR: DETRs Beat YOLOs on Real-time Object Detection) 原论文介绍,如何加nms方法进行介绍。
在(https://github.com/lyuwenyu/RT-DETR/tree/main/benchmark) 链接中将yolov8_onnx.py和utils.py两代码直接放入官网的YOLOv8中 [https://github.com/ultralytics/ultralytics?tab=readme-ov-file]

在这里插入图片描述
官方的yolov8_onnx.py源代码:

'''by lyuwenyu
'''

import torch 
import torchvision

import numpy as np 
import onnxruntime as ort 

from utils import yolo_insert_nms

class YOLOv8(torch.nn.Module):
    def __init__(self, name) -> None:
        super().__init__()
        from ultralytics import YOLO
        # Load a model
        # build a new model from scratch
        # model = YOLO(f'{name}.yaml')  

        # load a pretrained model (recommended for training)
        model = YOLO(f'{name}.pt')  
        self.model = model.model

    def forward(self, x):
        '''https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/tasks.py#L216
        '''
        pred: torch.Tensor = self.model(x)[0] # n 84 8400,
        pred = pred.permute(0, 2, 1)
        boxes, scores = pred.split([4, 80], dim=-1)
        boxes = torchvision.ops.box_convert(boxes, in_fmt='cxcywh', out_fmt='xyxy')

        return boxes, scores



def export_onnx(name='yolov8n'):
    '''export onnx
    '''
    m = YOLOv8(name)

    x = torch.rand(1, 3, 640, 640)
    dynamic_axes = {
        'image': {0: '-1'}
    }
    torch.onnx.export(m, x, f'{name}.onnx', 
                      input_names=['image'], 
                      output_names=['boxes', 'scores'], 
                      opset_version=13, 
                      dynamic_axes=dynamic_axes)

    data = np.random.rand(1, 3, 640, 640).astype(np.float32)
    sess = ort.InferenceSession(f'{name}.onnx')
    _ = sess.run(output_names=None, input_feed={'image': data})


if __name__ == '__main__':

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--name', type=str, default='YOLOv8x')
    parser.add_argument('--score_threshold', type=float, default=0.001)
    parser.add_argument('--iou_threshold', type=float, default=0.7)
    parser.add_argument('--max_output_boxes', type=int, default=300)
    args = parser.parse_args()

    export_onnx(name=args.name)
    
    yolo_insert_nms(path=f'{args.name}.onnx', 
                    score_threshold=args.score_threshold, 
                    iou_threshold=args.iou_threshold, 
                    max_output_boxes=args.max_output_boxes, )

然而我在跑我自己的数据集的时候它报了一个错误,根据错误信息,使用 split 方法将一个张量 pred 分成两个部分时遇到了问题。错误信息指出,split_with_sizes 期望 split_sizes 的和与张量在指定维度上的大小完全一致,但输入张量在最后一个维度上的大小是5,而传递的 split_sizes 是 [4, 80]。

我对源码进行了更正,更正如下:

'''by lyuwenyu
'''

import torch
import torchvision

import numpy as np
import onnxruntime as ort

from utils import yolo_insert_nms


class YOLOv8(torch.nn.Module):
    def __init__(self, name) -> None:
        super().__init__()
        from ultralytics import YOLO
        model = YOLO(f'{name}.pt')
        self.model = model.model

    def forward(self, x):
        '''https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/tasks.py#L216
        '''
        pred: torch.Tensor = self.model(x)[0]  # n 84 8400,
        pred = pred.permute(0, 2, 1)
        print(f'Pred shape: {pred.shape}')  # 打印 pred 的形状
        boxes, scores = pred.split([4, 1], dim=-1)  # 根据 pred 的形状调整 split 大小
        boxes = torchvision.ops.box_convert(boxes, in_fmt='cxcywh', out_fmt='xyxy')

        return boxes, scores


def export_onnx(name='yolov8n'):
    '''export onnx
    '''
    m = YOLOv8(name)

    x = torch.rand(1, 3, 640, 640)
    dynamic_axes = {
        'image': {0: '-1'}
    }
    torch.onnx.export(m, x, f'{name}.onnx',
                      input_names=['image'],
                      output_names=['boxes', 'scores'],
                      opset_version=13,
                      dynamic_axes=dynamic_axes)

    data = np.random.rand(1, 3, 640, 640).astype(np.float32)
    sess = ort.InferenceSession(f'{name}.onnx')
    _ = sess.run(output_names=None, input_feed={'image': data})

if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--name', type=str, default=r'YOLOv8x')
    parser.add_argument('--score_threshold', type=float, default=0.001)
    parser.add_argument('--iou_threshold', type=float, default=0.7)
    parser.add_argument('--max_output_boxes', type=int, default=300)
    args = parser.parse_args()
    export_onnx(name=args.name)
    yolo_insert_nms(path=f'{args.name}.onnx',
                    score_threshold=args.score_threshold,
                    iou_threshold=args.iou_threshold,
                    max_output_boxes=args.max_output_boxes, )

我用我自己的数据报错如下:

C:\Users\29269\Desktop\RTDETR-20240802\ultralytics\nn\modules\head.py:49: TracerWarning: Converting a tensor to a Python boolean might cause the trace to be incorrect. We can't record the data flow of Python values, so this value will be treated as a constant in the future. This means that the trace might not generalize to other inputs!
  elif self.dynamic or self.shape != shape:
C:\Users\29269\Desktop\RTDETR-20240802\ultralytics\utils\tal.py:254: TracerWarning: Iterating over a tensor might cause the trace to be incorrect. Passing a tensor of different shape won't change the number of iterations executed (and might lead to errors or silently give incorrect results).
  for i, stride in enumerate(strides):
Traceback (most recent call last):
  File "C:\Users\29269\Desktop\RTDETR-20240802\yolov8_onnx.py", line 66, in <module>
    export_onnx(name=args.name)
  File "C:\Users\29269\Desktop\RTDETR-20240802\yolov8_onnx.py", line 45, in export_onnx
    torch.onnx.export(m, x, f'{name}.onnx', 
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\onnx\utils.py", line 506, in export
    _export(
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\onnx\utils.py", line 1548, in _export
    graph, params_dict, torch_out = _model_to_graph(
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\onnx\utils.py", line 1113, in _model_to_graph
    graph, params, torch_out, module = _create_jit_graph(model, args)
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\onnx\utils.py", line 989, in _create_jit_graph
    graph, torch_out = _trace_and_get_graph_from_model(model, args)
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\onnx\utils.py", line 893, in _trace_and_get_graph_from_model
    trace_graph, torch_out, inputs_states = torch.jit._get_trace_graph(
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\jit\_trace.py", line 1268, in _get_trace_graph
============== Diagnostic Run torch.onnx.export version 2.0.1+cpu ==============
verbose: False, log level: Level.ERROR
======================= 0 NONE 0 NOTE 0 WARNING 0 ERROR ========================

    outs = ONNXTracedModule(f, strict, _force_outplace, return_inputs, _return_inputs_states)(*args, **kwargs)
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\nn\modules\module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\jit\_trace.py", line 127, in forward
    graph, out = torch._C._create_graph_by_tracing(
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\jit\_trace.py", line 118, in wrapper
    outs.append(self.inner(*trace_inputs))
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\nn\modules\module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\nn\modules\module.py", line 1488, in _slow_forward
    result = self.forward(*input, **kwargs)
  File "C:\Users\29269\Desktop\RTDETR-20240802\yolov8_onnx.py", line 29, in forward
    boxes, scores = pred.split([4, 80], dim=-1)
  File "D:\software\Anaconda3\envs\yolov8\lib\site-packages\torch\_tensor.py", line 803, in split
    return torch._VF.split_with_sizes(self, split_size, dim)
RuntimeError: split_with_sizes expects split_sizes to sum exactly to 5 (input tensor's size at dimension -1), but got split_sizes=[4, 80]

报错结果:
在这里插入图片描述运行下面指令后, 会生成两个文件,一个是没有加YOLOv8x.onnx文件和yolo_w_nms.onnx两个文件,这两个文件,yolo_w_nms.onnx是加入了nms而YOLOv8x.onnx没加入nms,

python  yolov8_onnx.py

如何查看是否加入了nms需要通过netron进行查看。下面是加入nms的效果示意图
在这里插入图片描述
转tensorrt 方法:

trtexec --onnx=./yolo_w_nms.onnx --saveEngine=yolo_w_nms.engine --buildOnly --fp16

测FPS方法:

trtexec --loadEngine=yolo_w_nms.engine --fp16 --avgRuns=100

参数介绍:

  • –loadEngine=/path/to/your_model.engine:指定要加载的 TensorRT 引擎文件。

  • –fp16:使用 FP16 精度进行推理(如果你的模型支持)。

  • –avgRuns=100:平均运行 100 次以获得稳定的 FPS 值。

用 trtexec --loadEngine=yolo_w_nms.engine --fp16 --avgRuns=100指令测试后会找到GPU Compute Time的mean值,然后用1000除以它得到FPS值。
如下图所示:它的mean值是2.00663 .则FPS=1000/2.00663=498.347
在这里插入图片描述
4.在用RT-DETR模型中,依然可以用官方的ultralytics导出onnx,然后用转tensorrt 方法再测FPS

import warnings
warnings.filterwarnings('ignore')
from ultralytics import RTDETR

# onnx onnxsim onnxruntime onnxruntime-gpu

# 导出参数官方详解链接:https://docs.ultralytics.com/modes/export/#usage-examples

if __name__ == '__main__':
    model = RTDETR(r"R18best.pt")
    model.export(format='onnx', simplify=True)

参考资料:

  1. https://blog.csdn.net/qq_41246375/article/details/133926272?spm=1001.2101.3001.6650.7&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-133926272-blog-120109778.235%5Ev43%5Epc_blog_bottom_relevance_base9&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-133926272-blog-120109778.235%5Ev43%5Epc_blog_bottom_relevance_base9&utm_relevant_index=13
  2. https://blog.csdn.net/java1314777/article/details/134629701
  3. https://blog.csdn.net/qq_41246375/article/details/115597025

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

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

相关文章

有什么简单方便的cad编辑器?2024快速进行cad编辑的软件合集

有什么简单方便的cad编辑器&#xff1f;2024快速进行cad编辑的软件合集 在建筑、工程、设计等领域&#xff0c;CAD&#xff08;计算机辅助设计&#xff09;软件是必不可少的工具。然而&#xff0c;面对复杂的CAD文件&#xff0c;有时我们只需要简单的编辑功能&#xff0c;而不…

nginx配置代理https端口的要点

今天配置了一个nginx代理端口&#xff0c;从http转成https的过程&#xff0c;刚开始以为很复杂&#xff0c;后面发现其实就那几个关键点&#xff0c;配置好了&#xff0c;就可以直接跳转 server的监听端口 我们常规nginx监听的端口都是http协议的&#xff0c;没有特殊说明&am…

Javascript实现笛卡儿积算法

在根据商品属性计算SKU时&#xff0c;通常会对商品不同选项的不同属性进行笛卡儿积运算。 function cartesian(elements) {if (!Array.isArray(elements))throw new TypeError();var end elements.length - 1,result [];function addTo(curr, start) {var first elements[s…

电话催收的优劣势

电话催收相比其他催收方式有哪些优势和劣势&#xff1f; 电话催收是催收业务这个场景最常用的一个方式&#xff0c;因为它无可替代。唯一还有催回欠款可能的&#xff0c;就是上门催&#xff0c;那成本太高了&#xff0c;一般不会选择。 优势方面 电话催收的主要优点包括成本低…

C语言实现SHA-256算法校验文件(win32-API)

一、前言 在数字化时代&#xff0c;信息安全与数据完整性成为了不可忽视的关键议题。在众多保障数据完整性的方法中&#xff0c;散列函数扮演着至关重要的角色。SHA-256&#xff08;Secure Hash Algorithm 256&#xff09;作为一种先进的散列算法&#xff0c;以其高度的安全性…

【C++】stack、queue、priority_queue的模拟实现

目录 一、stack &#x1f31f;stack的简单介绍 &#x1f31f;stack的基本使用 &#x1f31f;stack的模拟实现 &#x1f31f;stack模拟实现的完整代码 &#x1f31f;容器适配器 二、queue &#x1f31f;queue的简单介绍 &#x1f31f;queue的基本使用 &#x1f31f;q…

springboot酒店管理系统

springboot221酒店管理系统 摘 要 时代的发展带来了巨大的生活改变&#xff0c;很多事务从传统手工管理转变为自动管理。自动管理是利用科技的发展开发的新型管理系统&#xff0c;这类管理系统可以帮助人完成基本的繁琐的反复工作。酒店是出门的必需品&#xff0c;无论出差还是…

娱乐小项目-树莓派履带小车

快速使用 1.小车上电&#xff0c;开关在电源插口旁边 2.上电之后用电脑查看局域网WIFI&#xff0c;密码是12345678&#xff0c;固定IP是192.168.50.1 3.安装VNC软件&#xff1a;20240324_树莓派履带车\工具 4.打开VNC软件 5.在这个界面下 按ctrlaltt&#xff0c;弹出终端 6.输…

内存管理篇-20 Linux虚拟内存管理

1.虚拟地址的经典布局 这里的内容比较少。只要就是内核用户空间的划分。内核空间又有自己的划分。也需要注意一下每个区域的性能。理论上线性映射是最简单的&#xff0c;所以性能最高。同时&#xff0c;注意内核空间是可以配置的&#xff0c;并不是都3:1。 2.ARM32下的内存…

使用cURL探索WebSocket连接的奥秘

更多内容访问个人网站&#xff1a;孔乙己大叔 在现代Web开发中&#xff0c;实时通信已经成为不可或缺的一部分。WebSocket协议因其能够提供低延迟、全双工的通信能力&#xff0c;而被广泛应用于各种实时应用场景中&#xff0c;如在线聊天、实时通知、游戏等。虽然WebSocket主要…

React 实现PDF预览(数据源使用文件流而不是url)

一 前提 应公司要求&#xff0c;需要进行上传文件&#xff08;pdf&#xff09;的预览功能&#xff0c;网上大部分都是使用url作为预览数据源&#xff0c;但是现在后端那边只返回了pdf文件流&#xff0c;所以本文主要是用文件流来预览pdf。 二 首先需要获取pdf文件流&#xff…

四款经典的防泄密软件,企业防泄密必备软件

防泄密软件有哪些呢&#xff1f;以下是四款经典的防泄密软件介绍&#xff0c;每款软件都将从其主要功能、特点以及适用场景等方面进行详细阐述。 1. 安企神 主要功能&#xff1a; 文件加密&#xff1a;提供全面的文件加密解决方案&#xff0c;支持对敏感文件进行加密处理&…

IP地址在TikTok运营中为何重要?

TikTok作为外贸人宣传推广的重要平台&#xff0c;其运营成效与产品的实际转化率息息相关。然而&#xff0c;在TikTok的运营过程中&#xff0c;一个看似微不足道的元素—IP地址&#xff0c;却扮演着至关重要的角色。本文将深入探讨TikTok运营中IP地址的重要性&#xff0c;揭示其…

ETL数据集成丨SQLServer到Doris的无缝数据同步策略

在数据驱动的新时代&#xff0c;企业对数据的需求日益增加&#xff0c;尤其是数据同步的速度和准确性。随着数据源和数据目标的多样化&#xff0c;如何实现高效、无缝的数据同步成为了许多企业的关注焦点。ETLCloud正是这一领域的先锋&#xff0c;为用户提供了从 SQLServer 到 …

面向GPU计算平台的归约算法的性能优化研究

1 GPU归约算法的实现与优化 图3-1为本文提出的GPU归约算法总图&#xff0c;GPU归约求和算法的实现可以定义为三个层次&#xff1a; 线程内归约&#xff1a;线程从global memory中读取一个或多个数据进行归约操作&#xff0c;再把归约结果写入至LDS&#xff1b;work-group内归…

告警管理大师:深入解析Alertmanager的配置与实战应用

目录 一、前言 二、Alertmanager 简介 三、Alertmanager核心内容介绍 &#xff08;1&#xff09;告警分组&#xff08;Alert Grouping&#xff09; 分组原理 配置示例 &#xff08;2&#xff09;告警路由&#xff08;Alert Routing&#xff09; 路由原理 配置示例 &a…

中资优配:白马股跌出性价比 基金经理公开唱多

近年来走势欠安的一些白马股&#xff0c;其时现已跌出了性价比。 在刚刚宣布的二季报中&#xff0c;就有多名基金司理旗帜鲜明地标明看好此类财物。有基金司理认为&#xff0c;这些个股的股息率已靠近或高于无风险利率&#xff0c;其隐含的长期酬谢水平或许已明显高于其时获商…

VScode 的下载安装及常见插件 + Git的下载和安装

目录 一、VScode 的下载安装及常见插件 1、VSCode下载 2、VSCode安装 3、VSCode常见扩展插件及介绍 二、Git的下载和安装 1、Github 和 Gitee的区别 2、Git下载&#xff08;以Win为例&#xff09; 3、Git安装 一、VScode 的下载安装及常见插件 1、VSCode下载 &#x…

VBA字典与数组第十八讲:VBA中静态数组的定义及创建

《VBA数组与字典方案》教程&#xff08;10144533&#xff09;是我推出的第三套教程&#xff0c;目前已经是第二版修订了。这套教程定位于中级&#xff0c;字典是VBA的精华&#xff0c;我要求学员必学。7.1.3.9教程和手册掌握后&#xff0c;可以解决大多数工作中遇到的实际问题。…

ArcGIS小技巧:批量加载文件夹下的所有SHP数据到当前地图框

欢迎关注同名微信公众号&#xff0c;更多文章推送&#xff1a; 一般情况下&#xff0c;如果要加载SHP数据&#xff0c;只要在工程目录栏中将其拖到当前地图框中即可。 假设这样一个场景&#xff0c;一个文件夹下分布着很多个SHP数据&#xff0c;甚至有的SHP数据位于子文件夹中…