Vitis-AI量化编译YOLOv5(Pytorch框架)并部署ZCU104(二)

这篇具有很好参考价值的文章主要介绍了Vitis-AI量化编译YOLOv5(Pytorch框架)并部署ZCU104(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录


第一章  Vitis-AI量化编译YOLOv5(Pytorch框架)并部署ZCU104(一)

第二章  Vitis-AI量化编译YOLOv5(Pytorch框架)并部署ZCU104(二)


目录

系列文章目录

前言

一、Netron查看网络结构

二、与开发板建立通信

1.设置主机

2.设置开发板

三、C++ API编写

四、编译运行

总结


前言

第一章已经详细介绍了在主机利用Vitis-Ai进行量化编译后,成功生成了.Xmodel文件,本章主要介绍如何将.Xmodel部署到ZCU104,并利用C++ API进行目标检测。


一、Netron查看网络结构

Netron是一种用于神经网络、深度学习和机器学习模型的可视化工具,它可以为模型的架构生成具有描述性的可视化(descriptive visualization)

使用这一工具好处在于不需要下载,在线导入即可立即生成模型结构。(Netron 在线工具)

将生成的.Xmodel导入后,可以看到会生成如下可视化网络结构。(部分结构,全部结构太大了,自己去寻找自己所需要的部分即可)

xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习

 双击每一部分即可看到Input、Output具体信息。在这里主要是看输出层的名字,可以看到共有四个输出层,并且可看到这四个输出层名字。

xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习               xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习

          xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习

 可以看到4个输出层的名字和dim。(这里有一点,dim应该为128,256,512三层,但是中间多出一个输出层,dim为384,但是不影响检测,后续代码检测四层输出即可)

二、与开发板建立通信

1.设置主机

 为了方便,用网线直接将板子和PC连接,接下来就是配置同一网段的问题

我在学校用的是校园网,所以为了方便之后开发板可以联网,直接将WiFi网络给以太网共享,如下图。

xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习

之后确认之后,以太网的IPV4地址可以自动分配,下图是我的IPV4地址。

xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习

 可以看到主机网段是192.168.137,所以只需要将开发板设置到同一网段即可。

2.设置开发板

我使用的是MobaXterm串口软件,首先用Serial串口软件与开发板相连接,因为使用了usb与主机相连接,具体端口查看自己的设备管理器即可。比如我的端口为COM9,如下图。

xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习

 接下来将板子配置到PC同一网段(192.168.137),这里我选择将其配置为192.168.137.221.

ifconfig //可以查看当前网络信息
ifconfig eth0 192.168.137.221 //设置板子IP地址

 之后仍然使用MobaXterm,用ssh与板子建立远程连接,如下图。

xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习

三、C++ API编写

首先需要看手册中C++ API的函数使用。

// create runner
auto runner = vart::Runner::create_runner(dpu_subgraph, ”run”);
// get input tensors
auto input_tensors = runner->get_input_tensors();
// get input tensor buffers
auto input_tensor_buffers = std::vector<vart::TensorBuffer*>();
 for (auto input : input_tensors) {
 auto t = vart::alloc_cpu_flat_tensor_buffer(input);
 input_tensor_buffers.emplace_back(t.get());
}
// get output tensors
auto output_tensors = runner->get_output_tensors();
// get output tensor buffers
auto output_tensor_buffers = std::vector< vart::TensorBuffer*>();
for (auto output : output _tensors) {
 auto t = vart::alloc_cpu_flat_tensor_buffer(output);
 output_tensor_buffers.emplace_back(t.get());
}
// sync input tensor buffers
for (auto& input : input_tensor_buffers) {
 input->sync_for_write(0, input->get_tensor()->get_data_size() /
 input->get_tensor()->get_shape()[0]);
}
// run runner
auto v = runner->execute_async(input_tensor_buffers, output_tensor_buffers);
auto status = runner->wait((int)v.first, 1000000000);
// sync output tensor buffers
for (auto& output : output_tensor_buffers) {
 output->sync_for_read(0, output->get_tensor()->get_data_size() /
 output->get_tensor()->get_shape()[0]);
}

可以看到create 、get input 、get output等API的写法,DPU使用4个runner,代码如下:

auto graph = xir::Graph::deserialize(argv[2]);
  auto subgraph = get_dpu_subgraph(graph.get());
  CHECK_EQ(subgraph.size(), 1u)
      << "yolov3 should have one and only one dpu subgraph.";
  LOG(INFO) << "create running for subgraph: " << subgraph[0]->get_name();

  auto runner = vart::Runner::create_runner(subgraph[0], "run");
  auto runner1 = vart::Runner::create_runner(subgraph[0], "run");
  auto runner2 = vart::Runner::create_runner(subgraph[0], "run");
  auto runner3 = vart::Runner::create_runner(subgraph[0], "run");
  //auto runner4 = vart::Runner::create_runner(subgraph[0], "run");
  // get in/out tenosrs
  auto inputTensors = runner->get_input_tensors();
  auto outputTensors = runner->get_output_tensors();
  int inputCnt = inputTensors.size();
  int outputCnt = outputTensors.size();
  // init the shape info
  TensorShape inshapes[inputCnt];
  TensorShape outshapes[outputCnt];
  shapes.inTensorList = inshapes;
  shapes.outTensorList = outshapes;
  getTensorShape(runner.get(), &shapes, inputCnt,
                 //{"layer81", "layer93", "layer105", "layer117"});
                 //{"DetectMultiBackend__DetectMultiBackend_Model_model__Detect_model__Detect_24__Conv2d_m__ModuleList_0__9160", "DetectMultiBackend__DetectMultiBackend_Model_model__Detect_model__Detect_24__Conv2d_m__ModuleList_1__9207", "DetectMultiBackend__DetectMultiBackend_Model_model__Detect_model__Detect_24__Conv2d_m__ModuleList_2__9254"});
{"DetectMultiBackend__DetectMultiBackend_Model_model__Detect_model__Detect_33__Conv2d_m__ModuleList_1__12481", "DetectMultiBackend__DetectMultiBackend_Model_model__Detect_model__Detect_33__Conv2d_m__ModuleList_0__12434", "DetectMultiBackend__DetectMultiBackend_Model_model__Detect_model__Detect_33__Conv2d_m__ModuleList_2__12528","DetectMultiBackend__DetectMultiBackend_Model_model__Detect_model__Detect_33__Conv2d_m__ModuleList_3__12575"});

最后一行 getTensorShape 是我们需要得到输出张量的输出层名字,此时就需要步骤一中Netron查看结构所得到名字。

其次是Detect部分,网上现有的包括GitHub中基本上全都是用Python进行编写的,几乎没有C++,所以需要自己整理一下思路。

第一个思路:如果串行处理,也就是读取视频每一帧,送到DPU处理,再输出显示为视频。这样子可以吗?很明显有缺陷,如果读帧速度和DPU处理速度相冲突,必然会造成堵塞或进程崩溃,所以这个思路不可行。

第二个思路:串行行不通,很明显,并行是可以的。分为三个进程,第一个进程处理视频,读取每一帧并存入输入帧队列;第二个进程DPU读取输入帧队列,只要输入帧队列不空,就每次取一帧进行检测;第三个进程将DPU输出帧放入输出队列,并转换为视频进行输出。为了提供检测速率,共设置六个进程,一个进程作为输入帧队列,一个进程作为输出帧队列,其余进程用于DPU进行帧检测。

四、编译运行

因为自己制作的Linux系统没有GUI界面,所以如果直接用Serial相连,命令行运行输出展示时会报错,所以我们利用MobaXterm进行ssh连接,主要是为了利用ssh连接所提供的X11 server。可以看到,编译后运行命令:

./test video/test.webm ./yolov5.xmodel

视频格式看自己的opencv库,我的opencv很奇怪,不支持mp4或avi格式,可以看到检测效果如下:

xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习

可以看到居然只有5帧左右。???很奇怪,按理说DPU会加速,怎么帧率这么低呢?分析一下原因:

1、ssh连接的问题。我们知道ssh相当于远程服务器连接,DPU推理结果最后生成的视频是由板子所产生的,而最后是在主机也就是本地展示的视频,所以相当于远程服务器推理完成后再传输至本地进行展示,会有一定的延迟,也就造成了帧率的降低。

2、mobaxterm ssh传输速率低。和第一个问题类似,主要是因为ssh传输所带来的问题。

所以根据分析尝试进行解决,两个方案:

1、换用别的更好的串口软件,寻找ssh传输速率更高的方法。我又尝试了两个软件:

Xmanager:

xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习

 Putty:

xmodel部署到开发板,Vitis-Ai部署全过程,fpga开发,人工智能,pytorch,深度学习

可以看到,帧率显著提高了,所以第一次帧率过低确实是ssh传输所导致。此时在分辨率为640*640的情况下,FPS可以稳定在15帧,所以大胆推测一波,若直接输出视频,帧率还会更高。         

所以接下来可以改进一下代码,先不输出视频,检测完后将视频保存到本地,就不会出现传输延时的情况,之后实现后会继续更新! 


总结

至此,用Vitis-AI部署的全过程就做完了,时间很仓促,前后大约只做了一周左右的时间,之前一个月从0开始做PYNQ,也算是对Xilinx的软硬件结合开发有了一定得了解。

这次DPU用的是Xilinx的小黑盒,明年要做自己编写的深度学习协处理器,并基于Risc-V进行开发,之后再更新!文章来源地址https://www.toymoban.com/news/detail-781993.html

到了这里,关于Vitis-AI量化编译YOLOv5(Pytorch框架)并部署ZCU104(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【问题记录】树莓派+OpenCV+YOLOv5目标检测(Pytorch框架)

     -【学习资料】 子豪兄的零基础树莓派教程 https://github.com/TommyZihao/ZihaoTutorialOfRaspberryPi/blob/master/%E7%AC%AC2%E8%AE%B2%EF%BC%9A%E6%A0%91%E8%8E%93%E6%B4%BE%E6%96%B0%E6%89%8B%E6%97%A0%E7%97%9B%E5%BC%80%E6%9C%BA%E6%8C%87%E5%8D%97.md#%E7%83%A7%E5%BD%95%E9%95%9C%E5%83%8F 第2讲:树莓派新手无痛开机指南【子豪兄的树莓派

    2024年02月02日
    浏览(56)
  • 【解惑笔记】树莓派+OpenCV+YOLOv5目标检测(Pytorch框架)

     -【学习资料】 子豪兄的零基础树莓派教程 https://github.com/TommyZihao/ZihaoTutorialOfRaspberryPi/blob/master/%E7%AC%AC2%E8%AE%B2%EF%BC%9A%E6%A0%91%E8%8E%93%E6%B4%BE%E6%96%B0%E6%89%8B%E6%97%A0%E7%97%9B%E5%BC%80%E6%9C%BA%E6%8C%87%E5%8D%97.md#%E7%83%A7%E5%BD%95%E9%95%9C%E5%83%8F 第2讲:树莓派新手无痛开机指南【子豪兄的树莓派

    2024年02月14日
    浏览(38)
  • 模型量化(6):Yolov5 QAT量化训练

    2023年08月06日
    浏览(53)
  • 【AI】yolov5:数据下载、图像标注、训练、预测等,超详细笔记;pytorch转onnx再转TensorRT;训练识别口罩

    https://gitcode.net/mirrors/ultralytics/yolov5/ 1)安装pytorch 2)安装cudnn 3)下载yolov5源码: 4)安装yolov5依赖

    2024年02月15日
    浏览(45)
  • YOLOV5 INT8 量化对比

    对比了两种INT8量化, 熵校准的量化有更高的速度,但是吧… 最大最小值校准是一种 INT8 校准算法。在最大最小值校准中, 需要使用一组代表性的校准数据来生成量化参数, 首先将推理中的数据进行统计,计算数据的最小值和最大值,然后根据这些值来计算量化参数。具体步

    2024年02月16日
    浏览(43)
  • YOLOV5-模型轻量化的一些常见方法

    欢迎关注、点赞、评论! YOLOv5是一个基于深度学习的目标检测算法,是YOLO系列算法的最新版本。YOLO是You Only Look Once的缩写,意味着只需要一次前向传递就可以完成目标检测任务,因此具有非常快的检测速度和较高的精度。 相比于YOLOv4,YOLOv5在多个方面进行了改进和优化,包

    2024年01月22日
    浏览(45)
  • TensorRT量化实战课YOLOv7量化:pytorch_quantization介绍

    手写 AI 推出的全新 TensorRT 模型量化实战课程,链接。记录下个人学习笔记,仅供自己参考。 该实战课程主要基于手写 AI 的 Latte 老师所出的 TensorRT下的模型量化,在其课程的基础上,所整理出的一些实战应用。 本次课程为 YOLOv7 量化实战第一课,主要介绍 TensorRT 量化工具箱

    2024年02月07日
    浏览(48)
  • YOLOv5改进实战 | 更换主干网络Backbone(一)之轻量化网络Ghostnet

    前言 轻量化网络设计 是一种针对移动设备等资源受限环境的深度学习模型设计方法。下面是一些常见的轻量化网络设计方法: 网络剪枝 :移除神经网络中冗余的连接和参数,以达到模型压缩和加速的目的。 分组卷积 :将卷积操作分解为若干个较小的卷积操作,并将它们分

    2024年02月05日
    浏览(45)
  • OpenVINO 2022.3实战六:NNCF 实现 YOLOv5 模型 INT8 量化

    使用OpenVINO模型优化器将YOLOv5模型转换为OpenVINO IR格式,以便在Intel硬件上进行推理。 下载yolov5代码 ultralytics/yolov5 导出模型为onnx模型,接着使用mo导出openvino fp32和fp16模型 将训练数据集准备成可用于量化的格式。 配置量化管道,例如选择适当的量化算法和设置目标精度。 在

    2024年02月08日
    浏览(43)
  • YOLOv5改进实战 | 更换主干网络Backbone(四)之轻量化模型MobileNetV3

    前言 轻量化网络设计 是一种针对移动设备等资源受限环境的深度学习模型设计方法。下面是一些常见的轻量化网络设计方法: 网络剪枝 :移除神经网络中冗余的连接和参数,以达到模型压缩和加速的目的。 分组卷积 :将卷积操作分解为若干个较小的卷积操作,并将它们分

    2024年02月07日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包