修改yolov5的detect层,提高Triton推理服务的性能

博客围绕Yolov5在Infer模式下的性能优化展开。默认detect层输出数据处理时间长,影响推理服务性能。通过将模型转换为TensorRT engine并部署在Triton Inference Server进行测试,对detect层改造后,不同batch size下吞吐量等性能指标均有显著提升。

Infer模式下, yolov5 默认的detect层输出的数据是一个形状为[batches, 25200, 85]的张量。如果部署在Nvidia Triton中,输出层的张量大小过大,处理输出的时间会变大,造成队列积压。 特别是在Triton ServerClient不在同一台机器,无法使用shared memory的情况下,通过网络将数据传输到client的时间还会变大,影响推理服务的性能。 相关代码链接


1. 测试方法

将模型转换为tensorrt engine, 并部署在Triton Inference Server,instance group数量为1,类型为GPU,在其他机器上通过Triton提供的perf_analyzer工具进行性能测试。

  • 将yolov5s.pt转换为onnx格式
  • 将onnx转换为tensorrt engine

    /usr/src/tensorrt/bin/trtexec  \
    --onnx=yolov5s.onnx \
    --minShapes=images:1x3x640x640 \
    --optShapes=images:8x3x640x640 \
    --maxShapes=images:32x3x640x640 \
    --workspace=4096 \
    --saveEngine=yolov5s.engine \
    --shapes=images:1x3x640x640 \
    --verbose \
    --fp16 \
    > result-FP16.txt
    
  • 部署在Triton Inference Server

    模型上传到Triton server 设置的model repository路径,编写模型服务配置

  • 生成真实数据

    python generate_input.py --input_images <image_path> ----output_file <real_data>.json
    
  • 利用真实数据进行性能测试

    perf_analyzer  -m <triton_model_name>  -b 1  --input-data <real_data>.json  --concurrency-range 1:10  --measurement-interval 10000  -u <triton server endpoint> -i gRPC  -f <triton_model_name>.csv
    

2. 修改前的性能指标

如下为使用默认detect层的yolov5 trt engine, 部署在triton的性能测试结果,可以看到,使用默认的detect层,大量时间消耗在队列积压(Server Queue)和输出数据的处理(Server Compute Output),吞吐量甚至达不到 1 infer/sec

除了吞吐,其余指标的单位均为us, 其中Client Send和Client Recv分别为gRPC序列化、反序列化数据的时间

Concurrency Inferences/Second Client Send Network+Server Send/Recv Server Queue Server Compute Input Server Compute Infer Server Compute Output p90 latency
1 0.7 1683 1517232 466 8003 4412 9311 1592936
2 0.8 1464 1514475 393 10659 4616 956736 2583025
3 0.7 2613 1485868 1013992 7370 4396 1268070 3879331
4 0.7 2268 1463386 2230040 9933 5734 1250245 4983687
5 0.6 2064 1540583 3512025 11057 4843 1226058 6512305
6 0.6 2819 1573869 4802885 10134 4320 1234644 7888080
7 0.5 1664 1507386 6007235 11197 4899 1244482 8854777

因此,改造的一个方案就是将数据层进行精简,在送入nms之前根据conf对bbox进行粗略的筛选, 最后参考tensorrtx中对detect层的处理,将输出改造成形状为[batches, num_bboxes, 6]的向量, 其中num_bboxes=1000

6 = [cx,cy,w,h,conf,cls_id], 其中conf = obj_conf * cls_prob


3. 具体步骤

3.1 clone ultralytics yolov5 repo

git clone -b v6.1 https://github.com/ultralytics/yolov5.git

3.2 改造detect层

将detect的forward函数修改为

def forward(self, x):
    z 
### 如何在树莓派5上配置YOLOv5 #### 准备工作 为了确保一切顺利,在首次连接到新系统时建议先进行一些基本设置。运行 `sudo raspi-config` 来更改默认密码,并可在此处扩展文件系统以便充分利用大容量SD卡的空间[^3]。 #### 安装依赖项 由于YOLOv5基于Python开发,因此需要安装必要的软件包和支持库。这通常涉及到更新现有的包列表并安装特定版本的Python以及pip工具: ```bash sudo apt update && sudo apt upgrade -y sudo apt install python3-pip git -y ``` 对于CUDA支持,考虑到性能优化问题,训练过程推荐在主机而非树莓派上执行,因为TensorFlow框架及其配套软件最初是为了大型机而设计和优化的[^5]。 #### 下载YOLOv5仓库 通过Git克隆官方GitHub上的YOLOv5项目源码至本地环境: ```bash git clone https://github.com/ultralytics/yolov5.git cd yolov5 ``` #### 设置虚拟环境(可选) 创建一个新的Python虚拟环境有助于隔离不同项目的依赖关系冲突: ```bash python3 -m venv venv_yolo source venc_yolo/bin/activate pip install --upgrade pip setuptools wheel ``` #### 安装所需的Python包 根据README.md中的说明来安装YOLOv5所必需的所有Python模块: ```bash pip install -r requirements.txt ``` 完成上述操作之后,就可以开始探索如何利用预训练模型来进行推理测试或是微调现有权重以适应自定义数据集的需求了。 #### 测试安装 验证安装是否成功的一个简单方法就是尝试加载一个预训练好的检测网络并对单张图片实施预测分析: ```python from pathlib import Path import torch from models.common import DetectMultiBackend from utils.dataloaders import IMG_FORMATS, VID_FORMATS, LoadImages, LoadStreams from utils.general import (LOGGER, check_file, check_img_size, check_imshow, colorstr, increment_path, non_max_suppression, print_args, scale_coords, strip_optimizer, xyxy2xywh) weights = 'yolov5s.pt' # model path or triton URL imgsz=(640, 640) # inference size (height, width) conf_thres=0.25 # confidence threshold iou_thres=0.45 # NMS IOU threshold max_det=1000 # maximum detections per image device='' # cuda device, i.e. 0 or 0,1,2,3 or cpu view_img=False # show results save_txt=False # save results to *.txt save_conf=False # save confidences in --save-txt labels classes=None # filter by class: --class 0, or --class 0 2 3 agnostic_nms=False # class-agnostic NMS augment=False # augmented inference visualize=False # visualize features update=False # update all models project='runs/detect' # save results to project/name name='exp' # save results to project/name exist_ok=False # existing project/name ok, do not increment line_thickness=3 # bounding box thickness (pixels) hide_labels=False # hide labels hide_conf=False # hide confidences half=False # use FP16 half-precision inference dnn=False # use OpenCV DNN for ONNX inference model = DetectMultiBackend(weights, device=device, dnn=dnn, data=None, fp16=half) stride, names, pt = model.stride, model.names, model.pt imgsz = check_img_size(imgsz=imgsz, s=stride) # check image size dataset = LoadImages('data/images/zidane.jpg', img_size=imgsz, stride=stride, auto=pt) for path, im, im0s, vid_cap, s in dataset: im = torch.from_numpy(im).to(device) im = im.half() if model.fp16 else im.float() im /= 255 # normalize to [0, 1] pred = model(im, augment=augment, visualize=visualize) pred = non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms, max_det=max_det) for det in pred: gn = torch.tensor(im0s.shape)[[1, 0, 1, 0]] if len(det): det[:, :4] = scale_coords(im.shape[2:], det[:, :4], im0s.shape).round() print("Detection completed.") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值