鸿蒙进阶——一文读懂Mindspore-NNRT-HDF工作流程

引言

本文将从宏观上介绍华为MindSpore AI框架及其与NNRT(神经网络运行时)的协同工作方式。MindSpore作为AI推理框架,通过NNRT实现模型在NPU等硬件上的高效推理。

知识有限仅供参考

一、Mindspore Lite

在这里插入图片描述

MindSpore是华为自己开发的一套AI框架,与Onnx、Pytorch、TensorFlow功能类似,提供加载、推理、训练模型的功能,简单说就是通过MIndSpore 你可以像使用SDK API 一样简单使用模型。

1、模型加载

首先,需要将ms模型加载到Mindspore runtime中。这一步通常涉及到读取模型文件,并将其解析成内部数据结构。

2 、初始化

在模型加载完成后,需要进行一系列的初始化操作,包括内存分配、算子注册等。这些操作是为了确保模型推理能够顺利进行。

3、模型推理

在初始化完成后,就可以开始进行模型推理了。模型推理的核心是执行图中的各个算子(Operator),这些算子对应于深度学习模型中的各个层。Mindspore会根据模型的计算图,依次执行各个算子,完成模型的推理过程。

二、MindSpore+NNRT加载模型

MindSpore 默认是运行在CPU的,而有些模型运行在NPU、GPU等其他硬件上更高效,因此NNRT 应运而生,默认与MindSpore 强关联,经由NNRT 就可以实现相关加载、推理操作运行在NPU 或者其他绑定的硬件之上。
在这里插入图片描述
NNRT
Neural Network Runtime(NNRt, 神经网络运行时)是面向AI领域的跨芯片推理计算运行时,作为中间桥梁连通上层AI推理框架和底层加速芯片,实现AI模型的跨芯片推理计算。
在这里插入图片描述
从AI推理框架 把指定的模型传递到指定的硬件完成相关AI 运算。从某种程度上说NNRT 也是有自己的一套内部的模型图,AI推理框架可以调用NNRt的构图接口将推理框架的模型图转换为NNRt内部使用的模型图,然后调用NNRt的编译和执行接口在NNRt底层对接的AI加速硬件上进行模型推理。该方式可以实现无感知的跨AI硬件推理,但是首次加载模型速度较慢。AI推理框架和应用开发者也可以无需调用NNRt构图接口,直接使用某款具体硬件对应的离线模型在NNRt上执行模型推理。该方式仅能实现在特定AI硬件上执行推理,但是首次加载模型速度较快。更多详情参见OpenAtom OpenHarmony NNRT

NNRt目前支持常用算子56个,不过NNRt的算子并没有具体实现,仅作为内部模型图的元素对接底层AI硬件,具体算子实现其实是在AI硬件驱动中。

1、NNRT 架构

在这里插入图片描述

  • 在线构图,AI推理框架需要调用NNRt的构图接口将推理框架的模型图转换为NNRt内部模型图。而系统内置的MindSpore Lite推理框架(具体可参考Mindspore Lite )通过MindIR模型图对接NNRt。由于MindIR模型图和NNRt内部模型图格式兼容,因此MindSpore Lite无需调用NNRt的构图接口即可对接NNRt。
  • 模型编译:NNRt内部模型图或离线模型文件需要通过NNRt的编译接口在底层AI硬件驱动上编译为硬件相关的模型对象,后续就可以在该硬件上执行模型推理。
  • 模型推理:基于已编译的模型对象创建执行器,设置推理的输入和输出张量,然后在AI硬件上执行模型推理。
  • 内存管理:推理的输入和输出张量需要包含对应的数据内存,该模块负责在AI硬件驱动上申请共享内存并赋给张量,并在张量销毁时释放对应共享内存。通过AI硬件驱动上的共享内存可以实现输入和输出数据的“零拷贝”,提升推理性能。
  • 设备管理:负责展示NNRt对接的AI硬件信息,并提供了选择AI硬件的功能。
  • 模型缓存:已编译的模型对象写成模型缓存格式,保存在文件或一段内存中。在下一次编译模型时,可以直接从文件或内存形式的模型缓存中加载,大幅提升编译速度。
  • 离线模型推理:除了支持通过构图接口构造模型图,NNRt也支持直接使用AI硬件相关的模型文件(简称为离线模型)进行推理。应用开发者使用AI硬件厂商提供的模型转换器将原始训练模型转换为AI硬件对应的离线模型文件,并将它部署在应用程序中,在应用运行期间通过NNRt的离线模型编译接口传入。离线模型仅能在对应AI硬件上编译和推理,无法支持跨AI硬件兼容。但由于离线模型和硬件直接相关,因此编译速度通常很快。

NNRT 工作前所有的设备都会被映射为其内部的HDI Device概念(又称为后端)并把其对应的句柄缓存起来, 当 NeuralNetworkRuntime 需要使用已注册的后端(比如在运行神经网络模型时选择合适的硬件加速器)时,它会查询内部注册表,找到已注册的后端实例,HDI Device 是通过宏展开与静态变量初始化机制自动完成注册工作的。换言之,就是把HDI服务的句柄保存到NNRT框架中的BackendManager单例中。在HDIDeviceV2_0Creator()方法中会调用V2_0::INnrtDevice::Get()方法获取V2_0::INnrtDevice实例,这个实例就是底层推理设备的抽象实例句柄,后续调用推理等流程都是通过该实例句柄调用的。
V2_0::INnrtDevice::Get()实现在//out/f8pro/gen/drivers/interface/nnrt/v2_0/innrt_device.h 编译时默认生成的HDI服务中的静态接口,目的是获取HDI服务的句柄。
最终我们是通过这个句柄调用到NnrtDeviceService里的API,进而调用到相关硬件的能力。
在这里插入图片描述

Device——>HDIDeviceV2_0——>INnrtDevice
PreparedModel——>HDIPreparedModelV2_0——>PreparedModelService

三、Mindspore 实现NNRT 接口

Mindspore 通过Delegate 机制来支持NNRT,它首先抽象了一个Kernel 基类对象,然后不同的设备对应的不同的子类,在进行AI运算时指定对应的子类。

1、模型加载流程(整体数据的流向)

在这里插入图片描述

2、推理流程

在这里插入图片描述

四、HDF

OpenHarmony 系统 HDF 驱动框架主要由驱动基础框架、驱动程序、驱动配置文件和驱动接口这四个部分组成。
HDF_INIT(g_sampleDriverEntry); 系统内核自动调用的一个宏,驱动入口对象注册到HDF框架,会调用HDF_INIT函数将驱动入口地址注册到HDF框架。

  • HDF 驱动基础框架提供统一的硬件资源管理,驱动加载管理以及设备节点管理等功能。驱动框架采用的是主从模式设计,由Device Manager 和 Device Host 组成。Device Manager 提供了统一的驱动管理,Device Manager 启动时根据 Device Information 提供驱动设备信息加载相应的驱动Device Host,并控制 Host 完成驱动的加载。Device Host 提供驱动运行的环境,同时预置 Host Framework与 Device Manager 进行协同,完成驱动加载和调用。根据业务的需求Device Host 可以有多个实例。简而言之就是以统一的架构完成驱动和设备的匹配、加载工作。
    Device Host ,不同的应用场景或者不同的设备类型的,比如说Input Host、Display Host、USB等等
  • 驱动程序实现驱动具体的功能,每个驱动由一个或者多个驱动程序组成,每个驱动程序都对应着一个 Driver Entry驱动入口。Driver Entry 主要完成驱动的初始化和驱动接口绑定功能。图中蓝色部分就是Driver程序本身。
struct HdfDriverEntry g_nnrtdeviceDriverEntry = {
    .moduleVersion = 1,
    .moduleName = "nnrt",
    .Bind = HdfNnrtDeviceDriverBind,
    .Init = HdfNnrtDeviceDriverInit,
    .Release = HdfNnrtDeviceDriverRelease,
};
  • 驱动配置文件.hcs 主要由设备信息(Device Information)和设备资源(Device Resource)组成。Device Information 完成设备信息的配置。如配置接口发布策略,驱动加载的方式(动态加载或静态加载、优先级加载)等;Device Resource 完成设备资源的占有配置。如GPIO 管脚、寄存器等资源信息的配置。

  • 驱动接口 HDI(Hardware Driver interface)提供标准化的接口定义和实现,驱动框架提供 IO Service 和 IO Dispatcher 机制,使得不同部署形态下驱动接口趋于形式致。简而言之就是给用户层提供的接口层。

五、uhdf和nnrt的通信

nnrt/Framework部位作为Client端角色——>通过IPC——>Proxy——>通过IPC——>Stup。

  • Stup的载体是nnrt_device_service即Host 服务进程
  • 驱动程序的载体是xxx_device_driver.cpp
  • hdf_core 最终会被编译为一个可执行文件,会被多次调用用于加载so和拉起进程
  • Host 进程(Host服务)是nnrt_device_service、Stup、nnrt_device_driver的

六、HDI和IDL

HDI 是一套与硬件设备通信的PC 框架,而IDL 就是HDI文件使用的语法格式,HDI 框架经过编译后就自动生成一套C/S 架构的IPC 通信模块,而NNRT 就是通过HDI 接口与硬件设备芯片IPC通信。

  • HDI(Hardware Device Interface):OpenHarmony硬件设备接口,定义系统中跨进程通信的接口,实现服务间的跨进程通信。
  • IDL(Interface Description Language):接口描述语言,是HDI接口的语言格式
    HDI服务发布是基于用户态HDF驱动框架,所以需要实现一个驱动入口

七、NNRT HOST

NNRT HOST 本质上就一个HDI 服务为NNRT的接口的实现。该接口标准华为已经定义清楚,由IDL 文件描述。位于drivers/peripheral/nnrt/下是通过HDF 机制由系统启动时自动拉起的对应的进程名称为nnrt_host,作为一个部件依附于hdf子系统下的。

<think>好的,我现在需要帮助用户选择一个适合开发或学习的OpenHarmony或HarmonyOS项目。首先,我要理解用户的需求。用户可能对鸿蒙系统开发感兴趣,但不确定从哪里开始,需要一些项目示例作为参考。接下来,我应该考虑用户可能的背景:可能是开发者,也可能是学生或爱好者,所以项目示例需要涵盖不同难度和方向。 我需要结合提供的引用内容来生成相关建议。引用[1]提到鸿蒙开发的核心知识,包括ArkTS、ArkUI组件、Stage模型等,所以项目可以围绕这些技术点展开。引用[3]提到了移植OLED屏幕驱动的案例,说明硬件相关项目也是一个方向。引用[2]提到应用demo使用Build.gn编译和librknnrt.so库,这可能涉及AI或多媒体应用。引用[4]则强调了实践中的问题解决,所以项目可能需要包含调试和移植的内容。 接下来,我应该分类项目示例,比如基础应用、硬件交互、分布式应用、多媒体/AI、内核开发等,这样用户可以根据兴趣选择。同时,每个类别需要具体例子,比如天气预报应用、智能家居控制,这样用户更容易理解。还要考虑提供学习资源,如官方文档和社区,帮助用户进一步学习。 另外,用户可能需要了解如何开始,比如环境搭建和工具使用,所以需要简要提及开发工具。最后,生成相关问题,引导用户深入思考,比如性能优化或跨设备通信实现,这样可以帮助他们进一步学习。</think>### OpenHarmony/HarmonyOS 项目开发与学习建议 #### 一、项目示例分类 根据技术方向和应用场景,推荐以下项目类型(含具体实现思路): 1. **基础应用开发(适合入门)** - **示例1:天气预报应用** - 技术点:ArkTS声明式UI开发、网络请求、JSON解析 - 实现步骤: 1. 使用`@ohos.net.http`发起API请求 2. 通过`@ohos.data.preferences`实现本地数据缓存 3. 用Flex布局构建响应式界面 - 代码结构示例: ```typescript @Entry @Component struct WeatherPage { @State temperature: string = '--' async getWeather() { // 调用HTTP接口获取数据 } } ``` 2. **硬件交互项目(需开发板)** - **示例2:智能家居控制面板** - 技术点:驱动开发、GPIO控制、传感器数据读取[^3] - 实现方法: - 使用`@ohos.driver`模块操作外设 - 通过HDF框架对接OLED屏幕驱动 - 结合WiFi模块实现远程控制 3. **分布式应用开发(鸿蒙核心特性)** - **示例3:多设备文件共享** - 技术点:分布式软总线、设备发现、跨端数据传输 - 关键流程: ```typescript // 设备发现 deviceManager.createDeviceDiscovery() // 建立会话 session.createDistributionSession() // 文件传输 file.transfer() ``` 4. **多媒体/AI应用(进阶方向)** - **示例4:图像分类应用** - 技术点:NNRt推理框架、模型转换[^2] - 实现步骤: 1. 使用RKNN-Toolkit转换模型 2. 集成librknnrt.so推理库[^2] 3. 调用`@ohos.multimedia.image`处理图像 #### 二、开发准备 1. **环境搭建** - 工具链:DevEco Studio 3.1+ - SDK:API Version 9+(推荐) - 编译系统:使用Build.gn配置模块化编译[^2] 2. **学习路径建议** - 第一阶段:掌握ArkTS语法基础(2周) - 第二阶段:熟悉Stage应用模型(1周) - 第三阶段:实践UI开发与分布式能力(3周) #### 三、学习资源 1. **官方文档** - [OpenHarmony仓库](https://gitee.com/openharmony) - 鸿蒙开发者文档中心 2. **实战案例库** - 设备驱动开发案例(含HDF框架示例) - 分布式任务调度示例 - 图形渲染优化方案 #### 四、进阶方向建议 1. **内核开发** - 轻量级内核LiteOS-M研究 - 文件系统优化实践 2. **性能优化** - 启动速度分析工具使用 - 内存泄漏检测方案
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CrazyMo_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值