
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单算子网络示意图
环境准备
环境要求
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开发套件的压缩包。
解压缩后的内容如下(随版本迭代,目录下的内容可能发生变化,请以最新版本的Native API为准):
接口说明
这里给出Neural Network Runtime开发流程中通用的接口,具体请见下列表格。
结构体
结构体名称 | 描述 |
typedef struct OH_NNModel OH_NNModel | Neural Network Runtime的模型句柄,用于构造模型。 |
typedef struct OH_NNCompilation OH_NNCompilation | Neural Network Runtime的编译器句柄,用于编译AI模型。 |
typedef struct OH_NNExecutor OH_NNExecutor | Neural Network Runtime的执行器句柄,用于在指定设备上执行推理计算。 |
模型构造相关接口
接口名称 | 描述 |
OH_NNModel_Construct() | 创建OH_NNModel类型的模型实例。 |
OH_NN_ReturnCode OH_NNModel_AddTensor(OH_NNModel *model, const OH_NN_Tensor *tensor) | 向模型实例中添加张量。 |
OH_NN_ReturnCode OH_NNModel_SetTensorData(OH_NNModel *model, uint32_t index, const void *dataBuffer, size_t length) | 设置张量的数值。 |
OH_NN_ReturnCode OH_NNModel_AddOperation(OH_NNModel *model, OH_NN_OperationType op, const OH_NN_UInt32Array *paramIndices, const OH_NN_UInt32Array *inputIndices, const OH_NN_UInt32Array *outputIndices) | 向模型实例中添加算子。 |
OH_NN_ReturnCode OH_NNModel_SpecifyInputsAndOutputs(OH_NNModel *model, const OH_NN_UInt32Array *inputIndices, const OH_NN_UInt32Array *outputIndices) | 指定模型的输入输出。 |
OH_NN_ReturnCode OH_NNModel_Finish(OH_NNModel *model) | 完成模型构图。 |
void OH_NNModel_Destroy(OH_NNModel **model) | 释放模型实例。 |
模型编译相关接口
接口名称 | 描述 |
OH_NNCompilation *OH_NNCompilation_Construct(const OH_NNModel *model) | 创建OH_NNCompilation类型的编译实例。 |
OH_NN_ReturnCode OH_NNCompilation_SetDevice(OH_NNCompilation *compilation, size_t deviceID) | 指定模型编译和计算的硬件。 |
OH_NN_ReturnCode OH_NNCompilation_SetCache(OH_NNCompilation *compilation, const char *cachePath, uint32_t version) | 设置编译后的模型缓存路径和缓存版本。 |
OH_NN_ReturnCode OH_NNCompilation_Build(OH_NNCompilation *compilation) | 进行模型编译。 |
void OH_NNCompilation_Destroy(OH_NNCompilation **compilation) | 释放OH_NNCompilation对象。 |
执行推理相关接口
接口名称 | 描述 |
OH_NNExecutor *OH_NNExecutor_Construct(OH_NNCompilation *compilation) | 创建OH_NNExecutor类型的执行器实例。 |
OH_NN_ReturnCode OH_NNExecutor_SetInput(OH_NNExecutor *executor, uint32_t inputIndex, const OH_NN_Tensor *tensor, const void *dataBuffer, size_t length) | 设置模型单个输入的数据。 |
OH_NN_ReturnCode OH_NNExecutor_SetOutput(OH_NNExecutor *executor, uint32_t outputIndex, void *dataBuffer, size_t length) | 设置模型单个输出的缓冲区。 |
OH_NN_ReturnCode OH_NNExecutor_Run(OH_NNExecutor *executor) | 执行推理。 |
void OH_NNExecutor_Destroy(OH_NNExecutor **executor) | 销毁OH_NNExecutor实例,释放实例占用的内存。 |
设备管理相关接口
接口名称 | 描述 |
OH_NN_ReturnCode OH_NNDevice_GetAllDevicesID(const size_t **allDevicesID, uint32_t *deviceCount) | 获取对接到 Neural Network Runtime 的硬件ID。 |
开发步骤
Neural Network Runtime的开发流程主要包含模型构造、模型编译和推理执行三个阶段。以下开发步骤以Add单算子模型为例,介绍调用Neural Network Runtime接口,开发应用的过程。
1. 创建应用样例文件。
首先,创建Neural Network Runtime应用样例的源文件。在项目目录下执行以下命令,创建nnrt_example/目录,在目录下创建 nnrt_example.cpp 源文件。
2. 导入Neural Network Runtime。
在 nnrt_example.cpp 文件的开头添加以下代码,引入Neural Network Runtime模块。
3. 构造模型。
使用Neural Network Runtime接口,构造Add单算子样例模型。
4. 查询Neural Network Runtime已经对接的加速芯片。
Neural Network Runtime支持通过HDI接口,对接多种加速芯片。在执行模型编译前,需要查询当前设备下,Neural Network Runtime已经对接的加速芯片。每个加速芯片对应唯一的ID值,在编译阶段需要通过设备ID,指定模型编译的芯片。
5. 在指定的设备上编译模型。
Neural Network Runtime使用抽象的模型表达描述AI模型的拓扑结构,在加速芯片上执行前,需要通过Neural Network Runtime提供的编译模块,将抽象的模型表达下发至芯片驱动层,转换成可以直接推理计算的格式。
6. 创建执行器。
完成模型编译后,需要调用Neural Network Runtime的执行模块,创建推理执行器。执行阶段,设置模型输入、获取模型输出和触发推理计算的操作均围绕执行器完成。
7. 执行推理计算,并打印计算结果。
通过执行模块提供的接口,将推理计算所需要的输入数据传递给执行器,触发执行器完成一次推理计算,获取模型的推理计算结果。
8. 构建端到端模型构造-编译-执行流程。
步骤3-步骤7实现了模型的模型构造、编译和执行流程,并封装成4个函数,便于模块化开发。以下示例代码将4个函数串联成完整的Neural Network Runtime开发流程。
调测验证
1. 准备应用样例的编译配置文件。
新建一个 CMakeLists.txt 文件,为开发步骤中的应用样例文件 nnrt_example.cpp 添加编译配置。以下提供简单的 CMakeLists.txt 示例:
2. 编译应用样例。
执行以下命令,在当前目录下新建build/目录,在build/目录下编译 nnrt_example.cpp,得到二进制文件 nnrt_example。
3. 执行以下代码,将样例推送到设备上执行。
如果样例执行正常,应该得到以下输出。
4. 检查模型缓存(可选)。
如果在调测环境下,Neural Network Runtime对接的HDI服务支持模型缓存功能,执行完 nnrt_example, 可以在 /data/local/tmp 目录下找到生成的缓存文件。
说明
模型的IR需要传递到硬件驱动层,由HDI服务将统一的IR图,编译成硬件专用的计算图,编译的过程非常耗时。Neural Network Runtime支持计算图缓存的特性,可以将HDI服务编译生成的计算图,缓存到设备存储中。当下一次在同一个加速芯片上编译同一个模型时,通过指定缓存的路径,Neural Network Runtime可以直接加载缓存文件中的计算图,减少编译消耗的时间。
检查缓存目录下的缓存文件:
以下为打印结果:
如果缓存不再使用,需要手动删除缓存,可以参考以下命令,删除缓存文件。
