速度与技能的较量!飞桨黑客松 OpenVINO™ 任务获奖者经验分享

news2025/1/12 17:45:32

点击蓝字

关注我们,让开发变得更有趣

作者 | Fisher

排版 | 李擎

41f9319ec975801723f67ef36a69c513.gif

速度与技能的较量!

飞桨黑客松 OpenVINO™ 任务获奖者经验分享

d8ea55f71af510b3bfd3c817fd931632.png

前言/

获奖经验分享,比赛轻松拿捏,

千元奖金拿到手软!

29e5345ccc9c5c4d4678bdba0b0ce847.gif

黑客松活动介绍

飞桨黑客马拉松是一项兼具编程乐趣和挑战一项活动。通过该活动,我们能够接触并参与到企业建设的大型开源项目,提升个人编程能力,增强开源社区互动,推动开源生态发展。本期飞桨黑客马拉松由深度学习技术及应用国家工程研究中心主办,飞桨承办,英特尔作为顶级赞助方,为我们带来了 OpenVINO™ 算子映射和增加 Notebook Demo 等任务。算子映射能够将 PaddlePaddle 模型中的算子映射到 OpenVINO™ 中,完成模型在两个框架之间的转换,最终达到在 PaddlePaddle 训练模型、OpenVINO™ 部署推理的效果,在两个框架之间搭起模型转换的桥梁。

7fe30b5c00b1857960eb840ecb30fb9a.gif

OpenVINO™ 介绍

OpenVINO™ 工具套件是一款由英特尔公司开发的支持快速开发视觉、语音识别和自然语言处理应用的工具包。它采用了最新的人工智能神经网络模型,包括卷积神经网络、循环神经网络和注意力机制网络等,以实现高效的计算机视觉和深度学习应用。

OpenVINO™ 的主要功能包括:在边缘侧支持卷积神经网络的推理加速;在英特尔CPU、GPU、FPGA等设备上的混合执行/异构计算执行;通过大量的预训练模型库加速从产品原型到市场化的过程;支持传统的计算机视觉标准库中的操作,如OpenCV和OpenCL等。

总之,OpenVINO™ 是一个强大的工具包,可以帮助开发者快速构建和优化计算机视觉和深度学习应用,提高应用性能和商业价值。

(说明:Generated by 文心一言,Prompt:介绍一下OpenVINO™ 工具套件)

一、环境配置

1. 环境搭建

首先 Fork 一份 OpenVINO™ 的 GitHub 仓库,并将其克隆到本地(Fork后 OpenVINO™toolkit 应当替换为自己的用户名,新建分支等 git 操作在此不再赘述):

git clone https://github.com/OpenVINOtoolkit/OpenVINO.git

OpenVINO™ 为我们提供了一份编译构建的文档,详情见链接(https://github.com/openvinotoolkit/openvino/blob/master/docs/dev/build.md)

我们可以根据自身开发环境的不同查看对应平台的构建文档。我比较推荐使用 Docker 创建一个开发容器,这里我选择使用 paddlepaddle 提供的开发镜像,里面已经内置了常用的编译工具链,开箱即用非常方便。

docker run \
  -it \
  --gpus=all \
  --name=fisher_OpenVINO \
  --net=host \
  -v `pwd`:`pwd` \
  paddlepaddle/paddle:latest-dev-cuda11.7-cudnn8.4-trt8.4-gcc8.2 \
  /bin/bash

部分参数解析:

--gpus=all:将物理机上的GPU挂载到容器中,如本机无GPU可不挂载

--name=fisher_OpenVINO:给自己创建的容器起一个好记的名字

--net=host:直接使用主机的网络,方便在容器中使用主机的代理

-v `pwd`:`pwd`:将主机当前的路径直接挂载到容器对应路径中,方便clangd插件对compile_commands.json文件进行分析,提供语法检查、代码跳转等功能

2. 编译

根据构建文档中的步骤,我们初始化 git 子模块、安装构建依赖工具包、配置编译选项,以下是我的编译选项,可根据个人需要进行修改,其中关键的参数是-DENABLE_TESTS=ON,该参数将打开测试模块的编译,以便后续开发完成后进行本地测试。

cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX="{project_base_dir}/build/OpenVINO_dist" \
  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
  -DENABLE_CLANG_FORMAT=ON \
  -DENABLE_MYRIAD=OFF \
  -DENABLE_VPU=OFF \
  -DENABLE_PYTHON=ON \
  -DNGRAPH_PYTHON_BUILD_ENABLE=ON \
  -DENABLE_DEBUG_CAPS=ON \
  -DENABLE_TESTS=ON \
  -DENABLE_INTEL_GPU=OFF \
  -DENABLE_WHEEL=ON

编译完成后,在bin/intel64/Release/中能够找到Paddle相关的测试程序:

c09484a53fb12b52192f8f3090871acf.png

二、添加映射

1. 接口对齐

确认编译没有问题后,接下来便是真正的算子映射开发了。

我们首先需要查阅文档,将 Paddle 算子和 OpenVINO™ 算子的功能、输入、属性等对齐,以 silu 为例,我们在 Paddle 文档中很容易找到其相关文档:

462df70c247f7d29f8d51eedf56143a3.png

接下来便是在 OpenVINO™ 的文档中找到 silu 相关的文档,通过搜索发现没有任何结果。

此时有两种可能:

1. 在 OpenVINO™ 中,有功能完全相同,但命名不同的算子。

2. OpenVINO™ 中没有该算子的实现,我们需要使用现有的算子进行组合,组合后的算子能够实现相同的功能。

于是我们可以沿着这两种可能去寻找解决方法:

方法一:在激活函数中寻找名字不同,功能相同或相似的算子。经过一番查找,我在 Paddle 的文档中找到了一个计算公式和 silu 一样的激活函数 swish,swish 在 OpenVINO™ 文档中的定义如下图所示,显然当 β=1 时,就能完全对应上了,问题解决。

9dcb93b69a5188b4030f8f9745f77520.png

方法二:通过现有的组合算子实现。仔细观察 silu 的计算公式,可以发现silu(x) = x * sigmoid(x),我们也可以使用 multiply、sigmoid 两个算子组合实现相同的功能。因为已经存在可以直接映射的算子,我们就没必要将使用该方法了,在此仅提供一个实现思路,如遇到无法直接进行映射的算子,该思路可以作为一个参考。

2. 映射实现

新建映射文件 src/frontends/paddle/src/op/silu.cpp,将算子映射实现放置在以下命名空间域中:

namespace ov {
namespace frontend {
namespace paddle {
namespace op {
// 算子映射的具体实现
}  // namespace op
}  // namespace paddle
}  // namespace frontend
}  // namespace ov

实现算子映射的具体逻辑:

NamedOutputs silu(const NodeContext& node) {
    const auto x = node.get_input("X");
    return node.default_single_output_mapping(
      {std::make_shared<default_opset::Swish>(x)},
      {"Out"}
    );
}

在以上代码中,我们从计算节点中获取输入变量 X,将其作为输入调用 Swish,将输出写回到计算节点的 Out 变量中,完成了 silu 算子的映射。

在其他的算子中,输入的变量和属性可能不止一个,我们可以通过查看 Paddle源码中的 OpMaker 或 paddle/fluid/operators/compat/op.pbtxt 获取变量名和属性名,以下是 Paddle Silu 算子的变量名和属性名:

e2ae9cba33848a13389fc8739d9d3172.png

3. 注册映射

在 src/frontends/paddle/src/op_table.cpp 中注册该算子映射,该文件中包含了 Paddle 到 OpenVINO™ 的所有映射,我们依样画葫芦即可。

OP_CONVERTER(silu);


{"silu", op::silu},

4. 单测用例构造

创建文件src/frontends/paddle/tests/test_models/gen_scripts/generate_silu.py,用于生成 silu 相关的测试用例,在编写测试用例时,我们需要从以下几个维度去考虑单测用例,尽量做到全覆盖:Shape(静态、动态、1D~4D-Tensor)、数据类型(int32、float32等)、算子属性等。

def silu(name: str, x, data_type, use_static=True):
    # 启用Paddle静态图模式
    pdpd.enable_static()
    with pdpd.static.program_guard(pdpd.static.Program(), pdpd.static.Program()):
        if use_static:
          # 静态Shape作为输入
            node_x = pdpd.static.data(name='input_x', shape=x.shape, dtype=data_type)
        else:
          # 动态Shape作为输入
            node_x = pdpd.static.data(name='input_x', shape=[1, 1, -1, -1], dtype=data_type)
        # Paddle silu
        out = pdpd.nn.functional.silu(x=node_x, name='silu')
        # 使用CPU计算
        cpu = pdpd.static.cpu_places(1)
        exe = pdpd.static.Executor(cpu[0])
        # startup program will call initializer to initialize the parameters.
        exe.run(pdpd.static.default_startup_program())
        # 执行器执行并保存模型
        outs = exe.run(feed={'input_x': x}, fetch_list=[out])
        saveModel(name, exe, feedkeys=['input_x'], fetchlist=[out], inputs=[x], outputs=[outs[0]], target_dir=sys.argv[1])
    return outs[0]




def main():
    x1 = np.random.randn(2,).astype('float32')
    silu("silu_static_test1", x1, 'float32', True)
    # More static shape test cases
    x5 = np.random.randn(1, 1, 32, 32).astype('float32')
    silu("silu_dynamic_test1", x5, 'float32', False)
    # More dynamic shape test cases




if __name__ == "__main__":
    main()

以上脚本将会为每一个测试用例导出并保存一个模型,OpenVINO™ 读取、转换、运行该模型,通过比对计算结果判断测试是否通过。

5. 注册单测

在 src/frontends/paddle/tests/op_fuzzy.cpp 中注册单测,单测的名称就是在上一步中保存的模型名称。

std::string("silu_static_test1"),
std::string("silu_static_test2"),
std::string("silu_static_test3"),
std::string("silu_static_test4"),
std::string("silu_dynamic_test1"),
std::string("silu_dynamic_test2"),
std::string("silu_dynamic_test3"),
std::string("silu_dynamic_test4"),

三、测试

1. 编译并测试

重新编译并在 bin/intel64/Release/ 中运行以下测试,可以通过-- gtest_filter 参数筛选想要运行的单测,我们只增加了 silu 算子的映射和单测,因此我们只测试这一部分。

./paddle_tests --gtest_filter=*silu*

d0642504bb0792bee3850be59e32466f.png

测试完成,没有问题之后,使用 pre-commit  格式化代码,根据OpenVINO™ 贡献指南(https://github.com/openvinotoolkit/openvino/blob/master/CONTRIBUTING.md)的要求提PR,等待相应的研发检查即可。

四、总结

算子映射任务能够帮助我们了解算子的具体功能,理解模型在不同的AI框架中是如何进行转换的,对于新手来说是一份宝贵的学习经验。以下是我在开发过程中总结出来的一点经验,希望能够帮助到大家:

- 首次编译尽量使用代理,使用代理能够避免一部分网络原因造成的仓库克隆失败等问题

- 多翻翻文档,许多算子的功能是相同或相似的,多看文档也能够认识各种算子的功能,形成基本概念

- 多学习别人的思路、写法,自己想出的组合算子实现可能比较复杂,参考学习别人的思路和写法能够给自己带来一些改进的灵感

--END--

你也许想了解(点击蓝字查看)⬇️➡️ OpenVINO™ DevCon 2023重磅回归!英特尔以创新产品激发开发者无限潜能➡️ 5周年更新 | OpenVINO™  2023.0,让AI部署和加速更容易➡️ OpenVINO™5周年重头戏!2023.0版本持续升级AI部署和加速性能➡️ OpenVINO™2023.0实战 | 在 LabVIEW 中部署 YOLOv8 目标检测模型➡️ 开发者实战系列资源包来啦!➡️ 以AI作画,祝她节日快乐;简单三步,OpenVINO™ 助你轻松体验AIGC
➡️ 还不知道如何用OpenVINO™作画?点击了解教程。➡️ 几行代码轻松实现对于PaddleOCR的实时推理,快来get!➡️ 使用OpenVINO 在“端—边—云”快速实现高性能人工智能推理➡️ 图片提取文字很神奇?试试三步实现OCR!➡️【Notebook系列第六期】基于Pytorch预训练模型,实现语义分割任务➡️使用OpenVINO™ 预处理API进一步提升YOLOv5推理性能
扫描下方二维码立即体验 
OpenVINO™ 工具套件 2023.0

点击 阅读原文 立即体验OpenVINO 2023.0

3ae7585600fad397623828ec62c41fb3.png

文章这么精彩,你有没有“在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/693944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vuex —— 同步和异步请求

上一篇讲到 Vuex 状态管理的内容&#xff0c;先来简单的回顾一下 Vuex &#xff0c;Vuex 中有五个核心属性&#xff1a;state 、getter、mutation、action、module 。state: 存放数据状态&#xff0c;不能被直接的修改&#xff1b;getter: 基于 state 的计算属性&#xff1b;mu…

kaggle注册时出现一排“Captcha must be filled out.”

kaggle网址&#xff1a;Kaggle: Your Home for Data Science 想去kaggle下载一份数据&#xff0c;但是出现了一排红色的英文&#xff1a;&#xff08;真是学习之路哪哪都是阻碍哭唧唧&#xff09; ​ 出现该问题的原因&#xff1a;必须填写(图片)验证码&#xff0c;可是它没出…

长期不关路由器网速会变慢?一文读懂

如果把现代人最烦的十件事列一个清单&#xff0c;那么网速慢肯定其中一项。看剧的时候画面在转圈&#xff0c;玩游戏的时候角色在卡顿&#xff0c;真是让人非常恼火。 最近我家的网速也比刚安上网时慢了很多&#xff0c;看网上的说法是路由器太久没关了&#xff0c;应该天天关闭…

RESTful API是什么?

82. RESTful API是什么&#xff1f; 当我们构建应用程序或者开发Web服务时&#xff0c;常常需要提供一组接口供客户端访问和使用。RESTful API是一种常见的设计风格&#xff0c;它通过使用HTTP协议和一组规范的设计原则&#xff0c;提供了一种统一、可扩展和可维护的方式来构建…

2023金九银十Java基础-中级-高级面试题汇总(涵盖所有Java核心面试知识点)

寒冬来临&#xff0c;虽受眼前挫折&#xff0c;但咱程序猿&#xff08;媛&#xff09;也不能放弃啊&#xff01;也许这次秋招不是很理想&#xff0c;但是没得关系啊&#xff0c;再过几个月就开始备战2023年的金九银十了呀&#xff0c;现在着手准备&#xff0c;既是给自己的秋招…

机器学习评估与度量指标

这里的内容主要包括&#xff1a;性能度量、比较检验和偏差与方差。在上一篇文章中&#xff0c;我们解决了评估学习器泛化性能的方法&#xff0c;即用测试集的"测试误差"作为"泛化误差"的近似&#xff0c;当我们划分好训练/测试集后&#xff0c;那如何计算&…

《Opencv3编程入门》学习笔记—第十章

《Opencv3编程入门》学习笔记 记录一下在学习《Opencv3编程入门》这本书时遇到的问题或重要的知识点。 第十章 角点检测 一、Harris角点检测 &#xff08;一&#xff09;兴趣点与角点 1、图像特征类型&#xff1a; 边缘角点&#xff08;感兴趣点&#xff09;斑点&#xf…

在pycharm上导出Anaconda3的环境配置文件

目录 1.原理&#xff1a; ​2.亲身实践&#xff1a; 1.原理&#xff1a; 要在PyCharm中导出Anaconda3环境的配置文件&#xff0c;可以使用conda命令行工具来完成。请按照以下步骤进行操作&#xff1a; 打开PyCharm&#xff0c;并确保项目使用的是Anaconda3环境。 在PyCha…

【小程序】如何手动绘制分享用的图片

上一篇【小程序】如何实现滑动翻页中介绍了如何在小程序中实现上下滑动翻页的效果。 如果要给这个产品增加一个生成图片用于分享到朋友圈的功能&#xff0c;又该如何实现呢&#xff1f; 先来看一下最终的效果图&#xff1a; 首先&#xff0c;新建一个页面&#xff08;page&am…

vue+elementui实现英雄联盟道具城

目录 一、效果图 1.首页 2.商品列表、分类 二、实现重点讲解 1.首页轮播图 1.1技术实现&#xff1a; 1.2.鼠标聚焦切换图片事件 2.首页tab切换 3.商品列表实现 三、项目结构说明 四、总结 一、效果图 1.首页 项目与官方效果没有太大差异&#xff1a; 游戏导航&#xff1…

windows上VMware虚拟机彻底卸载详细教程

VMware虚拟机彻底卸载 一、彻底卸载过程1.1 停止VMware服务1.2 结束vmware任务1.3 开始卸载VMware1.4 删除注册表信息1.5 删除安装目录 二、vmware 安装教程三、vmware 使用教程 回到目录   回到末尾 一、彻底卸载过程 卸载之前&#xff0c;需要先关闭VMware相关的后台服务…

高速公路智慧稽核常用技术及发展方向浅析

交通运输部数据显示&#xff0c;截至2021年末&#xff0c;全国收费公路里程达18.76万公里&#xff0c;其中高速公路16.12万公里&#xff0c;占比高达85.9%&#xff0c;高速公路费用收缴的重要性尤为凸显。 收费系统作为高速公路的三大机电系统之一&#xff0c;在高速费用的收取…

【Java面试题】框架篇——Spring

文章目录 什么是Spring框架&#xff1f;Spring框架有哪些主要模块&#xff1f;Spring有几种配置方式&#xff1f;Spring框架中的单例Beans是线程安全的么&#xff1f;Spring 框架中都用到了哪些设计模式&#xff1f;★★★Spring AOP在实际项目中的应用★★★阐述一下Bean的生命…

使用 Transformers 为多语种语音识别任务微调 Whisper 模型

本文提供了一个使用 Hugging Face &#x1f917; Transformers 在任意多语种语音识别 (ASR) 数据集上微调 Whisper 的分步指南。同时&#xff0c;我们还深入解释了 Whisper 模型、Common Voice 数据集以及微调等理论知识&#xff0c;并提供了数据准备和微调的相关代码。如果你想…

django-vue-admin 运行记录

django-vue-admin 运行记录 1. 安装 ubuntu-20.04.6 桌面版 ubuntu-20.04.6-desktop-amd64.iso 桌面版本 桌面版的目的是 有浏览器可以看 django vue 的localhost网页。 用server版&#xff0c;需要用别的机器看&#xff0c;别的机器在权限上可能有问题。 sudo apt install …

ChatGLM2-6B-Int4本地部署

原文链接&#xff1a;http://wangguo.site/posts/9d8c1768.html ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本 GitHub地址&#xff1a;https://github.com/THUDM/ChatGLM2-6B 1、先看效果 2、本地部署 部署环境 wsl2-ubuntu22.04 LTS-----------------------…

计网简答题

答案不保证正确性&#xff0c;仅供参考。 1.有如图所示的以太网&#xff0c;每个交换机的名字及接口号、主机的名字及MAC地址都标明在图中。网络初启动时&#xff0c;两个交换机的转发表都为空&#xff0c;接着先后进行以下MAC帧传输&#xff1a;H1→H5&#xff0c;H3→H2&…

PG系列5:PG体系结构

文章目录 一. PG体系结构1.1 PG的体系结构概述1.2 PostgreSQL进程概述 二. PG内存结构三. PostgreSQL进程3.1 后台进程3.2 后端进程(backend)或服务器进程3.3 用户进程或客户端进程3.4 数据库服务器启动流程 四. PG逻辑结构4.1 PostgreSQL cluster4.2 database和cluster的关系4…

DevExpress WPF Scheduler组件,快速构建性能优异的调度管理器!(上)

无论您在WPF项目中是需要Outlook样式的调度程序&#xff0c;还是需要时间表或议程视图来向最终用户展示信息&#xff0c;DevExpress WPF Scheduler都提供了数十个选项&#xff0c;如集成的日程对话框等&#xff0c;因此用户可以快速构建下一个伟大的调度管理器。 DevExpress W…

抖音本地生活团购服务商

抖音本地生活团购服务商市场前景非常广阔。随着移动互联网的普及和人们对本地生活服务需求的增加&#xff0c;本地生活团购行业已成为一个快速增长的市场。而抖音平台拥有庞大的用户基础和强大的社交媒体传播力&#xff0c;为本地生活团购服务商提供了巨大的发展机遇。 抖音…