Vitis-AI量化编译YOLOv5(Pytorch框架)并部署ZCU104(一)(代码已开源) ...

打印 上一主题 下一主题

主题 976|帖子 976|积分 2928





   文章目录

  前言
   一、Vitis-AI Pytorch框架量化(vai_q_pytorch)
  
   二、编写量化脚本并举行量化
  
   三、模型编译
  
  总结
  
  
  
前言

Github仓库上传量化全部源码,需要自取(顺手点一个star)
Vitis-AI量化
https://github.com/kevinsu20/Vitis-ai-zcu104-yolov5
有些hxd情况装不上,这里把我的假造机贴在这里,里面是vitis-ai 2.5情况,有需要本身取。
通过百度网盘分享的文件:Ubuntu-2....zip 链接:百度网盘 请输入提取码 提取码:TF49
--------------------------------------------------------------------------------------------------------------------------------
        虽然Xilinx提供了Vitis-AI用户手册Vitis-AI 2.5用户手册,但是其中对于一些安装和利用介绍极为简略,在安装和利用过程中碰到了一系列问题,以是在这里记载一下利用Vitis-AI过程中遇到的各种坑。


一、Vitis-AI Pytorch框架量化(vai_q_pytorch)

     我们利用的是pytorch框架的yolo模型,在利用vitis-ai量化前根据引导手册,要安装vai_q_pytorch,但是需要注意,我们在安装过程中一直在报错,如下图。

      上图中几个package一直无法下载,一开始根据下方报错,以为是代理问题,我们尝试探求代理服务器去下载,发现还是这几个包无法正常下载。
      细致观察了无法下载的几个package,发现有一个共同特点,就是版本号均为2.5.0,这就很奇怪了,为什么全都是2.5.0版本的package无法下载,于是去看xilinx提供的下载脚本,忽然发现这么一行,该行下令是提供下载地址的,如下图:

      此时恍然大悟啊!官方提供的最新脚本中版本号是2.0.0,而实行安装下令时默认安装版本号是2.5.0,以是下载好的package里没有所需要的版本号,自然无法安装对应package。知道问题后,接下来就是探求2.5.0版本的下载包地址(个人以为Xilinx很狗,这么大的企业,对这些软件的维护,修改信息全都放在GitHub上)。在GitHub Xilinx账号下找到了其更新后的下载脚本,接下来就很简单了,将更新后的脚本copy到conda情况中,重新运行下令即可正常安装。可以看到下图中版本号为精确的2.5.0。

(Ps:精确脚本地址:val_q_pytorch2.5.0脚本)


 二、编写量化脚本并举行量化



      Xilinx用户手册提供的语言可以看一下:

      
      ???一脸问号,这只提供了API接口,里面对于模型的处置处罚,数据的导入完全没有介绍,那就只能本身来写,可以参考官方量化脚本。pytorch模型量化代码(minst数据集手写体辨认)
https://github.com/Xilinx/Vitis-AI-Tutorials/blob/1.4/Design_Tutorials/09-mnist_pyt/files/quantize.py
      可以发现主要包括几部分:读取模型、调用数据集、常规猜测函数(包括Detect、前向传播等等)、量化校准、Xmodel生成。
      首先我们来看一下模型的读取。
  
  1. model = model.to(device)
  2. model_name = "yolov5"
  3.     file_path = os.path.join(args.model_dir, model_name + '.pt')
复制代码
      根据本身选择利用GPU还是CPU。
  
  1. if (torch.cuda.device_count() > 0):
  2.     print('You have',torch.cuda.device_count(),'CUDA devices available')
  3.     for i in range(torch.cuda.device_count()):
  4.       print(' Device',str(i),': ',torch.cuda.get_device_name(i))
  5.     print('Selecting device 0..')
  6.     device = torch.device('cuda:0')
  7.   else:
  8.     print('No CUDA devices available..selecting CPU')
  9.     device = torch.device('cpu')
复制代码
      加载数据集,由于我利用的是Coco数据集,以是Class数为80(具体数字根据本身数据集和所训练的模型决定)。
  
  1. parser.add_argument('--data_dir',default="datasets/val",
  2.     help='Data set directory, when quant_mode=calib, it is for calibration, while quant_mode=test it is for evaluation')
  3. dataloader = create_dataloader(args.data_dir, imgsz=imgsz, batch_size=batch_size, pad=0.5,stride=32,
  4.                                        workers=workers, prefix=colorstr(f'quant: '))[0]
  5. model.eval()
  6.     nc =80 # number of classes
复制代码
      在脚本中加入Detect时需要注意,在用户手册中有这么一段话,如下图。

       可以看到,脚本中只能包含前传函数,以是需要将特征提取中多余的部分注释掉,仅保留下面代码即可。
  
  1. z = []
  2.         for i in range(nl):
  3.             bs, _, ny, nx, _no= x[i].shape
  4.             # x[i] = x[i].view(bs, na, no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
  5.             if grid[i].shape[2:4] != x[i].shape[2:4]:
  6.                     grid[i], anchor_grid[i] = _make_grid(anchors,stride,nx, ny, i)
复制代码
    之后是模型推理部分(部分代码)。
  
  1. x=model(im)
  2.         # ckpt = torch.load(file_path, map_location=device)
  3.         # paras=ckpt['model'].yaml
  4.         nc = 10  # number of classfication
  5.         no = nc+5 #each anchor's output,include nc(class)+conf(1)+xywh(4),故nc+5
  6.         anchors = [[1.25, 1.625, 2, 3.75, 4.125, 2.875], [1.875, 3.8125, 3.875, 2.8125, 3.6875, 7.4375], [3.625, 2.8125, 4.875, 6.1875, 11.65625, 10.1875]]
  7.         nl = 3  # number of detection layers
  8.         na = 3  # number of anchors
  9.         grid = [torch.zeros(1)] * nl  # init grid
  10.         anchors = torch.tensor(anchors).float().view(nl, -1, 2)
  11.         # register_buffer('anchors', a)
  12.         anchor_grid=[torch.zeros(1)] * nl
  13.         stride = [8, 16, 32]
复制代码
        脚本写好之后便可以开始模型的量化,分为两步,第一步是量化校准,利用如下下令。可以看到校准过程。
  
  1. python quantize.py --quant_mode calib --subset_len 1
复制代码

         第二部便是生成.Xmodel文件,利用如下下令,可以看到生成过程。

        查看量化后F1参数,精度并没有过多丧失。



 三、模型编译

       这一步才是最轻易踩坑的地方!!可以看到上一步量化后精度还是很不错的!此时大部分工作已经完成,编译时候仅需要一行下令就可以解决,选择相对应FPGA开辟板DPU的型号:
  
  1. vai_c_xir -x ./quantize_result/DetectMultiBackend_int.xmodel -a /opt/vitis_ai/compiler/arch/DPUCZDX8G/ZCU104/arch.json -o ./ -n model
复制代码
       很简单对吧!但是编译结束后,我们发现有多个DPU子图的模型(下图红框位置),说明此时模型并没有被完整的量化编译过来。
​      

       红框位置精确编译后应该只会生成一个子图,也就是DPU subgraph number为1,那么问题出在哪里呢?
       首先需要检查量化脚本中是否按照手册要求仅保留前传函数,别的函数均移除,颠末检查是没有问题的。
       那么问题只能是模型中存在了DPU不能够辨认的算子,才会导致生成多个子图,我们打开DPUCZDX8G产品指南,可以清楚看到该型号下DPU所支持的算子,如下图。

       信任大家看到后肯定明白问题出在哪里了!那就是激活函数的问题,我们本次yolo模型选用的是yolov5 6.0及以上版本,这些版本中一个显著的变化就是激活函数已经更改为SiLu,我们可以看到SiLu并不在该型号DPU支持算子目录下,为了验证猜想,我们将生成的.Xmodel用Netron工具打开,我们可以看到量化后模型结构(其中一小部分)如下图: 

       可以看到红框部分就是我们所用模型的激活函数,果然!激活函数是silu,不是DPU所支持的算子范例,我们将其改为ReLu,之后重新编译,得到下图:

       可以看到,DPU subgraph number为1!编译成功!! 

   
总结

       以上就是今天要讲的我在利用Vitis-AI过程中才的一些坑,本文仅仅简单介绍了Vitis-AI量化编译的过程,后续在ZCU104开辟板的部署将持续更新。



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

熊熊出没

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表