HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导

这篇具有很好参考价值的文章主要介绍了HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

场景介绍

Neural Network Runtime 作为 AI 推理引擎和加速芯片的桥梁,为 AI 推理引擎提供精简的 Native 接口,满足推理引擎通过加速芯片执行端到端推理的需求。

本文以图 1 展示的 Add 单算子模型为例,介绍 Neural Network Runtime 的开发流程。Add 算子包含两个输入、一个参数和一个输出,其中的 activation 参数用于指定 Add 算子中激活函数的类型。

图 1 Add 单算子网络示意图

HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导,人工智能,华为,HarmonyOS

环境准备

环境要求

Neural Network Runtime 部件的环境要求如下:

● 开发环境:Ubuntu 18.04 及以上。

● 接入设备:HarmonyOS 定义的标准设备,并且系统中内置的硬件加速器驱动,已通过 HDI 接口对接 Neural Network Runtime。

由于 Neural Network Runtime 通过 Native API 对外开放,需要通过 Native 开发套件编译 Neural Network Runtime 应用。

环境搭建

1.  打开 Ubuntu 编译服务器的终端。

2.  把下载好的 Native 开发套件压缩包拷贝至当前用户根目录下。

3.  执行以下命令解压 Native 开发套件的压缩包。

unzip native-linux-{版本号}.zip

解压缩后的内容如下(随版本迭代,目录下的内容可能发生变化,请以最新版本的 Native API 为准):

native/├── build // 交叉编译工具链├── build-tools // 编译构建工具├── docs├── llvm├── nativeapi_syscap_config.json├── ndk_system_capability.json├── NOTICE.txt├── oh-uni-package.json└── sysroot // Native API头文件和库

接口说明

这里给出 Neural Network Runtime 开发流程中通用的接口,具体请见下列表格。

结构体

HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导,人工智能,华为,HarmonyOS

模型构造相关接口

HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导,人工智能,华为,HarmonyOS

HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导,人工智能,华为,HarmonyOS

HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导,人工智能,华为,HarmonyOS

模型编译相关接口

HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导,人工智能,华为,HarmonyOS

HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导,人工智能,华为,HarmonyOS

执行推理相关接口

HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导,人工智能,华为,HarmonyOS

HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导,人工智能,华为,HarmonyOS

设备管理相关接口

HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导,人工智能,华为,HarmonyOS

开发步骤

Neural Network Runtime 的开发流程主要包含模型构造、模型编译和推理执行三个阶段。以下开发步骤以 Add 单算子模型为例,介绍调用 Neural Network Runtime 接口,开发应用的过程。

1.  创建应用样例文件。

首先,创建 Neural Network Runtime 应用样例的源文件。在项目目录下执行以下命令,创建 nnrt_example/目录,在目录下创建 nnrt_example.cpp 源文件。

mkdir ~/nnrt_example && cd ~/nnrt_exampletouch nnrt_example.cpp

2.  导入 Neural Network Runtime。

在 nnrt_example.cpp 文件的开头添加以下代码,引入 Neural Network Runtime 模块。

#include <cstdint>#include <iostream>#include <vector>
#include "neural_network_runtime/neural_network_runtime.h"
// 常量,用于指定输入、输出数据的字节长度const size_t DATA_LENGTH = 4 * 12;

3.  构造模型。

使用 Neural Network Runtime 接口,构造 Add 单算子样例模型。

OH_NN_ReturnCode BuildModel(OH_NNModel** pModel)
{
    // 创建模型实例,进行模型构造
    OH_NNModel* model = OH_NNModel_Construct();
    if (model == nullptr) {
        std::cout << "Create model failed." << std::endl;
        return OH_NN_MEMORY_ERROR;
    }

    // 添加Add算子的第一个输入Tensor,类型为float32,张量形状为[1, 2, 2, 3]
    int32_t inputDims[4] = {1, 2, 2, 3};
    OH_NN_Tensor input1 = {OH_NN_FLOAT32, 4, inputDims, nullptr, OH_NN_TENSOR};
    OH_NN_ReturnCode ret = OH_NNModel_AddTensor(model, &input1);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "BuildModel failed, add Tensor of first input failed." << std::endl;
        return ret;
    }

    // 添加Add算子的第二个输入Tensor,类型为float32,张量形状为[1, 2, 2, 3]
    OH_NN_Tensor input2 = {OH_NN_FLOAT32, 4, inputDims, nullptr, OH_NN_TENSOR};
    ret = OH_NNModel_AddTensor(model, &input2);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "BuildModel failed, add Tensor of second input failed." << std::endl;
        return ret;
    }

    // 添加Add算子的参数Tensor,该参数Tensor用于指定激活函数的类型,Tensor的数据类型为int8。
    int32_t activationDims = 1;
    int8_t activationValue = OH_NN_FUSED_NONE;
    OH_NN_Tensor activation = {OH_NN_INT8, 1, &activationDims, nullptr, OH_NN_ADD_ACTIVATIONTYPE};
    ret = OH_NNModel_AddTensor(model, &activation);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "BuildModel failed, add Tensor of activation failed." << std::endl;
        return ret;
    }

    // 将激活函数类型设置为OH_NN_FUSED_NONE,表示该算子不添加激活函数。
    ret = OH_NNModel_SetTensorData(model, 2, &activationValue, sizeof(int8_t));
    if (ret != OH_NN_SUCCESS) {
        std::cout << "BuildModel failed, set value of activation failed." << std::endl;
        return ret;
    }

    // 设置Add算子的输出,类型为float32,张量形状为[1, 2, 2, 3]
    OH_NN_Tensor output = {OH_NN_FLOAT32, 4, inputDims, nullptr, OH_NN_TENSOR};
    ret = OH_NNModel_AddTensor(model, &output);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "BuildModel failed, add Tensor of output failed." << std::endl;
        return ret;
    }

    // 指定Add算子的输入、参数和输出索引
    uint32_t inputIndicesValues[2] = {0, 1};
    uint32_t paramIndicesValues = 2;
    uint32_t outputIndicesValues = 3;
    OH_NN_UInt32Array paramIndices = {&paramIndicesValues, 1};
    OH_NN_UInt32Array inputIndices = {inputIndicesValues, 2};
    OH_NN_UInt32Array outputIndices = {&outputIndicesValues, 1};

    // 向模型实例添加Add算子
    ret = OH_NNModel_AddOperation(model, OH_NN_OPS_ADD, &paramIndices, &inputIndices, &outputIndices);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "BuildModel failed, add operation failed." << std::endl;
        return ret;
    }

    // 设置模型实例的输入、输出索引
    ret = OH_NNModel_SpecifyInputsAndOutputs(model, &inputIndices, &outputIndices);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "BuildModel failed, specify inputs and outputs failed." << std::endl;
        return ret;
    }

    // 完成模型实例的构建
    ret = OH_NNModel_Finish(model);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "BuildModel failed, error happened when finishing model construction." << std::endl;
        return ret;
    }

    *pModel = model;
    return OH_NN_SUCCESS;
}

4.  查询 Neural Network Runtime 已经对接的加速芯片。

Neural Network Runtime 支持通过 HDI 接口,对接多种加速芯片。在执行模型编译前,需要查询当前设备下,Neural Network Runtime 已经对接的加速芯片。每个加速芯片对应唯一的 ID 值,在编译阶段需要通过设备 ID,指定模型编译的芯片。

void GetAvailableDevices(std::vector<size_t>& availableDevice){    availableDevice.clear();
    // 获取可用的硬件ID    const size_t* devices = nullptr;    uint32_t deviceCount = 0;    OH_NN_ReturnCode ret = OH_NNDevice_GetAllDevicesID(&devices, &deviceCount);    if (ret != OH_NN_SUCCESS) {        std::cout << "GetAllDevicesID failed, get no available device." << std::endl;        return;    }
    for (uint32_t i = 0; i < deviceCount; i++) {        availableDevice.emplace_back(devices[i]);    }}

5.  在指定的设备上编译模型。

Neural Network Runtime 使用抽象的模型表达描述 AI 模型的拓扑结构,在加速芯片上执行前,需要通过 Neural Network Runtime 提供的编译模块,将抽象的模型表达下发至芯片驱动层,转换成可以直接推理计算的格式。

OH_NN_ReturnCode CreateCompilation(OH_NNModel* model, const std::vector<size_t>& availableDevice, OH_NNCompilation** pCompilation)
{
    // 创建编译实例,用于将模型传递至底层硬件编译
    OH_NNCompilation* compilation = OH_NNCompilation_Construct(model);
    if (compilation == nullptr) {
        std::cout << "CreateCompilation failed, error happened when creating compilation." << std::endl;
        return OH_NN_MEMORY_ERROR;
    }

    // 设置编译的硬件、缓存路径、性能模式、计算优先级、是否开启float16低精度计算等选项

    // 选择在第一个设备上编译模型
    OH_NN_ReturnCode ret = OH_NNCompilation_SetDevice(compilation, availableDevice[0]);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "CreateCompilation failed, error happened when setting device." << std::endl;
        return ret;
    }

    // 将模型编译结果缓存在/data/local/tmp目录下,版本号指定为1
    ret = OH_NNCompilation_SetCache(compilation, "/data/local/tmp", 1);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "CreateCompilation failed, error happened when setting cache path." << std::endl;
        return ret;
    }

    // 完成编译设置,进行模型编译
    ret = OH_NNCompilation_Build(compilation);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "CreateCompilation failed, error happened when building compilation." << std::endl;
        return ret;
    }

    *pCompilation = compilation;
    return OH_NN_SUCCESS;
}

6.  创建执行器。

完成模型编译后,需要调用 Neural Network Runtime 的执行模块,创建推理执行器。执行阶段,设置模型输入、获取模型输出和触发推理计算的操作均围绕执行器完成。

OH_NNExecutor* CreateExecutor(OH_NNCompilation* compilation){    // 创建执行实例    OH_NNExecutor* executor = OH_NNExecutor_Construct(compilation);    return executor;}

7.  执行推理计算,并打印计算结果。

通过执行模块提供的接口,将推理计算所需要的输入数据传递给执行器,触发执行器完成一次推理计算,获取模型的推理计算结果。

OH_NN_ReturnCode Run(OH_NNExecutor* executor)
{
    // 构造示例数据
    float input1[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
    float input2[12] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22};

    int32_t inputDims[4] = {1, 2, 2, 3};
    OH_NN_Tensor inputTensor1 = {OH_NN_FLOAT32, 4, inputDims, nullptr, OH_NN_TENSOR};
    OH_NN_Tensor inputTensor2 = {OH_NN_FLOAT32, 4, inputDims, nullptr, OH_NN_TENSOR};

    // 设置执行的输入

    // 设置执行的第一个输入,输入数据由input1指定
    OH_NN_ReturnCode ret = OH_NNExecutor_SetInput(executor, 0, &inputTensor1, input1, DATA_LENGTH);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "Run failed, error happened when setting first input." << std::endl;
        return ret;
    }

    // 设置执行的第二个输入,输入数据由input2指定
    ret = OH_NNExecutor_SetInput(executor, 1, &inputTensor2, input2, DATA_LENGTH);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "Run failed, error happened when setting second input." << std::endl;
        return ret;
    }

    // 设置输出的数据缓冲区,OH_NNExecutor_Run执行计算后,输出结果将保留在output中
    float output[12];
    ret = OH_NNExecutor_SetOutput(executor, 0, output, DATA_LENGTH);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "Run failed, error happened when setting output buffer." << std::endl;
        return ret;
    }

    // 执行计算
    ret = OH_NNExecutor_Run(executor);
    if (ret != OH_NN_SUCCESS) {
        std::cout << "Run failed, error doing execution." << std::endl;
        return ret;
    }

    // 打印输出结果
    for (uint32_t i = 0; i < 12; i++) {
        std::cout << "Output index: " << i << ", value is: " << output[i] << "." << std::endl;
    }

    return OH_NN_SUCCESS;
}

8.  构建端到端模型构造-编译-执行流程。

步骤 3-步骤 7 实现了模型的模型构造、编译和执行流程,并封装成 4 个函数,便于模块化开发。以下示例代码将 4 个函数串联成完整的 Neural Network Runtime 开发流程。

int main(){    OH_NNModel* model = nullptr;    OH_NNCompilation* compilation = nullptr;    OH_NNExecutor* executor = nullptr;    std::vector<size_t> availableDevices;
    // 模型构造阶段    OH_NN_ReturnCode ret = BuildModel(&model);    if (ret != OH_NN_SUCCESS) {        std::cout << "BuildModel failed." << std::endl;        OH_NNModel_Destroy(&model);        return -1;    }
    // 获取可执行的设备    GetAvailableDevices(availableDevices);    if (availableDevices.empty()) {        std::cout << "No available device." << std::endl;        OH_NNModel_Destroy(&model);        return -1;    }
    // 模型编译阶段    ret = CreateCompilation(model, availableDevices, &compilation);    if (ret != OH_NN_SUCCESS) {        std::cout << "CreateCompilation failed." << std::endl;        OH_NNModel_Destroy(&model);        OH_NNCompilation_Destroy(&compilation);        return -1;    }
    // 创建模型的推理执行器    executor = CreateExecutor(compilation);    if (executor == nullptr) {        std::cout << "CreateExecutor failed, no executor is created." << std::endl;        OH_NNModel_Destroy(&model);        OH_NNCompilation_Destroy(&compilation);        return -1;    }
    // 使用上一步创建的执行器,执行单步推理计算    ret = Run(executor);    if (ret != OH_NN_SUCCESS) {        std::cout << "Run failed." << std::endl;        OH_NNModel_Destroy(&model);        OH_NNCompilation_Destroy(&compilation);        OH_NNExecutor_Destroy(&executor);        return -1;    }
    // 释放申请的资源    OH_NNModel_Destroy(&model);    OH_NNCompilation_Destroy(&compilation);    OH_NNExecutor_Destroy(&executor);
    return 0;}

调测验证

1.  准备应用样例的编译配置文件。

新建一个 CMakeLists.txt 文件,为开发步骤中的应用样例文件 nnrt_example.cpp 添加编译配置。以下提供简单的 CMakeLists.txt 示例:

cmake_minimum_required(VERSION 3.16)project(nnrt_example C CXX)
add_executable(nnrt_example    ./nnrt_example.cpp)
target_link_libraries(nnrt_example    neural_network_runtime.z)

2.  编译应用样例。

执行以下命令,在当前目录下新建 build/目录,在 build/目录下编译 nnrt_example.cpp,得到二进制文件 nnrt_example。

mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE={交叉编译工具链的路径}/build/cmake/ohos.toolchain.cmake -DOHOS_ARCH=arm64-v8a -DOHOS_PLATFORM=OHOS -DOHOS_STL=c++_static ..
make

3.  执行以下代码,将样例推送到设备上执行。

# 将编译得到的 `nnrt_example` 推送到设备上,执行样例。hdc_std file send ./nnrt_example /data/local/tmp/.
# 给测试用例可执行文件加上权限。hdc_std shell "chmod +x /data/local/tmp/nnrt_example"
# 执行测试用例hdc_std shell "/data/local/tmp/nnrt_example"


如果样例执行正常,应该得到以下输出。

Output index: 0, value is: 11.000000.Output index: 1, value is: 13.000000.Output index: 2, value is: 15.000000.Output index: 3, value is: 17.000000.Output index: 4, value is: 19.000000.Output index: 5, value is: 21.000000.Output index: 6, value is: 23.000000.Output index: 7, value is: 25.000000.Output index: 8, value is: 27.000000.Output index: 9, value is: 29.000000.Output index: 10, value is: 31.000000.Output index: 11, value is: 33.000000.

4.  检查模型缓存(可选)。

如果在调测环境下,Neural Network Runtime 对接的 HDI 服务支持模型缓存功能,执行完 nnrt_example, 可以在 /data/local/tmp 目录下找到生成的缓存文件。

说明

模型的 IR 需要传递到硬件驱动层,由 HDI 服务将统一的 IR 图,编译成硬件专用的计算图,编译的过程非常耗时。Neural Network Runtime 支持计算图缓存的特性,可以将 HDI 服务编译生成的计算图,缓存到设备存储中。当下一次在同一个加速芯片上编译同一个模型时,通过指定缓存的路径,Neural Network Runtime 可以直接加载缓存文件中的计算图,减少编译消耗的时间。

检查缓存目录下的缓存文件:

ls /data/local/tmp

以下为打印结果:

# 0.nncache  cache_info.nncache

如果缓存不再使用,需要手动删除缓存,可以参考以下命令,删除缓存文件。文章来源地址https://www.toymoban.com/news/detail-773263.html

rm /data/local/tmp/*nncache

到了这里,关于HarmonyOS:Neural Network Runtime 对接 AI 推理框架开发指导的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • neural network basics2-1

    key words:simple neuron ; multilayer;feedforward;non-linear; (artificial)neural network inspired by the biological neural networls in brains 生物细胞处理信息后,从轴突中输出若干个信号 受神经网络和生物神经元的启发,设计出由计算机能够计算的人工神经元:接受n个数作为输入,然后产生一个数的

    2024年01月20日
    浏览(35)
  • 【AI实战】大模型 LLM 部署推理框架的 vLLM 应用

    vLLM is a fast and easy-to-use library for LLM inference and serving. vLLM 速度很快: State-of-the-art serving throughput Efficient management of attention key and value memory with PagedAttention Continuous batching of incoming requests Optimized CUDA kernels vLLM灵活且易于使用: Seamless integration with popular HuggingFace models High-throughput

    2024年02月04日
    浏览(39)
  • Convolutional Neural network(卷积神经网络)

    目录 Why CNN for Image? The whole CNN structure  Convolution(卷积) Max Pooling Flatten  CNN in Keras  What does CNN learn? what does filter do what does neuron do  what about output  Deep Dream Application Playing Go Speech  Text 当我们直接用一般的fully connected的feedforward network来做图像处理的时候,往往会需要太多

    2024年02月05日
    浏览(41)
  • GraphPlanner: Floorplanning with Graph Neural Network

    GraphPlanner: Floorplanning with Graph Neural Network https://doi.org/10.1145/3555804 在超大规模集成电路芯片的物理实现中,芯片布图规划一直是一项具有高计算复杂度的关键任务。它的主要目标是以最小的线长确定大芯片模块的初始位置,同时坚持密度约束,这在本质上是一个过程,构建一

    2024年02月13日
    浏览(51)
  • 卷积神经网络CNN(Convolutional Neural Network)

    一、CNN与NN的区别 卷积神经网络与传统神经网络的区别: 二、CNN的整体架构 1.输入层;2.卷积层;3.池化层;4.全连接层 三、卷积层做了什么 首先将图形分割成一个个小区域,对于每一个区域特征不同;接下来选择一种特征计算的方法,为每一个区域计算特征值,得到特征图

    2024年02月04日
    浏览(69)
  • Pytorch Tutorial【Chapter 3. Simple Neural Network】

    3.1 Train Neural Network Procedure训练神经网络流程 一个典型的神经网络训练过程包括以下几点: 定义一个包含可训练参数的神经网络 迭代整个输入 通过神经网络处理输入 计算损失(loss) 反向传播梯度到神经网络的参数 更新网络的参数,典型的用一个简单的更新方法:weight = weig

    2024年02月14日
    浏览(33)
  • HarmonyOS学习路之方舟开发框架—方舟开发框架(ArkUI)概述

    方舟开发框架(简称ArkUI)为HarmonyOS应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能(组件、布局、动画以及交互事件),以及实时界面预览工具等,可以支持开发者进行可视化界面开发。 UI: 即用户界面。开发者可以将应用的用户界面设计为多个功能

    2024年02月16日
    浏览(45)
  • 神经网络语言模型(Neural Network Language Model,NNLM)

    神经网络语言模型(Neural Network Language Model,NNLM)是一种用神经网络建模语言的方法。NNLM 通过学习文本序列中的词汇之间的概率关系,能够捕捉到语言的结构和语境,从而能够生成自然语言文本或进行其他与语言相关的任务。 想象一下,你正在阅读一本小说。每当你读到一

    2024年02月02日
    浏览(41)
  • 深度学习4. 循环神经网络 – Recurrent Neural Network | RNN

    目录 循环神经网络 – Recurrent Neural Network | RNN 为什么需要 RNN ?独特价值是什么? RNN 的基本原理 RNN 的优化算法 RNN 到 LSTM – 长短期记忆网络 从 LSTM 到 GRU RNN 的应用和使用场景 总结 百度百科+维基百科 卷积神经网络和普通的算法大部分都是输入和输出的一一对应,也就是一

    2024年02月11日
    浏览(41)
  • AIGC实战——卷积神经网络(Convolutional Neural Network, CNN)

    在深度学习一节中,我们使用 Keras

    2024年02月04日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包