Steins;Lab

某团的自留研究所

PYNQ上手体验:以目标检测应用为例

最近拿到了基于ZYNQ 7020器件的PYNQ开发板,便有了这篇体验文章。本文首先进行常规的开箱和初见印象描述;随后尝试解释了ZYNQ这一硬件的特色;最后以目标检测为例,体验了PYNQ的开发流程。

 

之前接近半年的时间都在使用ZYNQ这款器件,并用ZYNQ这款器件完成我的毕业设计。

有幸的是,Xilinx家的官方开发板,从zc706,到zcu102、zcu106,我都有实际地使用过。

实事求是地讲,作为一个软件开发者,ZYNQ这种ARM+FPGA的架构,在我这里的开发思路更像是个大个儿树莓派+FPGA协处理器。由于涉及到了FPGA硬件,若要发挥出其最大的优势,开发思路并不是码完代码直接跑这样单纯。关于这点在下文中将尝试对ZYNQ进行解释,ZYNQ是个比较有趣的硬件平台

本文首先进行常规的开箱和初见印象描述,随后尝试解释了ZYNQ这一硬件的特色。最后以目标检测为例,体验了PYNQ的开发流程。

1 开箱与初见

我拿到的是PYNQ Z2版本,是由Tul出品的。在国内依元素大学计划拿到,开发板套装1350元。包装比较简洁,附带电源适配器网线亚克力壳等等。

板子正面比较简洁。整体色调为粉色。第一眼可以看到有数个PMOD接口、Raspberry Pi兼容接口、Arduino 拓展板接口。核心器件 ZYNQ7020已经被散热片覆盖。

在官方推崇的主流开发流程中,只需网线和供电,配合jupyter即可完成大部分开发操作。

因此大部分情况下,它通过Ethernet接入你的PC或者局域网后,只需安静地躺在桌子旁边。必要时可连接USB URAT进行debug。

PYNQ Z2的简要规格如下,我关心的一些参数加粗了:

ZYNQ XC7Z020-1CLG400C
650MHz dual-core Cortex-A9 processor
DDR3 memory controller with 8 DMA channels and
4 High Performance AXI3 Slave ports
• High-bandwidth peripheral controllers: 1G Ethernet, 
  USB 2.0, SDIO
• Low-bandwidth peripheral controller:
SPI, UART, CAN, I2C
• Programmable from JTAG, Quad-SPI flash,
and MicroSD card
• Programmable logic equivalent to Artix-7 FPGA
13,300 logic slices, each with four 6-input LUTs
and 8 flip-flops
630 KB of fast block RAM
• 4 clock management tiles, each with a phase
locked loop (PLL) and mixed-mode clock
manager (MMCM)
220 DSP slices
• On-chip analog-to-digital converter (XADC)
Memory
512MB DDR3 with 16-bit bus @ 1050Mbps
• 16MB Quad-SPI Flash with factory programmed
48-bit globally unique EUI-48/64™ compatible
identifier
• MicroSD slot
Power
• Powered from USB or 7V-15V external power source
USB and Ethernet
• Gigabit Ethernet PHY
• Micro USB-JTAG Programming circuitry
• Micro USB-UART bridge
USB 2.0 OTG PHY (supports host only)
Audio and Video
• HDMI sink port (input)
• HDMI source port (output)
• I2S interface with 24bit DAC with 3.5mm TRRS jack
• Line-in with 3.5mm jack
Switches, Push-buttons and LEDs
• 4 push-buttons
• 2 slide switches
• 4 LEDs
• 2 RGB LEDs
Expansion Connectors
• Two standard Pmod ports
16 Total FPGA I/O (8 shared pins with 
   Raspberry Pi connector)
Arduino Shield connector
• 24 Total FPGA I/O
• 6 Single-ended 0-3.3V Analog inputs to XADC
• Raspberry Pi connector
• 28 Total FPGA I/O (8 shared pins with Pmod
A port)

 

2 ZYNQ与PYNQ

2.1 ZYNQ片上系统

ZYNQ是Xilinx出品的片上系统(SoC,System On Chip)。SoC指单个硅芯片可以来实现整个系统的功能,往往该系统可能需要多个不同的芯片。在消费电子中,你可能比较熟悉高通的手机处理器骁龙系列,没错,骁龙就是典型的SoC,它在一片SoC上集成了移动宽带解调与多媒体、3D图形、GPS等功能。SoC意味着是解决方案,往往有着更好的数据传输、更低功耗和更小的空间占用。

我们今天的主角ZYNQ的架构图如下。在这一片SoC中,将处理系统Process System可编程逻辑Programmable System集合起来,其间使用片内AXI总线连接。

图: Zynq架构简化模型[Zynq Book – http://www.zynqbook.com/]

 

 

2.1.1 处理系统Process System

处理系统为上述蓝色部分,简称PS端。在一片典型的Zynq 7000系列SoC上,可以是:

  • 双核ARM Cortex-A9处理器

看到这里熟悉ARM的同学会明白,如果单看PS端,它就是一片基于ARM的处理器,可以用来支撑部分硬件接口、操作系统、应用层程序。

事实上,把它当普通的ARM来进行软件开发没有任何不妥。

 

 

2.1.2 可编程逻辑Programmable System

黄色部分为可编程逻辑,简称PL端。在一片典型的Zynq 7000系列SoC上,可以是:

  •  Artix-7 FPGA

FPGA的全称是Field-Programmable Gate Array,现场可编程门阵列。简单理解,它就是一块可以硬件地编程的胶水硬件,由无数个可编程逻辑门组成。我们可以在上“定制”出我们自己想要的专属硬件。

 

 

2.1.3 协同工作

PL 和PS 之间的链接采用了片内AXI总线连接,速度比较理想。

上面已经介绍了PS端和PL端。

软件(PS端)擅长完成一般性的顺序执行任务,如OS、Application和GUI。

硬件(PL端)市场进行数据流计算的任务,尤其是具有并行限制的软件算法。

PL 部分用来实现高速逻辑、算术和数据流子系统是很理想的,而PS支持软件程序和/或操作系统,这就意味着任何被设计的系统的整个功能可以恰当地在硬件和软件之间做出划分。

系统架构的设计通常是自上而下的方法。 那就是先确定顶层的接口和参数,确定底层的子系统或功能。 根据需要将设计适当地分为硬件和软件,并在系统定义中定义必要的通信。

图:http://www.zynqbook.com/

 

因此,ZYNQ的方法论可以归结如下:

  1.  一般逻辑算法在ARM端运行
  2. 大量计算卸载到FPGA端运行
  3. ARM+FPGA高速互联、协同运行

 

 

2.1.4 优势和劣势

我在这里,谨代表我目前作为学生的一些见解,班门弄斧,大家见笑~如果您有任何不同的见解、或者我的论述出现错误,请立即之处,我也可以学习一下~

优势很明显,如此结合的SoC在某些场景,尤其是需要将系统的整个功能可以恰当地在硬件和软件之间做出划分,结合ARM+FPGA优势的场景,ZYNQ会获得天生的集成度。

 

然而我不是来做广告的。我必须指出它的劣势

价格

可以尝试在贸泽电子搜索对比器件价格。ZYNQ的价格绝对说不上低,在量产的情形下,几分几毛钱都值得细究。至于是否上一片ZYNQ,用ARM+FPGA的优势,还是上一篇高性能的其他处理器尝试解决问题,就值得思考了。

开发难度

FPGA对于软件工程师绝对不算友好。可能Xilinx也在考虑这方面,尤其近年来推出了一些结合PS和PL端的开发工具SDSoC,和一些软件栈,来吸引软件工程师,尤其是近年来大火的机器学习、边缘计算应用。但一点点细抠PL端的硬件设计,哪有我用Python在应用层上码代码,立即运行&所见即所得来的开心呢?性能不够我就上志强、堆GPU嘛,反正OpenCV、Caffe等等都自带CUDA驱动。

上升一下,去大学随便看一看,CS的毕业生的毕设有多少人做软件应用?又有几个人做硬件设计?人生苦短。

 

 

 

2.2 PYNQ

PYNQ是Xilinx公司的开源项目,只在使用Python语言和库,让开发者可以更方便的基于ZYNQ创建高性能嵌入式系统,更方便的使用PS-PL结合。

  • 并行硬件执行
  • 高帧率视频处理
  • 硬件加速算法
  • 实时信号处理
  • 高带宽IO
  • 低延迟控制

PYNQ试图将设计流程变得更加友好,面向系统架构师和软件开发工程师。

  • 希望利用Zynq和可编程硬件功能而无需使用ASIC式设计工具来设计硬件的软件开发人员。
  • 系统架构师需要一个简单的软件界面和框架来快速进行原型设计和Zynq设计的开发。
  • 希望他们的设计被最广泛的受众使用的硬件设计师。

PYNQ使用Jupyter Notebook,直接使用基于浏览器对硬件进行交互。

项目官网和文档见 http://www.pynq.io/

个人理解,PYNQ更像是一个创客的玩具。它试图将设计流程变得更加友好,Python也迎合了很多软件开发者的口味。为了更加友好地使用PL端,PYNQ提供了overlay。

Overlay是PYNQ的一个重要概念。官方的描述值得寻味:

PYNQ提供了一个Python接口,允许通过PS中运行的Python控制PL中的Overlay。FPGA设计是一项需要硬件工程知识和专业知识的专业任务。PYNQ的Overlay层由硬件设计人员创建,并包含在此PYNQ Python API中。然后,软件开发人员可以使用Python接口来编程和控制专用硬件Overlay,而无需自己设计。

这类似于由专家开发人员创建的软件库,然后由在应用程序级别工作的许多其他软件开发人员使用。

说的确实有道理,难道我们在写应用层程序时候,不也是用一些常用的轮子软件库吗

图:http://www.zynqbook.com/

 

如果你看了上面的话感到一头雾水,可以结合上图理解:

PYNQ的Overlay就是由硬件专家设计好的硬件协处理器。你现在可以在PYNQ中使用Python接口非常方便调用它!如果你有一定硬件知识,你也可以根据自己的需要自定义Overlay。

作为一篇开箱文,关于Overlay的自定义不在本文中阐述。但是关于Overlay的使用,将在下章涉及。

 

 

 

3 开发流程 – 以目标检测应用为例

说了这么多,我们马上来进入PYNQ的应用层开发吧!

本章首先介绍了PYNQ板卡的准备,然后简单介绍了Tiny YOLO目标检测算法的原理,最后记录了实验结果。

3.1 Get Started

首先我们熟悉一下PYNQ的开发流程。

图:PYNQ上手流程[https://pynq.readthedocs.io/en/latest/getting_started.html]

 

和任何一块开发板上手一样,根据官方引导,首先设置好板上跳帽,烧写好TF卡镜像,开机。

PYNQ推荐将它接入到你的局域网中,或者用以太网连接PC。在官方推崇的主流开发流程中,只需网线和供电,配合jupyter即可完成大部分开发操作。

接入局域网后,由于PYNQ默认的hostname为“PYNQ”,因此,你可以在浏览器中直接输入 http://PYNQ 进入Jupyter notebook。

 

在Jupyter notebook中即可完成大部分Python程序的编写任务,能够获得输入和输出。同时Jupyter notebook也提供了终端模拟器,可以直接从浏览器管理开发板上的Linux。

当然,我已经习惯了用终端来管理我的Linux主机。因此我使用Jupyter notebook + Xshell作为我自己的开发环境。

如果你熟悉Linux,应该已经理解,其将之前较为复杂的ZYNQ开发流程变成了简单易懂的板上Python开发方式。在原本嵌入式Linux的基础上提供了Jupyter notebook,更为方便。

顺带一提,官方的镜像基于Ubuntu 16.04 LTS,架构为armv7l

当然,我更加习惯使用UART串口直接进行板上开发……一下接触了方便的东西反而不适应了……

OK,在PYNQ编写Python程序已经如此简洁,参考:https://pynq.readthedocs.io 查看Python环境、库的信息、overlay的用法等等。

 

 

 

3.2 Tiny YOLO目标检测算法

YOLO是一个神一样的目标检测算法。目标检测,简单来说,输入是一幅图像,输出是检测出目标的类型和图像中的位置。

图:YOLO v3输出示例[https://pjreddie.com/darknet/yolo/]

 

作者项目地址为

https://pjreddie.com/darknet/yolo/

YOLO在工业界也是非常受欢迎的目标检测算法,它精度和速度都很不错,大牛作者也很可爱,感兴趣的同学可以检索下,或者看下近年来目标检测的综述。

 

 

 

3.3 QNN-MO-PYNQ 官方机器学习库

这次我们使用的项目为Xilinx官方的为PYNQ设计的机器学习示例:

https://github.com/Xilinx/QNN-MO-PYNQ

项目中使用的是修改后的Tiny YOLO模型,叫做Tinier-YOLO。在VOC数据集上训练,使用了1bit的权重层和3bit的激活层。

模型如下[https://github.com/Xilinx/QNN-MO-PYNQ]:

 

3.3.1 安装

首先pip安装:

如果报错SSL证书问题,检查你PYNQ板上的时间!如果时间早于目前时间,可能造成SSL整数不生效导致Https拉取失败。

安装完成后,我们可以看到在jupyter中出现了我们刚才安装的库用例。

 

 

3.3.2 初始化

打开tiny-yolo-image-loop.ipynb即可运行我们的Tiny YOLO。但是我们也看下其中的逻辑:

首先导入必要的库。我们在pip安装的时候,安装了qnn库和yolo算法的Darknet库。

然后创建分类器,初始化我们的加速器。

如果你熟悉Darknet框架,一定很眼熟其中的配置文件形式和权重形式。

 

在这个过程中,我们的加速器Overlay被示例化进我们的FPGA中,成为了我们的硬件协加速器!该加速器已经由库设计好。当然,在以后的进阶开发中,我们可以创建自己的协加速器。

具体的Overlay比特流如下(bitstream,可以理解成描述FPGA加速器的文件)。

 

 

3.3.3 软硬协同前向推理

随后是大循环,不断地载入图片,前向推理。最终输出结果。

还记得我们刚才画的模型图吗?YOLO的特点是这样,在一端将图像的像素信息输入,经过前向推理计算,就可以得到检测结果。

在前向推理的过程中,卷积层计算占用了绝大部分时间,因此我们要使用硬件加速的overlay加速我们计算密集的部分。

值得注意的是,在本DEMO中,第一层和最后一层是用CPU软件算的,其余层使用了FPGA硬件协加速器。

 

3.3.4 重置退出

安全退出的方法。

 

3.4 结果

jupyter输出如下:

jupyter确实方便,能将结果直接输出出来方便调试。

输出精度大致可以接受,毕竟是Tiny YOLO的简化版。

输出速度,大概是3秒/1帧。注意,不是1秒3帧,是3秒1帧。

考虑到ZYNQ7020不到5w的功耗,和嵌入式ARM的计算能力,这个成绩符合我的预料。根据我之前Darknet框架的实验,Tiny YOLO在1GHz的ARM A9纯CPU计算需要70秒以上。虽然本实验的模型是“Tinier YOLO”,这个成绩已经获得了相较纯软件计算数十倍的加速。

成绩算不上实时,但足以满足许多创客的项目需求。

 

 

4 总结

本文首先进行常规的开箱和初见印象描述;随后尝试解释了ZYNQ这一硬件的特色;最后以目标检测为例,体验了PYNQ的开发流程。

本文只是PYNQ的一篇开箱文。关于Overlay和一些更加深入的特色,如果将来我的项目使用到了,也更深入地再写一下吧。

总之,PYNQ试图将设计流程变得更加友好,Python也迎合了很多软件开发者的口味,overlay提供了某些功能的硬件加速。

我确实看到了PYNQ的诚意,PYNQ确实能将ZYNQ的开发变得友好:至少对于软件开发者,上手不必折腾那一套Vivado+SDK的工具链,而是尽快投入开发。

对于创客,它绝对是一款值得购买的开发板。如果你的某些项目应用,涉及到了视觉和并行计算等等需求,不妨考虑弄一块PYNQ体验一下。

4
说点什么

avatar
2 Comment threads
2 Thread replies
3 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
SPtuan王竞泽xywang Recent comment authors
  Subscribe  
最新 最旧 得票最多
提醒
王竞泽
游客
王竞泽

请教一下,我在PYNQ-z2上安装QNN-MO-PYNQ,使用的这里的命令行,结果不行,如果是PYNQ-Z2的话,用什么命令行?

xywang
游客
xywang

乖乖