HiAI Foundation开发平台,加速端侧AI应用的智能革命

如果您是一名开发者,正在寻找一种高效、灵活且易于使用的端侧AI开发框架,那么HarmonyOS SDKHiAI Foundation服务(HiAI Foundation Kit)就是您的理想选择。

作为一款AI开发框架,HiAI Foundation不仅提供强大的NPU计算能力和丰富的开发工具,还提供完善的技术支持和社区资源,帮助您快速构建高质量的AI应用程序。以图像分类这种常见的AI应用为例,使用HiAI Foundation可以帮助开发者们快速实现高效的图像分类应用。HiAI Foundation面向自定义AI算法的开发者们,可以灵活地支持自有的算法,给应用带来更好的性能功耗收益。

功能演示

如果开发者对实现方式感兴趣,可以下载Demo体验,基于具体的应用场景优化。Demo支持加载离线模型,对图片中的物体进行分类。

图像分类开发步骤

1.创建项目

本章以Caffe SqueezeNet模型集成为例,说明App集成操作过程。

2.配置项目NAPI

编译HAP时,NAPI层的so需要编译依赖NDK中的libneural_network_core.so和libhiai_foundation.so。

3.头文件引用

按需引用头文件。

#include "neural_network_runtime/neural_network_core.h"
#include "hiai_foundation/hiai_options.h"

4.编写CMakeLists.txt

CMakeLists.txt中的关键代码如下:

include_directories(${HMOS_SDK_NATIVE}/sysroot/usr/lib)
FIND_LIBRARY(hiai_foundation-lib hiai_foundation)
add_library(entry SHARED Classification.cpp HIAIModelManager.cpp)
target_link_libraries(entry PUBLIC libace_napi.z.so
    libhilog_ndk.z.so
    librawfile.z.so
    ${hiai_foundation-lib}
    libneural_network_core.so
    )

5.集成模型

模型的加载、编译和推理主要是在native层实现,应用层主要作为数据传递和展示作用。

模型推理之前需要对输入数据进行预处理以匹配模型的输入,同样对于模型的输出也需要做处理获取自己期望的结果。另外SDK中提供了设置模型编译和运行时的配置接口,开发者可根据实际需求选择使用接口。

本节阐述同步模式下单模型的使用,从流程上分别阐述每个步骤在应用层和Native层的实现和调用,接口请参见API参考。

6.预置模型

为了让App运行时能够读取到模型文件和处理推理结果,需要先把离线模型和模型对应的结果标签文件预置到工程的"entry/src/main/resources/rawfile"目录中。

本示例所使用的离线模型转换和生成可参考Caffe模型转换,当前支持Caffe 1.0版本。

命令行中的参数说明请参见OMG参数,转换命令:

./omg --model xxx.prototxt --weight yyy.caffemodel --framework 0 --
output ./modelname

转换示例:

./omg --model deploy.prototxt --weight squeezenet_v1.1.caffemodel --framework
0 --output ./squeezenet

当看到OMG generate offline model success时,则说明转换成功,会在当前目录下生成squeezenet.om。

7.加载离线模型

在App应用创建时加载模型和读取结果标签文件。

1)调用NAPI层的"LoadModel"函数,读取模型的buffer。

2)把模型buffer传递给HIAIModelManager类的"HIAIModelManager::LoadModelFromBuffer"接口,该接口调用

OH_NNCompilation_ConstructWithOfflineModelBuffer创建模型的编译实例。

3)获取并设置模型的deviceID。

size_t deviceID = 0;
const size_t *allDevicesID = nullptr;
uint32_t deviceCount = 0;
OH_NN_ReturnCode ret = OH_NNDevice_GetAllDevicesID(&allDevicesID, &deviceCount);
if (ret != OH_NN_SUCCESS || allDevicesID == nullptr) {
    OH_LOG_ERROR(LOG_APP, "OH_NNDevice_GetAllDevicesID failed");
    return OH_NN_FAILED;
}
for (uint32_t i = 0; i < deviceCount; i++) {
    const char *name = nullptr;
    ret = OH_NNDevice_GetName(allDevicesID[i], &name);
    if (ret != OH_NN_SUCCESS || name == nullptr) {
        OH_LOG_ERROR(LOG_APP, "OH_NNDevice_GetName failed");
        return OH_NN_FAILED;
    }
    if (std::string(name) == "HIAI_F") {
        deviceID = allDevicesID[i];
        break;
    }
}
// modelData和modelSize为模型的内存地址和大小
OH_NNCompilation *compilation = OH_NNCompilation_ConstructWithOfflineModelBuffer(modelData, modelSize); 
ret = OH_NNCompilation_SetDevice(compilation, deviceID); 
if (ret != OH_NN_SUCCESS) {
    OH_LOG_ERROR(LOG_APP, "OH_NNCompilation_SetDevice failed");
    return OH_NN_FAILED;
}

4)调用OH_NNCompilation_Build,执行模型编译。

5)调用OH_NNExecutor_Construct,创建模型执行器。

6)调用OH_NNCompilation_Destroy,释放模型编译实例。

上述流程可参见Demo中"entry/src/main/cpp/Classification.cpp"文件中的"LoadModel"函数和"entry/src/main/cpp/HiAiModelManager.cpp"中的"HIAIModelManager::LoadModelFromBuffer"函数。

8.准备输入输出

1)准备输入输出

2)处理模型的输入,例如示例中模型的输入为13227*227格式Float类型的数据,需要把输入的图片转成该格式后传递到NAPI层。

3)创建模型的输入和输出Tensor,并把应用层传递的数据填充到输入的Tensor中。

// 创建输入数据
size_t inputCount = 0;
std::vector<NN_Tensor*> inputTensors;
OH_NN_ReturnCode ret = OH_NNExecutor_GetInputCount(executor, &inputCount); 
if (ret != OH_NN_SUCCESS || inputCount != inputData.size()) { // inputData为开发者构造的输入数据
    OH_LOG_ERROR(LOG_APP, "OH_NNExecutor_GetInputCount failed, size mismatch");
    return OH_NN_FAILED;
}
for (size_t i = 0; i < inputCount; ++i) {
    NN_TensorDesc *tensorDesc = OH_NNExecutor_CreateInputTensorDesc(executor, i); 
    NN_Tensor *tensor = OH_NNTensor_Create(deviceID, tensorDesc); // deviceID的获取方式可参考"加载离线模型"的步骤3
    if (tensor != nullptr) {
        inputTensors.push_back(tensor);
    }
    OH_NNTensorDesc_Destroy(&tensorDesc);
}
if (inputTensors.size() != inputCount) {
    OH_LOG_ERROR(LOG_APP, "input size mismatch");
    DestroyTensors(inputTensors); // DestroyTensors为释放tensor内存操作函数
    return OH_NN_FAILED;
}
// 初始化输入数据
for (size_t i = 0; i < inputTensors.size(); ++i) {
    void *data = OH_NNTensor_GetDataBuffer(inputTensors[i]);
    size_t dataSize = 0;
    OH_NNTensor_GetSize(inputTensors[i], &dataSize);
    if (data == nullptr || dataSize != inputData[i].size()) { // inputData为模型的输入数据
        OH_LOG_ERROR(LOG_APP, "invalid data or dataSize");
        return OH_NN_FAILED;
    }
    memcpy(data, inputData[i].data(), inputData[i].size()); // inputData为模型的输入数据
}
// 创建输出数据,与输入数据的创建方式类似
size_t outputCount = 0;
std::vector<NN_Tensor*> outputTensors;
ret = OH_NNExecutor_GetOutputCount(executor, &outputCount); 
if (ret != OH_NN_SUCCESS) {
    OH_LOG_ERROR(LOG_APP, "OH_NNExecutor_GetOutputCount failed");
    DestroyTensors(inputTensors); // DestroyTensors为释放tensor内存操作函数
    return OH_NN_FAILED;
}
for (size_t i = 0; i < outputCount; i++) {
    NN_TensorDesc *tensorDesc = OH_NNExecutor_CreateOutputTensorDesc(executor, i); 
    NN_Tensor *tensor = OH_NNTensor_Create(deviceID, tensorDesc); // deviceID的获取方式可参考"加载离线模型"的步骤3
    if (tensor != nullptr) {
        outputTensors.push_back(tensor);
    }
    OH_NNTensorDesc_Destroy(&tensorDesc);
}
if (outputTensors.size() != outputCount) {
    DestroyTensors(inputTensors); // DestroyTensors为释放tensor内存操作函数
    DestroyTensors(outputTensors); // DestroyTensors为释放tensor内存操作函数
    OH_LOG_ERROR(LOG_APP, "output size mismatch");
    return OH_NN_FAILED;
}

上述流程可参见Demo中"entry/src/main/cpp/Classification.cpp"文件中的"InitIOTensors"函数和"entry/src/main/cpp/HiAiModelManager.cpp"中的"HIAIModelManager::InitIOTensors"函数。

9.同步推理离线模型

调用OH_NNExecutor_RunSync,完成模型的同步推理。

可参见Demo中"entry/src/main/cpp/Classification.cpp"文件中的"RunModel"函数和"entry/src/main/cpp/HiAiModelManager.cpp"中的"HIAIModelManager::RunModel"函数。

说明:如果不更换模型,则首次编译加载完成后可多次推理,即一次编译加载,多次推理。

10.模型输出后处理

1)调用OH_NNTensor_GetDataBuffer,获取输出的Tensor,在输出Tensor中会得到模型的输出数据。

2)对输出数据进行相应的处理可得到期望的结果。

3)例如本示例demo中模型的输出是1000个label的概率,期望得到这1000个结果中概率最大的三个标签。

4)销毁实例。

调用OH_NNExecutor_Destroy,销毁创建的模型执行器实例。

调用OH_NNTensor_Destroy,销毁创建的输入输出Tensor。

上述流程可参见Demo中"entry/src/main/cpp/Classification.cpp"文件中的"GetResult"、“UnloadModel"函数和"entry/src/main/cpp/HiAiModelManager.cpp"中的"HIAIModelManager::GetResult”、"HIAIModelManager::UnloadModel"函数。

了解更多详情>>

访问HiAI Foundation服务联盟官网

获取HiAI Foundation服务开发指导文档

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

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

相关文章

c/c++语言的一种日志的编写办法

今日分享一下&#xff0c;从某源码中看到这种日志编写方式&#xff0c;很强。可以借鉴。 这个函数调用的日志函数是不一样的&#xff0c;仔细观看&#xff1a; 这几种日志输出函数&#xff0c;背后都调用了相同的调用。 与之对应的区别就是&#xff0c;函数名称的差异取决于…

小D----海量数据商用短链平台项目大课

从0-1 掌握ClickHouse新一代OLAP数据库。 Kafka接入组件封装Ip获取地理位置信息库使用。 后端工程师角度进阶数据仓库分层大数据领域技术视野 Flinkkafka短链接数据实时计算多维度数据处理。 Async异步关联查询多维度宽表扩展。 Flink多流合并DWS层整合Click House存储。

JDBC【封装工具类、SQL注入问题】

day54 JDBC 封装工具类01 创建配置文件 DBConfig.properties driverNamecom.mysql.cj.jdbc.Driver urljdbc:mysql://localhost:3306/qnz01?characterEncodingutf8&serverTimezoneUTC usernameroot passwordroot新建配置文件&#xff0c;不用写后缀名 创建工具类 将变…

北斗/GPS模块输出的NMEA语句详解

NMEA协议采用 ASCII 码来传递 GPS 定位信息&#xff0c;我们称之为帧。 帧格式形如&#xff1a;$aaccc,ddd,ddd,…,ddd*hh(CR)(LF) 1、“$”&#xff1a;帧命令起始位 2、aaccc&#xff1a;地址域&#xff0c;前两位为识别符&#xff08;aa&#xff09;&#xff0c;后三位为…

记一次android打包,因路由规则设置不合理而导致pom文件无法访问的错误

一、错误详情 FAILURE: Build failed with an exception.* What went wrong: Could not determine the dependencies of task :mediaplayer:compileReleaseAidl. > Could not resolve all task dependencies for configuration :mediaplayer:releaseCompileClasspath.> C…

nodejs版本升级12->18

1.把老版本删除&#xff0c;没删除升级没成功。 2.在官网下载新版本。 3.在菜单中输入cmd&#xff0c;一定要用管理员身份运行&#xff0c;切记&#xff0c;不然会出现2503/2502错误。 4.安装即可。

SCI丨5分期刊,JCR一区

SCI&#xff0c;5分&#xff0c;JCR Q1&#xff0c;中科大类3小类2区 1 基于复杂网络与xxx能源汽车节能数值分析 2 基于热能损失优化的xxx与性能管理 3 基于xxxLCA技术的绿色制造工艺优化研究 4 基于xxx入侵检测技术的物联网智能制造监控系统设计 6 基于物联网技术xxx电力系…

跨境电商自养号全攻略:TEMU、Shein、速卖通测评技巧揭秘

TEMU、Shein、速卖通等跨境平台都推出了全托管模式&#xff0c;普通平台讲究排名&#xff0c;销量&#xff0c;流量量&#xff0c;转化率等等。那么全托管为什么需要做测评呢&#xff1f;因为全托管平台讲究的是一个动销率&#xff0c;有的新品上架或许很快就出单&#xff0c;而…

邮件通知提醒邮箱设置教程及API代码示例!

邮件通知的警告功能如何配置&#xff1f;详细教程与API代码示例&#xff01; 无论是业务提醒、账户活动警告&#xff0c;还是个人事务&#xff0c;邮件通知已经成为一种重要的沟通工具。AokSend将详细介绍如何设置邮件通知提醒邮箱&#xff0c;并提供相应的API代码示例&#x…

场景管理分析平台介绍

在数字化浪潮的推动下&#xff0c;数据已成为企业决策的重要依据。特别是在智能驾驶、虚拟现实和物联网等领域&#xff0c;场景数据的高效管理和利用至关重要。在智能驾驶领域面对海量的场景数据&#xff0c;如何高效处理、精准分析&#xff0c;并将其转化为有价值的决策支持&a…

[OC]萝卜圈Python手动机器人脚本

这是给机器人设置的端口&#xff0c;对照用 代码 # #作者:溥哥’ ##机器人驱动主程序 #请在main中编写您自己的机器人驱动代码 import msvcrt def main():a"none"while True:key_input msvcrt.getch()akey_inputif abw:print(a)robot_drv.set_motors(1,40,2,40,3,…

(漏洞检查项) | 任意文件包含漏洞 file-include

(漏洞检查项)|任意文件包含漏洞 file-include 漏洞场景 1.含有动态包含语句 2.有类似于文件读取的url 漏洞描述 攻击者可以利用任意文件包含漏洞&#xff0c;读取任意文件&#xff0c;对服务器造成危害。 程序开发人员为了代码的灵活性&#xff0c;常常会将包含文件的路径…

SpringBoot怎么单独关闭某个类打印出来的日志?

application.yml文件增加以下内容&#xff1a; logging:level:org.springframework.amgp.rabbit: OFF 配置logging:level是配置的什么&#xff1f; 在application.yml文件中配置logging.level是用来设置日志级别的。这是Spring Boot应用中的一个常用配置&#xff0c;它允许您…

JeecgFlow错误事件

事件定义 错误事件可以用做一个流程的开始事件或者作为一个任务或者子流程的边界事件&#xff0c;错误事件没有提供作用中间事件的功能&#xff0c;这一点和前面介绍的定时器事件和消息事件还有区别的。在错误事件中提供了错误结束事件。 BPMN错误和Java异常并没有直接关联。BP…

tiktok数据分析应用介绍和tiktok数据分析平台分享

对于创作者、商家&#xff0c;tiktok官方有提供相应的数据分析为精细化运营给予辅助支持。 tiktok官方数据分析功能 TikTok Pro Account&#xff08;专业账户&#xff09;&#xff0c;包括CA账户&#xff08;Creator Account&#xff09;和BA&#xff08;Business Account&am…

ONLYOFFICE8.1版本桌面编辑器简单测评

ONLYOFFICE官网链接&#xff1a;在线PDF查看器和转换器 | ONLYOFFICE ONLYOFFICE介绍&#xff1a;https://www.onlyoffice.com/zh/office-suite.aspx OnlyOffice 是一款免费且开源的 Office 协作办公套件&#xff0c;支持桌面端和移动端等多平台&#xff0c;由一家领先的 IT 公…

Python深度理解系列之【排序算法——冒泡排序】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️木道寻的主页 文章目录 &#x1f525;前言&#x1f680;冒泡排序python实现算法实现图形化算法展示 ⭐️⭐️⭐️总结 &#x1f525;前…

师傅们 ~ 2024HW一手资料

各位师傅们&#xff0c;2024HW来了&#xff01; 从2026年开始&#xff0c;随着我国对网络安全的重视&#xff0c;涉及单位不断增加&#xff0c;越来越多单位和个人都加入到HW当中。 2024HW就在眼前&#xff0c; 那么还有不了解或者还没投简历面试的朋友们&#xff0c;需要注意…

职升网:中级会计师考试难度是怎样的?

中级会计师考试确实被普遍认为是具有一定难度的考试。以下是我对其难度的分析&#xff1a; 一、知识体系的广泛性 中级会计师考试覆盖的内容十分广泛&#xff0c;包括但不限于财务管理、财务会计、成本会计、税法等。这就要求考生具备扎实的基础知识和广泛的知识面&#xff0…

咨询公司在推行TPM管理中有哪些不可替代的作用?

TPM管理作为一种先进的生产维护理念&#xff0c;正逐渐成为企业追求卓越生产性能的不二之选。在这场转型升级的浪潮中&#xff0c;咨询公司扮演着不可替代的角色&#xff0c;它们如何助力企业成功推行TPM管理&#xff0c;成为了我们今天要探讨的焦点。 一、专业引领&#xff0c…