<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

為OpenVINO添加對Paddle 2.5的支持

英特爾物聯網 ? 來源:英特爾物聯網 ? 2024-01-19 09:20 ? 次閱讀

作者:盧暢,英特爾 OpenVINO工具套件領航者聯盟成員,PPDE

1. 前言

我是飛槳黑客馬拉松第五期OpenVINO賽題獲獎者——為 OpenVINO添加了對 Paddle 2.5 的支持。在此記錄下來貢獻的過程,希望有更多的同學可以參與到 OpenVINO的社區建設當中來。我在貢獻代碼的過程中,也遇到了一些問題,在此,非常感謝英特爾的技術老師們非常耐心地指導我,幫助我解決了問題!

那么,接下來就讓我們正式進入正題!

2. 介紹

2.1OpenVINO 是什么?

OpenVINO是英特爾推出的一款深度學習推理框架,它可以將訓練好的模型轉換為 OpenVINO支持的 IR 格式,從而可以在 OpenVINO的推理引擎上進行推理。

OpenVINO支持多種深度學習框架,包括 Paddle、TensorFlow、PyTorch 等。

2.2任務說明

在這個任務完成之前,OpenVINO只支持 Paddle 2.4 的版本,由于 Paddle 2.5 的一些接口變動,OpenVINO無法直接支持 Paddle 2.5。同時,由于 Paddle 2.4 版本并不支持 Python 3.11,因此 OpenVINO默認關閉了對 Paddle 的支持,需要手動開啟,在手動開啟后,又會遇到無法編譯出 Paddle 相關單側的問題。

本任務的目標是為 OpenVINO添加對 Paddle 2.5 的支持,并確保 OpenVINO可以正常編譯出 Paddle 相關單側且線上 CI 均可通過。

3. 開發過程

3.1問題分析

在任務開始之前,OpenVINO開啟對 Paddle 的支持后主要會遇到兩個問題:

1API名稱變動導致的編譯報錯,如:

paddle.fluid.layers.elementwise_add -> paddle.add

2API名稱變動導致的編譯報錯,如:paddle.fluid.layers.elementwise_add -> paddle.add

針對上面這兩個問題,主要的解決方案如下:

1將老 API 與新 API 名稱映射

2修改名稱/屬性變動的 API

3修復因 Op 行為變動導致的單側報錯

3.2將老 API 與新 API 名稱映射

由于 Paddle 2.5 版本在 API 層面發生了較大的變化,因此需要將老 API 與新 API 名稱進行映射,這樣 OpenVINO中的代碼就可以使用新 API 名稱,從而解決 API 名稱變動導致的編譯報錯問題。該問題可參考 Paddle 官網的 API 映射表。

鏈接:

https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/model_convert/convert_from_older_versions/paddle_api_mapping_cn.html#paddle-1-8-paddle-2-0-api

為了兼容老版本的 API,OpenVINO中的代碼需要同時支持新 API 與老 API,因此需要在 generate_xxx.py中進行相應修改。

  with paddle.static.program_guard(paddle.static.Program(), paddle.static.Program()):
    node_x = paddle.static.data(name='x', shape=x.shape, dtype=x.dtype)
    node_i = paddle.full(shape=[1], fill_value=0, dtype='int64', name='i')
    if paddle.__version__ >= '2.0.0':
      node_i = paddle.add(node_i, node_x)
    else:
      paddle.fluid.layers.nn.elementwise_add(node_i, node_x)
    node_ten = paddle.full(shape=[1], fill_value=10, dtype='int64', name='ten')

左滑查看更多

代碼中的paddle.fluid.layers.nn.elementwise_add就是老版本的 API,而 paddle.add就是新版本的 API。

3.3修改名稱/屬性變動的 API

對于部分 API 接口,老版本與新版本的名稱或屬性發生了變化,因此需要給 OpenVINO中的代碼進行相應的修改。比如 paddle.fluid.layers.relu6(x, threshold=6.0, name=None)和 paddle.nn.functional.relu6(x, name=None)的屬性發生了變化。

可以看到,paddle.fluid.dygraph.relu6中的 threshold屬性在新版本中被刪除了。

這種情況下需要確認 Python 源碼中是否修改底層 C++ 源碼,如果是修改了 C++ 源碼,那么需要在 OpenVINO的op源碼中進行相應的修改。如果沒有修改 C++ 源碼,那么只需要對應修改 Python 源碼即可。

一般情況下,底層 C++ 源碼不會修改,Python 層一般是修改屬性的名稱,修改屬性的默認值,刪除某個屬性等。

比如新版本 relu6在 Paddle 的 Python 端的實現如下:

def relu6(x, name=None):
  threshold = 6.0
  if in_dynamic_or_pir_mode():
    return _C_ops.relu6(x)


  check_variable_and_dtype(
    x, 'x', ['float16', 'uint16', 'float32', 'float64'], 'relu6'
  )
  helper = LayerHelper('relu6', **locals())
  out = helper.create_variable_for_type_inference(x.dtype)
  helper.append_op(
    type='relu6',
    inputs={'X': x},
    outputs={'Out': out},
    attrs={'threshold': threshold},
  )
  return out

左滑查看更多

通過實現代碼可以看到,新版本的 relu6在 Python 端并沒有修改 C++ 源碼,只是刪除了 threshold屬性,在調用 C++ 源碼時,將 threshold屬性設置為了默認值 6.0。

因此,對于這種情況,只需要修改 OpenVINO中的 Python 單側代碼即可,不需要修改 C++ 源碼。OpenVINO在進行模型轉化的時候是對底層op 進行轉化,因此只要 Paddle 沒有修改底層 Op 的行為,那么 OpenVINO就不需要修改 Op 相關的代碼。

3.4修復因 Op 行為變動導致的單側報錯

在 Paddle 2.5 版本中,部分 Op 的行為發生了變化,導致 OpenVINO中的單側報錯。比如 paddle.argmax新增了 0-d tensor的支持,但是 OpenVINO中的 Op 并沒有對應的修改。想要修復這種問題,需要結合單側報錯的具體情況進行相應的修改。

在介紹如何修復單側報錯之前,先介紹一下 OpenVINO的算子支持機制。

3.4.1 OpenVINO算子支持機制

接下來我們先看一下 OpenVINO中的算子支持機制。

通過 Paddle 官方提供的 Topk_v2 樣例進行說明:

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


#include "default_opset.hpp"
#include "openvino/frontend/paddle/node_context.hpp"


namespace ov {
namespace frontend {
namespace paddle {
namespace op {
NamedOutputs top_k_v2(const NodeContext& node) {
  auto x = node.get_input("X");
  Output k_expected_node;
  if (node.has_input("K")) {
    auto k_variable = node.get_input("K");
    auto k_var_node = std::make_shared(k_variable, element::i32);
    k_expected_node = std::make_shared(k_var_node);
  } else {
    const auto k_expected = node.get_attribute("k", 1);
    k_expected_node = default_opset::i32, {}, {k_expected});
  }


  auto axis = node.get_attribute("axis", -1);
  bool sorted = node.get_attribute("sorted", true);
  bool largest = node.get_attribute("largest", true);


  std::string sort_type = sorted ? "value" : "none";
  std::string mode = largest ? "max" : "min";


  auto node_topk = std::make_shared(x, k_expected_node, axis, mode, sort_type);


  NamedOutputs named_outputs;
  named_outputs["Out"] = OutputVector{node_topk->output(0)};
  named_outputs["Indices"] = OutputVector{node_topk->output(1)};


  return named_outputs;
}
} // namespace op
} // namespace paddle
} // namespace frontend
} // namespace ov

左滑查看更多

在 OpenVINO中,一般來說每個算子都是一個單獨的文件,比如 Topk_v2 算子對應的文件就是 topk_v2.cpp。在這個文件中,我們可以看到 top_k_v2函數,這個函數就是 OpenVINO中的 Topk_v2 算子的實現。

在這個函數中,我們可以看到 auto x = node.get_input("X");,這個函數就是獲取輸入的 Tensor,auto node_topk = std::make_shared(x, k_expected_node, axis, mode, sort_type);這個函數就是創建 Topk_v2 算子,named_outputs["Out"] = OutputVector{node_topk->output(0)};這個函數就是獲取輸出的 Tensor。

每個Op都可以映射為一個圖結構,數據根據圖結構在不同的計算節點之間流通和計算,而Node便定義了圖結構中的數據節點,通過實現每一個Node,便可以通過組合實現更多的算子。

Op 轉換的代碼需要寫在 src/frontends/paddle/src/op/目錄下,并在 src/frontends/paddle/src/op_table.cpp中進行注冊。

單測代碼需要寫在 src/core/tests/frontend/paddle/test_models/gen_scripts目錄中,并在 src/core/tests/frontend/paddle/op_fuzzy.cpp中進行注冊。

3.4.2 修復因 Op 行為變動導致的單側報錯

下面以 paddle.argmax為例,介紹如何修復因 Op 行為變動導致的單側報錯。

修復此類問題一般只能見招拆招,需要結合單側報錯的具體情況進行相應的修改。比如 paddle.argmax新增了 0-d tensor的支持,但是 OpenVINO中的 Op 并沒有對應的修改。因此,我們需要在 OpenVINO中的 Op 中添加對 0-d tensor的支持。經過對代碼的分析我們可以發現,OpenVINO中該 Op 是通過 std::make_shared(node_reshape, k, axis, "max", "index", index_element_type);實現的,但是 TopK并沒有對 0-d tensor進行支持。我們可以判斷 output_size 是否為 0,如果為 0,那么就組合一個 Slice節點返回即可。以下是修改后的代碼:

NamedOutputs argmax(const NodeContext& node) {
  auto data = node.get_input("X");
  bool flatten = node.get_attribute("flatten");
  const element::Type& index_element_type = element::i64;
  const Output k = ov::i64, {}, {1});


  if (!flatten) {
    auto axis = node.get_attribute("axis");
    const auto axis_to_remove = ov::u64, Shape{}, {axis});
    auto node_topk = std::make_shared(data, k, axis, "max", "index", index_element_type);
    const auto reshaped_indices = std::make_shared(node_topk->output(1), axis_to_remove);
    return node.default_single_output_mapping(
      {std::make_shared(reshaped_indices, element::i64)},
      {"Out"});
  } else {
    int64_t axis = 0;
    const Output reshape_flatten = ov::i64, {1}, {-1});
    auto node_reshape = std::make_shared(data, reshape_flatten, true);
    auto node_topk = std::make_shared(node_reshape, k, axis, "max", "index", index_element_type);
    const auto output_info = node.get_output_port_infos("Out");
    // 獲取輸出的維度
    size_t output_size = output_info[0].second.size();
    // 如果輸出的維度為0,那么就組合一個Slice節點返回
    if (output_size == 0) {
      auto out = std::make_shared(node_topk->output(1));
      return node.default_single_output_mapping({std::make_shared(out, element::i64)},
                           {"Out"});
    } else {
      return node.default_single_output_mapping(
        {std::make_shared(node_topk->output(1), element::i64)},
        {"Out"});
    }
  }
}

左滑查看更多

除了 argmax 之外,還有一些 Op 也需要進行相應的修改:

?p_norm

?reduce_ops

?matmul_v2

?elementwise_floordiv

具體的修改可以參考 PR

4. 總結

這次的黑客松活動,讓我對 OpenVINO有了更深入的了解。

OpenVINO的工程師們非常熱心,對于社區的問題都會非常耐心的解答。我也是第一次在 PR 頁面有 144 次的 Conversation。

整個 PR 的周期大概是 3 個月,期間經歷了很多次的修改,最終才能夠被合并。在這次的活動中,我也學到了很多知識,比如 OpenVINO的算子支持機制,Op 的單側測試等。

希望有更多的同學可以參與到 OpenVINO的社區建設當中來,為 OpenVINO的發展及開源社區的建設貢獻自己的力量!

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 英特爾
    +關注

    關注

    60

    文章

    9535

    瀏覽量

    169325
  • 模型
    +關注

    關注

    1

    文章

    2775

    瀏覽量

    47874
  • 代碼
    +關注

    關注

    30

    文章

    4569

    瀏覽量

    67059
  • pytorch
    +關注

    關注

    2

    文章

    766

    瀏覽量

    12877
  • OpenVINO
    +關注

    關注

    0

    文章

    63

    瀏覽量

    97

原文標題:代碼貢獻:為 OpenVINO? 支持 Paddle 2.5 | 開發者實戰

文章出處:【微信號:英特爾物聯網,微信公眾號:英特爾物聯網】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    PADS添加對象,添加一個BMP文件,為什么只顯示圖標?

    PADS9.3添加對象,添加一個BMP文件的LOGO,為什么只顯示圖標,如何顯示圖片內容?
    發表于 02-23 22:09

    請問u32 omap_bootmode=MMCSD_MODE_FAT要添加 bootmode的選擇,該怎么添加?我想增加對nand的支持?

    本帖最后由 一只耳朵怪 于 2018-6-20 15:16 編輯 在 SDK5.6 中。Boot_common.c 文件中 默認的啟動方式是 SD 卡啟動。u32 omap_bootmode=MMCSD_MODE_FAT我要添加 bootmode 的選擇,該怎么添加
    發表于 06-20 01:43

    如何在stm32mp1上添加對動畫啟動畫面的支持呢?

    大家好,如何在 stm32mp1 上添加對動畫啟動畫面的支持?我了解用于自定義引導屏幕的 psplash 配方,它工作得很好。我想在系統啟動時播放動畫。任何輸入都非常感謝。
    發表于 12-16 06:07

    如何使用交叉編譯方法Raspbian 32位操作系統構建OpenVINO工具套件的開源分發

    提供如何使用交叉編譯方法 Raspbian* 32 位操作系統構建 OpenVINO? 工具套件的開源分發。 單擊主題上的 了解詳細信息: 系統要求注意本指南假定您的 Raspberry Pi* 主板
    發表于 08-15 06:28

    永久設置OpenVINO trade Windows reg10的工具套件環境變量

    ;gt;環境變量的控制面板。在系統變量下,以以下各項的相應值添加以下作為新變量,如下所示: 可變名稱可變值筆記 INTEL_OPENVINO_DIRC:\\Program Files (x86
    發表于 08-15 07:18

    從Docker映像Raspbian OpenVINO工具套件的安裝過程

    最大限度地提高了性能。英特爾英特爾? Distribution工具OpenVINO?工具套件還包括英特爾?深度學習部署工具套件。 本指南用戶提供了創建 Docker* 映像的步驟,以安裝適用于
    發表于 08-15 06:59

    無法使用Microsoft Visual Studio 2017Windows 10構建開源OpenVINO怎么解決?

    無法使用 Microsoft Visual Studio 2017 Windows 10 構建開源OpenVINO?。
    發表于 08-15 06:43

    Fedora項目團隊宣布添加對樹莓派2和3的系統支持

    Fedora項目團隊于今天宣布添加對樹莓派2和3的系統支持。項目負責人Peter Robinson說道:“過去幾年反饋最多的要求就是對樹莓派設備的支持,為此我們也付出了諸多努力。早期
    發表于 04-02 14:44 ?185次閱讀

    AMD添加對高端線程撕裂者Pro平臺支持

    在去年更新并發布了StoreMI 2.0后,用戶在使用SSD加機械硬盤時就已經方便了不少。而最近,AMD再度更新StoreMI,為其添加了對于高端的線程撕裂者Pro平臺的支持,并且新增了使用SSD分區進行緩存加速的特性。
    的頭像 發表于 02-18 16:45 ?1328次閱讀

    RT-Thread 4.1.0正式添加對Arm Compiler 6支持

    在 RT-Thread 4.1.0 正式發布版中,添加了對 Arm Compiler 6 的支持,用戶可以修改 rtconfig.py 指定生成 mdk5 工程時使用的編譯器
    的頭像 發表于 06-01 15:20 ?1626次閱讀
    RT-Thread 4.1.0正式<b class='flag-5'>添加對</b>Arm Compiler 6<b class='flag-5'>支持</b>

    基于OpenVINO? 的飛槳版 PGNet 實現案例

    OpenVINO 工具套件2022.1版于2022年3月22日正式發布,根據官宣OpenVINO 迎來迄今為止最重大更新,2022.1新特性搶先看!,OpenVINO 2022.1將是迄今為止最大變化的版本,并可以直接
    發表于 08-04 16:25 ?717次閱讀

    OpenVINO?的C API 2.0有何新特性?

    你是否準備好在新的一年體驗 OpenVINO 工具套件分發版的最新長期支持 (LTS) 版本?
    的頭像 發表于 02-24 11:14 ?374次閱讀

    沒有“中間商賺差價”, OpenVINO? 直接支持 PyTorch 模型對象

    隨著 OpenVINO 2023.0 版本的發布,OpenVINO 工具庫中預置了全新的 PyTorch 前端,為開發者們提供了一條全新的 PyTorch 模型支持路徑,帶來更友好的用戶
    的頭像 發表于 06-27 16:39 ?494次閱讀
    沒有“中間商賺差價”, <b class='flag-5'>OpenVINO</b>? 直接<b class='flag-5'>支持</b> PyTorch 模型對象

    OpenVINO? C# API詳解與演示

    OpenVINO C# API 支持 NuGet 程序包安裝方式,這與 OpenVINO C++ 庫的安裝過程相比,更加簡單。如果使用 Visual Studio 開發 AI 項目,則可以通過 NuGet 程序包管理功能直接安裝
    的頭像 發表于 10-13 16:39 ?433次閱讀
    <b class='flag-5'>OpenVINO</b>?  C# API詳解與演示

    iPhone將增加對RCS消息的支持

    根據9to5Mac的一份報告(9to5mac.com/2023/11/16/apple-rcs-coming-to-iphone/),蘋果表示,2024年,iPhone將增加對RCS消息的支持
    的頭像 發表于 11-20 16:55 ?501次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>