您现在的位置是:首页 > 技术教程 正文

yolov8实战第三天——yolov8TensorRT部署(python推理)(保姆教学)

admin 阅读: 2024-03-19
后台-插件-广告管理-内容页头部广告(手机)

在上一篇中我们使用自己的数据集训练了一个yolov8检测模型,best.py。

yolov8实战第一天——yolov8部署并训练自己的数据集(保姆式教程)-CSDN博客

yolov8实战第二天——yolov8训练结果分析(保姆式解读)-CSDN博客

接下要对best.py进行TensorRT优化并部署。

TensorRT是一种高性能深度学习推理优化器和运行时加速库,可以为深度学习应用提供低延迟、高吞吐率的部署推理。

TensorRT可用于对超大规模数据中心、嵌入式平台或自动驾驶平台进行推理加速。

TensorRT现已能支持TensorFlow、Caffe、Mxnet、Pytorch等几乎所有的深度学习框架,将TensorRT和NVIDIA的GPU结合起来,能在几乎所有的框架中进行快速和高效的部署推理。

一般的深度学习项目,训练时为了加快速度,会使用多GPU分布式训练。但在部署推理时,为了降低成本,往往使用单个GPU机器甚至嵌入式平台(比如 NVIDIA Jetson)进行部署,部署端也要有与训练时相同的深度学习环境,如caffe,TensorFlow等。

由于训练的网络模型可能会很大(比如,inception,resnet等),参数很多,而且部署端的机器性能存在差异,就会导致推理速度慢,延迟高。这对于那些高实时性的应用场合是致命的,比如自动驾驶要求实时目标检测,目标追踪等。

为了提高部署推理的速度,出现了很多模型优化的方法,如:模型压缩、剪枝、量化、知识蒸馏等,这些一般都是在训练阶段实现优化。

而TensorRT 则是对训练好的模型进行优化,通过优化网络计算图提高模型效率。

一、安装TensorRT  

Log in | NVIDIA Developer

下载TensorRT 。

我下载的是8.6里画黑线的那个。 

将 TensorRT-8.6.1.6\include中头文件 copy 到C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\include
将TensorRT-8.6.1.6\lib 中所有lib文件 copy 到C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\lib\x64
将TensorRT-8.6.1.6\lib 中所有dll文件copy 到C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\bin

在python文件夹中找到适合自己的。

pip install tensorrt-8.6.1-cp310-none-win_amd64.whl

 至此TensorRT安装完成。

 二、pt转onnx:

GitHub - triple-Mu/YOLOv8-TensorRT: YOLOv8 using TensorRT accelerate !

参考着这个,下载,安装环境后。

安装onnx:

  1. pip install onnx -i https://pypi.tuna.tsinghua.edu.cn/simple
  2. pip install onnxsim -i https://pypi.tuna.tsinghua.edu.cn/simple
  3. pip install onnxruntime -i https://pypi.tuna.tsinghua.edu.cn/simple

生成onnx: 

python export-det.py --weights yolov8n.pt --iou-thres 0.65 --conf-thres 0.25 --topk 100 --opset 11 --sim --input-shape 1 3 640 640 --device cuda:0

使用上篇文章中的老鼠模型做了测试: 

onnx的测试代码:

  1. import onnxruntime as rt
  2. import numpy as np
  3. import cv2
  4. import matplotlib.pyplot as plt
  5. def nms(pred, conf_thres, iou_thres):
  6. conf = pred[..., 4] > conf_thres
  7. box = pred[conf == True]
  8. cls_conf = box[..., 5:]
  9. cls = []
  10. for i in range(len(cls_conf)):
  11. cls.append(int(np.argmax(cls_conf[i])))
  12. total_cls = list(set(cls))
  13. output_box = []
  14. for i in range(len(total_cls)):
  15. clss = total_cls[i]
  16. cls_box = []
  17. for j in range(len(cls)):
  18. if cls[j] == clss:
  19. box[j][5] = clss
  20. cls_box.append(box[j][:6])
  21. cls_box = np.array(cls_box)
  22. box_conf = cls_box[..., 4]
  23. box_conf_sort = np.argsort(box_conf)
  24. max_conf_box = cls_box[box_conf_sort[len(box_conf) - 1]]
  25. output_box.append(max_conf_box)
  26. cls_box = np.delete(cls_box, 0, 0)
  27. while len(cls_box) > 0:
  28. max_conf_box = output_box[len(output_box) - 1]
  29. del_index = []
  30. for j in range(len(cls_box)):
  31. current_box = cls_box[j]
  32. interArea = getInter(max_conf_box, current_box)
  33. iou = getIou(max_conf_box, current_box, interArea)
  34. if iou > iou_thres:
  35. del_index.append(j)
  36. cls_box = np.delete(cls_box, del_index, 0)
  37. if len(cls_box) > 0:
  38. output_box.append(cls_box[0])
  39. cls_box = np.delete(cls_box, 0, 0)
  40. return output_box
  41. def getIou(box1, box2, inter_area):
  42. box1_area = box1[2] * box1[3]
  43. box2_area = box2[2] * box2[3]
  44. union = box1_area + box2_area - inter_area
  45. iou = inter_area / union
  46. return iou
  47. def getInter(box1, box2):
  48. box1_x1, box1_y1, box1_x2, box1_y2 = box1[0] - box1[2] / 2, box1[1] - box1[3] / 2, \
  49. box1[0] + box1[2] / 2, box1[1] + box1[3] / 2
  50. box2_x1, box2_y1, box2_x2, box2_y2 = box2[0] - box2[2] / 2, box2[1] - box1[3] / 2, \
  51. box2[0] + box2[2] / 2, box2[1] + box2[3] / 2
  52. if box1_x1 > box2_x2 or box1_x2 < box2_x1:
  53. return 0
  54. if box1_y1 > box2_y2 or box1_y2 < box2_y1:
  55. return 0
  56. x_list = [box1_x1, box1_x2, box2_x1, box2_x2]
  57. x_list = np.sort(x_list)
  58. x_inter = x_list[2] - x_list[1]
  59. y_list = [box1_y1, box1_y2, box2_y1, box2_y2]
  60. y_list = np.sort(y_list)
  61. y_inter = y_list[2] - y_list[1]
  62. inter = x_inter * y_inter
  63. return inter
  64. def draw(img, xscale, yscale, pred):
  65. img_ = img.copy()
  66. if len(pred):
  67. for detect in pred:
  68. detect = [int((detect[0] - detect[2] / 2) * xscale), int((detect[1] - detect[3] / 2) * yscale),
  69. int((detect[0]+detect[2] / 2) * xscale), int((detect[1]+detect[3] / 2) * yscale)]
  70. img_ = cv2.rectangle(img, (detect[0], detect[1]), (detect[2], detect[3]), (0, 255, 0), 1)
  71. return img_
  72. if __name__ == '__main__':
  73. height, width = 640, 640
  74. img0 = cv2.imread('mouse-4-6-0004.jpg')
  75. x_scale = img0.shape[1] / width
  76. y_scale = img0.shape[0] / height
  77. img = img0 / 255.
  78. img = cv2.resize(img, (width, height))
  79. img = np.transpose(img, (2, 0, 1))
  80. data = np.expand_dims(img, axis=0)
  81. sess = rt.InferenceSession('best.onnx')
  82. input_name = sess.get_inputs()[0].name
  83. label_name = sess.get_outputs()[0].name
  84. pred = sess.run([label_name], {input_name: data.astype(np.float32)})[0]
  85. pred = np.squeeze(pred)
  86. pred = np.transpose(pred, (1, 0))
  87. pred_class = pred[..., 4:]
  88. pred_conf = np.max(pred_class, axis=-1)
  89. pred = np.insert(pred, 4, pred_conf, axis=-1)
  90. result = nms(pred, 0.3, 0.45)
  91. ret_img = draw(img0, x_scale, y_scale, result)
  92. ret_img = ret_img[:, :, ::-1]
  93. plt.imshow(ret_img)
  94. plt.show()

三、TensorRT部署

导出engine模型:

python build.py --weights yolov8n.onnx --iou-thres 0.65 --conf-thres 0.25 --topk 100 --fp16 --device cuda:0

等待一会,engine成功导出。 

 

使用python脚本进行推理:

python infer-det.py --engine yolov8n.engine --imgs data --show --out-dir outputs --out-dir outputs --device cuda:0

infer-det.py: 

  1. from models import TRTModule # isort:skip
  2. import argparse
  3. from pathlib import Path
  4. import cv2
  5. import torch
  6. from config import CLASSES, COLORS
  7. from models.torch_utils import det_postprocess
  8. from models.utils import blob, letterbox, path_to_list
  9. def main(args: argparse.Namespace) -> None:
  10. device = torch.device(args.device)
  11. Engine = TRTModule(args.engine, device)
  12. H, W = Engine.inp_info[0].shape[-2:]
  13. # set desired output names order
  14. Engine.set_desired(['num_dets', 'bboxes', 'scores', 'labels'])
  15. images = path_to_list(args.imgs)
  16. save_path = Path(args.out_dir)
  17. if not args.show and not save_path.exists():
  18. save_path.mkdir(parents=True, exist_ok=True)
  19. for image in images:
  20. save_image = save_path / image.name
  21. bgr = cv2.imread(str(image))
  22. draw = bgr.copy()
  23. bgr, ratio, dwdh = letterbox(bgr, (W, H))
  24. rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)
  25. tensor = blob(rgb, return_seg=False)
  26. dwdh = torch.asarray(dwdh * 2, dtype=torch.float32, device=device)
  27. tensor = torch.asarray(tensor, device=device)
  28. # inference
  29. data = Engine(tensor)
  30. bboxes, scores, labels = det_postprocess(data)
  31. if bboxes.numel() == 0:
  32. # if no bounding box
  33. print(f'{image}: no object!')
  34. continue
  35. bboxes -= dwdh
  36. bboxes /= ratio
  37. for (bbox, score, label) in zip(bboxes, scores, labels):
  38. bbox = bbox.round().int().tolist()
  39. cls_id = int(label)
  40. cls = CLASSES[cls_id]
  41. color = COLORS[cls]
  42. cv2.rectangle(draw, bbox[:2], bbox[2:], color, 2)
  43. cv2.putText(draw,
  44. f'{cls}:{score:.3f}', (bbox[0], bbox[1] - 2),
  45. cv2.FONT_HERSHEY_SIMPLEX,
  46. 0.75, [225, 255, 255],
  47. thickness=2)
  48. if args.show:
  49. cv2.imshow('result', draw)
  50. cv2.waitKey(0)
  51. else:
  52. cv2.imwrite(str(save_image), draw)
  53. def parse_args() -> argparse.Namespace:
  54. parser = argparse.ArgumentParser()
  55. parser.add_argument('--engine', type=str, help='Engine file')
  56. parser.add_argument('--imgs', type=str, help='Images file')
  57. parser.add_argument('--show',
  58. action='store_true',
  59. help='Show the detection results')
  60. parser.add_argument('--out-dir',
  61. type=str,
  62. default='./output',
  63. help='Path to output file')
  64. parser.add_argument('--device',
  65. type=str,
  66. default='cuda:0',
  67. help='TensorRT infer device')
  68. args = parser.parse_args()
  69. return args
  70. if __name__ == '__main__':
  71. args = parse_args()
  72. main(args)

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索
排行榜