yolov5 detect.py推理.onnx速度很慢

请问我使用官方的export.py转换出来的onnx推理很慢是什么原因?安装环境时执行的是代码头部给出的命令,pip查看也安装的是onnxruntime-gpu。
转换时参数设置

def parse_opt():
    parser = argparse.ArgumentParser()
    parser.add_argument('--data', type=str, default=ROOT / 'data/nj.yaml', help='dataset.yaml path')
    parser.add_argument('--weights', nargs='+', type=str, default=ROOT / 'best.pt', help='model.pt path(s)')
    parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[640, 640], help='image (h, w)')
    parser.add_argument('--batch-size', type=int, default=4, help='batch size')
    parser.add_argument('--device', default='cpu', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--half', action='store_true', help='FP16 half-precision export')
    parser.add_argument('--inplace', action='store_true', help='set YOLOv5 Detect() inplace=True')
    parser.add_argument('--train', action='store_true', help='model.train() mode')
    parser.add_argument('--optimize', action='store_true', help='TorchScript: optimize for mobile')
    parser.add_argument('--int8', action='store_true', help='CoreML/TF INT8 quantization')
    parser.add_argument('--dynamic', action='store_true', help='ONNX/TF: dynamic axes')
    parser.add_argument('--simplify', action='store_true', help='ONNX: simplify model')
    parser.add_argument('--opset', type=int, default=12, help='ONNX: opset version')
    parser.add_argument('--verbose', action='store_true', help='TensorRT: verbose log')
    parser.add_argument('--workspace', type=int, default=4, help='TensorRT: workspace size (GB)')
    parser.add_argument('--nms', action='store_true', help='TF: add NMS to model')
    parser.add_argument('--agnostic-nms', action='store_true', help='TF: add agnostic NMS to model')
    parser.add_argument('--topk-per-class', type=int, default=100, help='TF.js NMS: topk per class to keep')
    parser.add_argument('--topk-all', type=int, default=100, help='TF.js NMS: topk for all classes to keep')
    parser.add_argument('--iou-thres', type=float, default=0.45, help='TF.js NMS: IoU threshold')
    parser.add_argument('--conf-thres', type=float, default=0.25, help='TF.js NMS: confidence threshold')
    parser.add_argument('--include', nargs='+',
                        default=['onnx'],
                        help='torchscript, onnx, openvino, engine, coreml, saved_model, pb, tflite, edgetpu, tfjs')
    opt = parser.parse_args()
    print_args(FILE.stem, opt)
    return opt

援引GPT回答:
导致推理速度慢的原因可能有很多,以下是一些可能的原因:

  1. 模型结构复杂:如果模型的结构非常复杂,包含大量的层和参数,那么推理速度可能会较慢。可以尝试简化模型结构或者使用更轻量级的模型。

  2. 输入图像尺寸过大:如果输入的图像尺寸很大,会增加推理的计算量,导致推理速度较慢。可以尝试将图像尺寸调整为更小的尺寸。

  3. 批处理大小过小:如果批处理大小设置得太小,会导致GPU利用率较低,从而影响推理速度。可以尝试增大批处理大小。

  4. 使用的设备不支持GPU加速:如果使用的设备不支持GPU加速,即使安装了onnxruntime-gpu,推理仍然会在CPU上运行,导致速度慢。可以确认设备是否支持GPU加速。

  5. 模型转换参数设置不合理:在转换模型时,可能需要根据实际情况调整一些参数,例如是否使用半精度(FP16)、是否进行优化等。可以尝试调整这些参数,看看是否会影响推理速度。

以上是一些可能的原因,具体原因还需要根据实际情况进行排查。可以尝试调整一些参数,或者使用其他工具或框架进行推理,看看是否能够改善推理速度。

【相关推荐】



  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7782167
  • 你也可以参考下这篇文章:yolov5的onnx推断示例和思路记录(包含detect.py的最新源码解读)
  • 除此之外, 这篇博客: yolov5检测图片用detect.py中的 一、检测问题解决 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

    今天在用detect.py以及自己训练的模型检测图片时,遇到了一些问题,在这总结一下子
    1、修改代码
    看下面这段代码,是yolo.py中的Model类中的forward函数,训练的时候augment=False,而检测时我们得把它改为true,augment=True
    ------------------我又来了,真的切记训练时把它改为false,不然真的会报错还不知道错哪了!!!!!!!!!!!!

        def forward(self, x, augment=True, profile=False):   # 训练:augment=False
            if augment:    # TTA(Test Time Augmentation) 只在测试和检测的时候做的数据增强
                return self.forward_augment(x)  # augmented inference, None
            else:          # 如果是训练的过程则执行else
                return self.forward_once(x, profile)  # single-scale inference, train
    

    2、还有一个特别值得注意的问题是,当你使用你自己的训练模型检测图片时,你的网络模型得用的是和训练时一模一样的,不能修改,不然会报错,因为在检测时,也会执行yolo.pydetect.py文件
    例如,我训练模型时用的concat模块是这样的:(common.py文件中)
    这是我把原来的concat模块给改了

    # biFPN 1
    class Concat(nn.Module):
        def __init__(self, c1):
            super(Concat, self).__init__()
            # self.relu = nn.ReLU()
            self.w = nn.Parameter(torch.ones(2, dtype=torch.float32), requires_grad=True)
            self.epsilon = 0.0001
            self.swish = Swish()
    
        def forward(self, x):
            weight = self.w / (torch.sum(self.w, dim=0) + self.epsilon)
            # Connections for P6_0 and P7_0 to P6_1 respectively
            x = self.swish(weight[0] * x[0] + weight[1] * x[1])
            return x
    

    然而我检测时又用了原来的concat模块:

    # 原
     class Concat(nn.Module):
         # Concatenate a list of tensors along dimension
         def __init__(self, dimension=1):
             super(Concat, self).__init__()
             self.d = dimension
    
         def forward(self, x):
             return torch.cat(x, self.d)
    

    这样的话当然是不行的哈


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^