社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

深度学习模型在FPGA上的部署

3D视觉工坊 • 3 年前 • 404 次点击  

编辑丨阿chai带你学AI


我是来自山区、朴实、不偷电瓶的AI算法工程师阿chai,给大家分享人工智能、自动驾驶、机器人、3D感知相关的知识


今天给大家介绍一下FPGA上部署深度学习的算法模型的方法以及平台。希望通过介绍,算法工程师在FPGA的落地上能“稍微”缓和一些,小白不再那么迷茫。阿chai最近在肝一个开源的项目,等忙完了会给大家出几期FPGA上从零部署的教程,包括一些底层的开发、模型的量化推理等等,因为涉及的东西太多了,所以得分开写

FPGA与“迷宫”

深度学习这里就不多介绍了,我们接下来介绍一下FPGA是什么。FPGA是现场可编程逻辑门阵列,灵活性非常高,现场编程真的香。说到这里小伙伴们可能还是不太明白,那么我们和ARM对比一下,ARM可以理解为比如这有一个迷宫,迷宫有很多进口也有对应的出口,道路中间有很多“暗门”可以走,对ARM芯片做编程就是触发当中一条通路,路是死的,我们不好改变。FPGA是如果我们想要一个迷宫,FPGA给提供了一个大的“盒子”,里面有很多的“隔板”,我们自己搭建一条就可以了,你想要什么样的路就什么样子,类似玩我的世界,只不过“矿”是各种逻辑门。那就意味着,FPGA可以设计外围电路也可以设计CPU,是不是很爽,当然,爽的背后开发难度也是相当的大的,这种“特定属性”非常时候做人工智能的算法加速。由于制作特殊电路,FPGA之前经常用做信号处理中,配合DSP或者ARM使用,后来也有用FPGA或者CPLD搭建“矿机”当“矿老板”(祝愿”挖矿“的天天矿难)。

小白入门A:PYNQ

PYNQ是Python + ZYNQ,用Python进行FPGA开发,首先强调一点,Python近几年非常火,虽然很强大,但是他开发硬件不是真的就做硬件,希望大家不要迷。
教程:https://github.com/xupsh/Advanced-Embedded-System-Design-Flow-on-Zynq
我们类比一下很火的MicroPython,使用Python开发硬件是得有特定的电路设计的,除非自己是大佬修改底层的固件,但是都修改底层了,是不是可以自己开发就好了。当然这个是面向小白的,对应的开发板如下图。
这个板子类似我们之前玩MicroPython,也是各种调包。实际上ZYNQ是一个双核ARM Cortex-A9处理器和一个FPGA,使用Python的话可以通过Jupyter进行开发,是不是很香,所以这个非常适合小白。
FPGA上跑BNN(二值神经网络)是非常不错的,“PYNQ-Z1不同的机器学习数据集(dataset)的测试结果显示:对于MNIST数据集PYNQ-Z1能实现每秒168000张图片的分类,延迟102微妙,准确率达98.4%;对于CIFAR-10、SVHN、GTSRB数据集PYN1-Z1能实现每秒1700张图片的分类,延迟2.2毫秒,准确率分别为80.1%、96.69%和97.66%,系统功耗均保持在2.5W左右。
这个到底有多方便,我们看一段代码,首先我们调用模型:
import bnn

hw_classifier = bnn.CnvClassifier(bnn.NETWORK_CNVW1A1,'cifar10',bnn.RUNTIME_HW)
sw_classifier = bnn.CnvClassifier(bnn.NETWORK_CNVW1A1,'cifar10',bnn.RUNTIME_SW)
进行测试:
from IPython.display import display

im = Image.open('car.png')
im.thumbnail((6464), Image.ANTIALIAS)
display(im) 
car_class = hw_classifier.classify_image_details(im)
print("{: >10}{: >13}".format("[CLASS]","[RANKING]"))
for i in range(len(car_class)):
    print("{: >10}{: >10}".format(hw_classifier.classes[i],car_class[i]))
同样支持matplotlib进行数据可视化:
%matplotlib inline
import matplotlib.pyplot as plt

x_pos = np.arange(len(car_class))
fig, ax = plt.subplots()
ax.bar(x_pos - 0.25, (car_class/100.0), 0.25)
ax.set_xticklabels(hw_classifier.classes, rotation='vertical')
ax.set_xticks(x_pos)
ax.set
plt.show()
这不就是Python嘛,真的是非常的方便,而且图像处理也兼容使用Pillow。文件中给出了一些图像识别的例子,大家可以去看看。改天阿chai给大家出一个从零搭建PYNQ的教程,包括模型的量化推理等等。

小白入门B:DPU

DPU是一个用于卷积神经网络的可编程引擎。该单元包含寄存器配置模块、数据控制器模块和卷积计算模块。当然,强大的PYNQ也是支持使用DPU的,如果用这个直接看Python的API就可以了,开发板可以使用ZCU104。大神很多直接用ZYNQ开整的,但是那个难度真的不适合初学者去看,等忙完了项目阿chai给小伙伴们整个这个的教程。
我们首先clone下来项目并且编译:
git clone https://github.com/Xilinx/DPU-PYNQ.git
cd DPU-PYNQ/upgrade
make
安装pynq-dpu:
pip install pynq-dpu
启动jupyter-notebook:
pynq get-notebooks pynq-dpu -p .
模型库在如下链接中。
模型库:https://github.com/Xilinx/Vitis-AI/tree/v1.3
对于DPU的设计,我们需要在自己的电脑上进行,在添加模块后,我们使用如下命令进行编译:
make BOARD=
对于ZYNQ+DPU的开发过程阿chai会单独出一期,因为涉及的东西太多了。。。

支持国产框架:Paddle-Lite

既然python都可以,那肯定Paddle-Lite这种推理框架也是可行的,百度也有专门的部署开发套件 EdgeBoard。EdgeBoard是基于Xilinx Zynq UltraScale+ MPSoC系列芯片打造的计算卡,芯片内部集成ARM处理器+GPU+FPGA的架构,既具有多核处理能力、也有视频流硬解码处理能力,还具有FPGA的可编程的特点。

其实部署的思路小伙伴们应该有一些眉目了,就是将自己训练的深度学习模型转换成Paddle Lite模型,然后移植到EdgeBoard开发板上进行测试。接下来我们简单看看是怎样操作的。
EdgeBoard中模型的测试由json文件做管理:
{
 "model":"测试的模型"
 "combined_model":true
 "input_width":224,
 "input_height":224,
 "image":"测试的路径",
 "mean":[104,117,124],
 "scale":1,
 "format":"BGR"
    "threshold":0.5
}
详细的操作请前往Paddle Lite的GitHub,这里只做简单的流程介绍。
GitHub: https://github.com/PaddlePaddle/Paddle-Lite
如果不想编译,直接在如下网址中下载编译好的文件即可。
编译后的文件:https://ai.baidu.com/ai-doc/HWCE/Yk3b95s8o

1.安装测试

我们首先在有在开发板上编译Paddle Lite,编译的时候需要设置cmake的参数,设置LITE_WITH_FPGA=ONLITE_WITH_ARM=ON,问就是我们都用到。对应的FPGA的编译脚本是lite/tools/build_FPGA.sh,我们执行即可。
sh ./lite/tools/build_fpga.sh
make publish_inference -j2
接下来我们编译示例demo,demo也在刚才的下载链接中。
板子的使用过程请参考百度官方的文档,文档介绍的非常的清楚,阿chai这里就不花时间去讲解使用过程了。
然后进入demo中进行编译:
# classification
cd /home/root/workspace/sample/classification/    
mkdir build
cd build
cmake ..
make
build目录下会出现image_classify和video_classify两个可执行文件,图片预测运行image_classify文件。
使用FPGA 进行resnet50进行测试:
./image_classify_fpga_preprocess ../configs/resnet50/drink.json  
可以看到对应的输出结果,同样detection的模型测试方式也这样操作。

2.可调用的接口

C++

C++的主要包括预处理以及预测库的接口。
  • 预处理接口主要是使用FPGA完成图片的缩放、颜色空间转换和mean/std操作。
  • 预测库接口主要完成模型的初始化、输入参数构造、预测和结果获取。
预处理接口示例:
/**
  * 判断输入图像是否是wc 16对齐
  * width 输入图像宽度
  * channel 输入图像高度
  **/

 bool img_is_align(int width, int channel);

 /**
  * 对齐后的大小
  * width 输入图像宽度
  * channel 输入图像高度
  **/

 int align_size(int width, int channel);

 /**
  * 分配存放图片的内存,析构函数会自动释放 (目前支持BGR->RGB RGB->BGR YUV422->BGR YUV->RGB) 图像最大分辨率支持1080p
  * height 输入图像的框
  * width 输入图像宽度
  * in_format 输入图像格式 参考image_format
  * return uint8_t*  opencv Mat CV_8UC3
  **/

 uint8_tmem_alloc(int img_height, int img_width, image_format in_format);
预测库使用步骤
1、模型初始化,构建预测对象
 std::unique_ptr<:paddlepredictor> g_predictor;
    PaddleMobileConfig config;
    std::string model_dir = j["model"];
    config.precision = PaddleMobileConfig::FP32;
    config.device = PaddleMobileConfig::kFPGA;
    config.prog_file = model_dir + "/model";
    config.param_file = model_dir + "/params";
    config.thread_num = 4;
    g_predictor = CreatePaddlePredictor                    PaddleEngineKind::kPaddleMobile>(config);
2、输入输出参数
    std::vector paddle_tensor_feeds;
    PaddleTensor tensor;
    tensor.shape = std::vector<int>({13, input_height, input_width});
    tensor.data = PaddleBuf(input, sizeof(input));
    tensor.dtype = PaddleDType::FLOAT32;
    paddle_tensor_feeds.push_back(tensor);

    PaddleTensor tensor_imageshape;
    tensor_imageshape.shape = std::vector<int>({12});
    tensor_imageshape.data = PaddleBuf(image_shape, 1 * 2 * sizeof(float));
    tensor_imageshape.dtype = PaddleDType::FLOAT32;
    paddle_tensor_feeds.push_back(tensor_imageshape);

    PaddleTensor tensor_out;
    tensor_out.shape = std::vector<int>({});
    tensor_out.data = PaddleBuf();
    tensor_out.dtype = PaddleDType::FLOAT32;
    std::vector outputs(1, tensor_out);
3、预测
 g_predictor->Run(paddle_tensor_feeds, &outputs);
4、获取结果
 float *data = static_cast<float *>(outputs[0].data.data());
    int size = outputs[0].shape[0];

Python

EdgeBoard系统已经安装了python环境,用户可直接使用即可,同时python接口为用户提供了paddlemobile的python安装包以及示例工程。
文件名称
说明


paddlemobile-0.0.1.linux-aarch64-py2.tar.gz
paddlemobile的python2安装包
edgeboard.py
基于python的模型预测示例
api.py
edgeboard.py的api示例
configs.classification
分类模型的配置文件目录,同C++示例的配置文件
configs.detection
检测模型的配置文件目录,同C++示例的配置文件
models.classification
分类模型的模型文件目录,同C++示例的模型文件
models.detection
检测模型的模型文件目录,同C++示例的模型文件
安装paddlemobile-python SDK,在根目录中解压
tar -xzvf  home/root/workspace/paddlemobile-0.0.1.linux-aarch64-py2.tar.gz
例如使用分类模型的测试如下:
python api.py -j 你测试的json文件
详细的使用说明请关注Paddle-Lite的GitHub。
介绍了这几种,其实大家可以看出来,入门使用并不难,难的是底层的硬件设计与算法加速量化等等,这些都是打包好的东西,我们真的开发还是得慢慢的扣底层的。在这里借用一位大神说的话,现在人工智能算法工程师和十年前的嵌入式工程师差不多,从需求到硬件、软件、算法、应用等等都能做,貌似真的是这样,太卷了,不多学点真的要凉。工具是越来越好用,难的是轮子怎么造,一起加油。
本文仅做学术分享,如有侵权,请联系删文。
下载1
在「3D视觉工坊」公众号后台回复:3D视觉即可下载 3D视觉相关资料干货,涉及相机标定、三维重建、立体视觉、SLAM、深度学习、点云后处理、多视图几何等方向。

下载2
「3D视觉工坊」公众号后台回复:3D视觉github资源汇总即可下载包括结构光、标定源码、缺陷检测源码、深度估计与深度补全源码、点云处理相关源码、立体匹配源码、单目、双目3D检测、基于点云的3D检测、6D姿态估计源码汇总等。

下载3
「3D视觉工坊」公众号后台回复:相机标定即可下载独家相机标定学习课件与视频网址;后台回复:立体匹配即可下载独家立体匹配学习课件与视频网址。

重磅!3DCVer-学术论文写作投稿 交流群已成立

扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

同时也可申请加入我们的细分方向交流群,目前主要有3D视觉CV&深度学习SLAM三维重建点云后处理 自动驾驶、多传感器融合、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流、ORB-SLAM系列源码交流、深度估计等微信群。


一定要备注:研究方向+学校/公司+昵称,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,可快速被通过且邀请进群。原创投稿也请联系。

▲长按加微信群或投稿

▲长按关注公众号

3D视觉从入门到精通知识星球:针对3D视觉领域的知识点汇总、入门进阶学习路线、最新paper分享、疑问解答四个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近3000星球成员为创造更好的AI世界共同进步,知识星球入口:

学习3D视觉核心技术,扫描查看介绍,3天内无条件退款
 圈里有高质量教程资料、可答疑解惑、助你高效解决问题
觉得有用,麻烦给个赞和在看~  

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/111480
 
404 次点击