社区贡献者分享 | OpenVINO™ 代码贡献助力我的开源之路

点击蓝字

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

作者 | 占俊坚

排版 | 李擎

摘要

在 OpenVINO™ 2024.1 release 版本中,我为 OpenVINO™ 添加了 TensorFlow 中的 Rint operation 以及 PyTorch 中的 aten::bucketize operation 的支持,在此分享我的实现过程,给有兴趣参与 OpenVINO™ 开源项目的同学参考,希望大家都能积极参与到社区建设当中来!

OpenVINO™ 代码贡献持续开放中,感兴趣的同学可以点击“化身英特尔‘Issues 猎手’,共创百万用户开源生态!”了解详情。

OpenVINO™

介绍

OpenVINO™ 中用来支持 TensorFlow 模型的前端组件称为 TensorFlow Frontend (简称“TF FE” )。TF FE 将一个用 TensorFlow opset 表示的模型转成用 OpenVINO™ opset 表示的模型。为了支持模型中含有 Rint 操作的模型的推理,TF FE 需要支持这个操作。同理 PyTorch 前端需要支持 aten::bucketize 操作。

TensorFlow opset :

https://www.tensorflow.org/api_docs/python/tf/raw_ops

OpenVINO™ opset:

https://docs.openvino.ai/archive/2023.2/openvino_docs_ops_opset13.html

Rint:

https://www.tensorflow.org/api_docs/python/tf/raw_ops/Rint

OpenVINO™

TensorFlow operation 开发过程

a4c2adba03f8f4cad20f4774d264768f.gif

1.在 TF FE 的 op 目录为 Rint 实现对应的 loader

一个 loader 负责对一种 TensorFlow 操作进行转换。loader 的职责就是解析 operation 的 attributes, 读取输入,并通过 OpenVINO™ 已有的 operations 去表达。以我的实现为例,我实现了 src/frontends/tensorflow_common/src/op/rint.cpp 文件,内容如下:

// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//


#include "common_op_table.hpp"
#include "openvino/op/round.hpp"


using namespace std;
using namespace ov::op;


namespace ov {
namespace frontend {
namespace tensorflow {
namespace op {


OutputVector translate_rint_op(const NodeContext& node) {
    default_op_checks(node, 1, {"Rint"});


    auto input = node.get_input(0);
    // using default round mode "half_to_even" in openvino,
    // as TF has only that mode
    auto round_mode = v5::Round::RoundMode::HALF_TO_EVEN;
    auto res = make_shared<v5::Round>(input, round_mode);
    set_node_name(node.get_name(), res);
    return res->outputs();
}
}  // namespace op
}  // namespace tensorflow
}  // namespace frontend
}  // namespace ov

loader 输入的 NodeContext 包含 Rint 的所有的 inputs 和 attributes 。首先使用 default_op_checks 函数校验 Rint 操作已被支持,且输入的个数大于1。然后通过 get_input 方法获取输入。根据 Tensorflow 文档中对 Rint 的定义,在 OpenVINO™ 的 Operation Sets 文档中 https://docs.openvino.ai/archive/2023.2/openvino_docs_ops_opset13.html 找到可以表达 Rint 的 v5::Round(注:复杂的 Operation 可能需要组合使用多个 OpenVINO™ 的 Operation)。最后返回包含输出的 vector。

5e06fd048b0502c685febcdca8cb4471.gif

2. 注册 Rint Operation

分别在 src/frontends/tensorflow/src/op_table.cpp 中加上一行 {"Rint", CreatorFunction(translate_rint_op)}, 在 src/frontends/tensorflow_common/include/common_op_table.hpp 加上一行 OP_CONVERTER(translate_rint_op); 来注册该 Operation。

0f99ad4269ac1fbc033636ffd7c1e505.gif

3. Build 项目

编译 build 整个 OpenVINO™ 项目。可能需要解决代码规范问题,以及可能出现的编译错误。注意新手在 build 的时候可能会踩坑,注意仔细查看相应平台的 build 文档如 build_linux.md,一步一步操作。例如这个例子中,需要加上文档中提示的编译 Python API 所需要的 -DENABLE_PYTHON=ON 选项。

6693be1a48ae37d68860f9b723410711.gif

4. 实现对应单测并验证

在 tests/layer_tests/tensorflow_tests/test_tf_Rint.py 目录中实现对应的单测,如下所示:

# Copyright (C) 2018-2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0


import numpy as np
import pytest
import tensorflow as tf
from common.tf_layer_test_class import CommonTFLayerTest


class TestRint(CommonTFLayerTest):
    def _prepare_input(self, inputs_info):
        assert 'input:0' in inputs_info
        inputs_shape = inputs_info['input:0']
        inputs_data = {}
        rng = np.random.default_rng()
        inputs_data['input:0'] = rng.uniform(-5.0, 5.0, inputs_shape).astype(self.input_type)
        return inputs_data


    def create_tf_rint_net(self, input_shape, input_type):        
        self.input_type = input_type
        tf.compat.v1.reset_default_graph()
        with tf.compat.v1.Session() as sess:
            input = tf.compat.v1.placeholder(input_type, input_shape, 'input')
            tf.raw_ops.Rint(x=input)
            tf.compat.v1.global_variables_initializer()
            tf_net = sess.graph_def


        ref_net = None


        return tf_net, ref_net


    @pytest.mark.parametrize("input_shape", [[], [6], [2, 5], [5, 4, 1]])
    @pytest.mark.parametrize("input_type", [np.float32, np.float64])
    @pytest.mark.precommit
    @pytest.mark.nightly
    def test_rint_basic(self, input_shape, input_type, ie_device, precision,
                        ir_version, temp_dir, use_legacy_frontend):
        self._test(*self.create_tf_rint_net(input_shape, input_type),
                ie_device, precision, ir_version, temp_dir=temp_dir,
                use_legacy_frontend=use_legacy_frontend)

通过 @pytest.mark.parametrize 装饰器配置单测的输入的 shape 和 type,注意要配置输入 shape 为空的 corner case。在 create_tf_rint_net 方法中定义包含 Rint 操作的网络。在 _prepare_input 方法中根据输入的 shape 和 type,随机生成输入的 tensor。

实现之后,执行以下命令开始测试:

export TEST_DEVICE=CPU
cd openvino/tests/layer_tests/tensorflow_tests
pytest test_tf_Shape.py

小 Tips:

  1. pytest 加上 -s 选项,否则      pytest 不打印 print 的结果到标准输出。

  2. pytest 加上 —maxfail=1 可以在第一组测试用例 fail 的时候停止,防止 console 出现过多的错误用例信息。或者也可以在 pytest.mark.parametrize 装饰器可以先配置一组参数,调通后再添加多组参数。

  3. 单测的实现可以多参考同目录的其他 operation 单测,基本涵盖了各种情况的测试。

整个 PR 的链接为 https://github.com/openvinotoolkit/openvino/pull/24059/files。

OpenVINO™

PyTorch operation 开发过程

实现步骤及思路同上面的 TensorFlow operation 一致。以我实现的 aten::bucketize operation 为例。

在 PyTorch 的文档中查阅 torch.bucketize 的签名如下torch.bucketize(input, boundaries, ***, out_int32=False, right=False, out=None) → Tensor

https://pytorch.org/docs/stable/tensors.html#torch.Tensor

然后在 OpenVINO™ 的 opset 文档查阅到可用的 v3::Bucketize 进行相应的转换。

// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//


#include "openvino/op/bucketize.hpp"


#include "openvino/frontend/pytorch/node_context.hpp"
#include "openvino/op/add.hpp"
#include "openvino/op/concat.hpp"
#include "openvino/op/convert_like.hpp"
#include "openvino/op/logical_or.hpp"
#include "openvino/op/multiply.hpp"
#include "utils.hpp"


namespace ov {
namespace frontend {
namespace pytorch {
namespace op {


using namespace ov::op;


OutputVector translate_bucketize(const NodeContext& context) {
    num_inputs_check(context, 2, 5);
    auto input = context.get_input(0);
    auto boundaries = context.get_input(1);


    element::Type output_type = ov::element::i64;
    if (!context.input_is_none(2) && context.const_input<bool>(2)) {
        output_type = ov::element::i32;
    }


    bool with_right_bound = true;
    if (!context.input_is_none(3)) {
        with_right_bound = !context.const_input<bool>(3);
    }


    auto bucketize =
        context.mark_node(std::make_shared<v3::Bucketize>(input, boundaries, output_type, with_right_bound));


    if (!context.input_is_none(4)) {
        context.mutate_input(4, bucketize);
    }


    return {bucketize};
};


}  // namespace op
}  // namespace pytorch
}  // namespace frontend
}  // namespace ov

具体地,首先进行参数个数的校验,然后获取2个输入,随后,通过读取第3个输入决定输出的类型是否为 int32 (默认 int64)。接下来,读取第3个输入,判断 with_right_bound是否为 true。紧接着,就可以创建一个 v3::Bucketize node。接着读取第3个输入,判断输出是否返回。最后返回输出。

后续的注册 operation, build OpenVINO™ 项目以及实现单测的步骤和上面的 Rint 操作思路基本一致。具体可以参考 PR (链接:https://github.com/openvinotoolkit/openvino/pull/23527/files)

OpenVINO™

总结

OpenVINO™ 的社区非常活跃,maintainer 会耐心回答大家的问题,并仔细 review 我们提交的代码。通过这2个 PR,我熟悉了给开源项目贡献代码的流程,也对 OpenVINO™ 有了更深入的了解。看到自己的代码可以被合入到一个拥有百万用户级别的开源项目,我感到非常有成就感!在这里,我鼓励大家可以积极参与,为开源项目做贡献的同时,提升自身技能,共创开源之路!

OpenVINO™ 代码贡献持续开放中,感兴趣的同学可以点击“化身英特尔‘Issues 猎手’,共创百万用户开源生态!”了解详情

OpenVINO™

--END--

点击下方图片,让我们一起成为“Issues 猎手”,共创百万用户开源生态!
你也许想了解(点击蓝字查看)⬇️➡️ OpenVINO™ 助力 Qwen 2 —— 开启大语言模型新时代➡️ 揭秘XPU架构下AIGC的推理加速艺术--AI PC 新纪元:将 AI 引入 NPU,实现快速低功耗推理➡️ 隆重介绍 OpenVINO™ 2024.0: 为开发者提供更强性能和扩展支持➡️ 隆重推出 OpenVINO 2023.3 ™ 最新长期支持版本➡️ OpenVINO™ 2023.2 发布:让生成式 AI 在实际场景中更易用➡️ 开发者实战 | 介绍OpenVINO™ 2023.1:在边缘端赋能生成式AI➡️ 5周年更新 | OpenVINO™  2023.0,让AI部署和加速更容易➡️ OpenVINO™5周年重头戏!2023.0版本持续升级AI部署和加速性能➡️ 开发者实战系列资源包来啦!
扫描下方二维码立即体验 
OpenVINO™ 工具套件 2024.1

点击 阅读原文 获取工具套件,评论区已开放,欢迎大家留言评论!

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

最快的开源UDP传输工具:Kcptun

Kcptun&#xff1a;极速网络隧道&#xff0c;让数据传输飞起来&#xff01;- 精选真开源&#xff0c;释放新价值。 概览 kcptun 是一个轻量级、高性能的TCP/UDP网络加速工具&#xff0c;由xtaci开发并托管在GitHub上。它通过使用kcp协议&#xff0c;为网络数据传输提供了一个快…

深度解析:AI Prompt 提示词工程的兴起、争议与未来发展

PART1: 提示词工程的兴起 在人工智能领域中&#xff0c;一个新的领域——提示词工程&#xff08;prompt engineering&#xff09;——开始显露头角。 这个领域的核心在于精心设计输入&#xff0c;以引导AI模型产生特定的、期望的输出。 随着AI技术的飞速发展&#xff0c;特别…

移除重复节点---链表

面试题 02.01. 移除重复节点 - 力扣&#xff08;LeetCode&#xff09; 链表指针p和curr 与head指向同一块空间&#xff1b; p和head来比较相同的值&#xff0c;遇到一样的值、就改变这个空间里面struct的成员变量next指针指向的地址&#xff0c;跳向next的next再比较&#xf…

深度网络学习笔记(二)——Transformer架构详解(包括多头自注意力机制)

Transformer架构详解 前言Transformer的整体架构多头注意力机制&#xff08;Multi-Head Attention&#xff09;具体步骤1. 步骤12. 步骤23. 步骤34. 步骤4 Self-Attention应用与比较Self-Attention用于图像处理Self-Attention vs. CNNSelf-Attention vs. RNN Transformer架构详…

Kimichat使用案例010:快速识别出图片中的表格保存到Excel

文章目录 一、介绍二、图片信息三、输入内容四、输出内容五、markdown提示词六、markdown输出一、介绍 如果有一张图片格式的表格,想要快速复制到Excel表格中,那么一般要借助于OCR工具。之前试过不少在线OCR工具,识别效果差强人意。其实,kimichat就可以非常好的完成这个任务…

为什么需要在微服务中使用链路追踪?Spring Cloud 可以选择哪些微服务链路追踪方案?

引言&#xff1a;在当今的软件开发领域中&#xff0c;微服务架构已经成为了构建大型应用程序的主流方式之一。随着微服务数量的增加和服务之间复杂性的提高&#xff0c;对于了解和监控服务之间的调用关系变得越来越重要。而链路追踪技术的出现&#xff0c;为解决这一难题提供了…

心链13---主页切换功能 + loading特效 + 导航栏完善 + 队伍页接口修改

心链 — 伙伴匹配系统 直接取出所有用户&#xff0c;依次和当前用户计算分数&#xff0c;取 TOP N&#xff08;54 秒&#xff09; 优化方法&#xff1a; 切忌不要在数据量大的时候循环输出日志&#xff08;取消掉日志后 20 秒&#xff09;Map 存了所有的分数信息&#xff0c;占…

[ROS 系列学习教程] 建模与仿真 - 使用 Arbotix 控制机器人

ROS 系列学习教程(总目录) 本文目录 一、Arbotix 简介二、安装Arbotix三、配置Arbotix控制器四、配置launch启动文件五、数据交互接口六、在rviz中仿真控制机器人6.1 直接发topic控制6.2 使用键盘控制6.3 编写代码控制机器人移动 前面讲了机器人的建模&#xff0c;是静态的&…

力扣 240.搜素矩阵II

题目描述&#xff1a; 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9…

Kali Linux 2024.2 释出

渗透测试发行版 Kali Linux 释出了最新的 2024.2。 主要新特性包括&#xff1a;桌面环境更新到 GNOME 46&#xff0c;Xfce 环境加入 HiDPI 模式&#xff0c;更新了网络侦察工具 AutoRecon&#xff0c;监视 Linux 进程的命令行工具 pspy&#xff0c;提取和显示 CVE 信息的 Splo…

Oxlint 会取代 Eslint 吗?

最近&#xff0c;一个基于 Rust 的代码检查工具 Oxlint 在国外前端社区引起了热议&#xff0c;许多专家对其给予了高度评价。那么&#xff0c;相比于它的大哥 Eslint&#xff0c;Oxlint 有哪些优势&#xff1f;它会在未来取代 Eslint 吗&#xff1f;本文将讨论这个话题。 Oxc 和…

XUbuntu22.04之ssh+x11显示远程图形到本机(二百四十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

[羊城杯 2023]CSGO

主函数初始化时&#xff0c;有反调试检测 打个断点在前面&#xff0c;然后nop掉 go语言的主函数是main_main 直接来到main_main&#xff0c;发现能可能是base64变表 在前面打个断点&#xff0c;F9 此处为base64变表&#xff0c;来到v25的地址处 得到变表LMNOPQRSTUVWXYZab…

[大模型]CharacterGLM-6B Transformers部署调用

环境准备 在autodl平台中租一个3090等24G显存的显卡机器&#xff0c;如下图所示镜像选择PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8 接下来打开刚刚租用服务器的JupyterLab&#xff0c;并且打开其中的终端开始环境配置、模型下载和运行demo。 pip换源和安装依赖包 …

PyQt5 多进程 多任务 多线程实现进度条功能 无边框 含源码

概述&#xff1a; 在项目 中我们常遇到&#xff0c;大量计算或者加载数据时&#xff0c;需要用到多线程&#xff0c;此时只能等待&#xff0c;我们这个时间需要添加一下进度条&#xff0c;告诉用户当前需要等待&#xff0c;这时间就需要用到多线程和等待进度条&#xff1b; 效…

SpringCloudAlibaba基础二 Nacos注册中心

一 什么是 Nacos 官方&#xff1a;一个更易于构建云原生应用的动态服务发现(Nacos Discovery )、服务配置(Nacos Config)和服务管理平台。 集 注册中心配置中心服务管理 平台。 Nacos 的关键特性包括: 服务发现和服务健康监测动态配置服务动态 DNS 服务服务及其元数据管理 …

【教程】让小爱音箱Play增强版接入Mi-GPT

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 项目地址&#xff1a;https://github.com/idootop/mi-gpt MiIOT&#xff1a;小米小爱音箱Play 增强版 - 产品规格 - Xiaomi Miot Spec 实现效果图&…

Eslint配置指南

1. Eslint配置指南 1.1. 安装 ESLint1.2. 生成配置文件1.3. 修改配置文件1.4. 创建 .eslintignore 文件1.5. 运行 ESLint1.6. 整合到编辑器/IDE1.7. 自动修复 2. 配置prettier 2.1. 安装依赖包2.2. .prettierrc.json添加规则2.3. .prettierignore忽略文件2.4. 保存自动格式化 3…

二进制中1的个数-java

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、二进制中1的个数 二、算法思路 1.将一个整数转化成二进制形式 2.查询一个数的二进制数中的第k位是多少 3.lowbit(x)操作 三、代码如下 1.代码如下&…

Docker的资源限制

文章目录 一、什么是资源限制1、Docker的资源限制2、内核支持Linux功能3、OOM异常4、调整/设置进程OOM评分和优先级4.1、/proc/PID/oom_score_adj4.2、/proc/PID/oom_adj4.3、/proc/PID/oom_score 二、容器的内存限制1、实现原理2、命令格式及指令参数2.1、命令格式2.2、指令参…