diff --git a/README_zh.md b/README_zh.md index d2ca3e9fd0395403f43b04700374af2d75415b63..38cfaab4ef64f3548e01379de7844c8246ed60d7 100644 --- a/README_zh.md +++ b/README_zh.md @@ -2,11 +2,11 @@ ## 简介 -Neural Network Runtime(NNRt, 神经网络运行时)是一套面向AI领域的加速推理框架,支持在各种端侧AI加速芯片上的推理计算;NNRt作为上层AI推理框架和底层加速芯片中间的桥梁,为端侧AI推理框架提供统一的Native接口,并使能AI推理框架的硬件加速推理;NNRt开放了南向HDI接口,便于端侧AI加速芯片直接接入OpenHarmony硬件生态。 +Neural Network Runtime(NNRt, 神经网络运行时)是面向AI领域的跨芯片推理计算运行时,作为中间桥梁连通上层AI推理框架和底层加速芯片,实现AI模型的跨芯片推理计算。 -如图1所示,NNRt北向对接了[MindSpore Lite](https://gitee.com/openharmony/third_party_mindspore)推理框架,同时开放Native接口对接其他端侧推理框架(Tensorflow Lite等);NNRt南向开放了HDI接口,支持各种AI加速芯片(NPU、DSP等)对接。AI应用层通过AI推理框架和NNRt能直接使用底层AI加速芯片加速推理计算。 +如图1所示,NNRt开放北向Native接口供AI推理框架接入,当前NNRt对接了系统内置的[MindSpore Lite](https://gitee.com/openharmony/third_party_mindspore)推理框架。同时NNRt开放南向HDI接口,供端侧AI加速芯片(如NPU、DSP等)接入OpenHarmony硬件生态。AI应用通过AI推理框架和NNRt能直接使用底层芯片加速推理计算。 -Neural Network Runtime与MindSpore Lite使用[MindIR](https://gitee.com/openharmony/third_party_mindspore)来统一两个框架间的模型中间表达,减少中间过程不必要的模型转换,使得模型传递更加高效。 +Neural Network Runtime与MindSpore Lite使用统一的模型中间表达,减少中间过程不必要的模型转换,使得模型传递更加高效。 通常,AI应用、AI推理引擎、Neural Network Runtime处在同一个进程下,芯片驱动运行在另一个进程下,两者之间需要借助进程间通信(IPC)传递模型和计算数据。Neural Network Runtime根据HDI接口实现了HDI客户端,相应的,芯片厂商需要根据HDI接口实现并开放HDI服务。 @@ -48,16 +48,14 @@ Neural Network Runtime与MindSpore Lite使用[MindIR](https://gitee.com/openharm ### 接口说明 -Native接口文档请参考: -- 待补充,正在评审翻译。 +Native接口文档请参考:[Native接口](https://gitee.com/openharmony-sig/interface_native_header/pulls/182)。 -HDI接口文档请参考: -- 待补充,正在评审翻译。 +HDI接口文档请参考:[HDI接口](https://gitee.com/openharmony-sig/interface_native_header/pulls/179)。 ### 使用说明 -- AI推理引擎/应用开发请参考:[Neural Network Runtime开发指导](./neural-network-runtime-guidelines.md) -- AI加速芯片驱动/设备开发请参考:[Neural Network Runtime设备开发指导](./example/drivers/README_zh.md) +- AI推理引擎/应用开发请参考:[Neural Network Runtime应用开发指导](./neural-network-runtime-guidelines.md)。 +- AI加速芯片驱动/设备开发请参考:[Neural Network Runtime设备开发指导](./example/drivers/README_zh.md)。 ## 相关仓 diff --git a/example/drivers/README_zh.md b/example/drivers/README_zh.md index c6e7de5f86e4af93d9b9c2a3ee1bc0d319ac5a44..5a34521cffd575a063520528d52d069380b1ca3d 100644 --- a/example/drivers/README_zh.md +++ b/example/drivers/README_zh.md @@ -4,7 +4,7 @@ ### 功能简介 -神经网络运行时部件(NNRt)是跨设备的AI运行时框架,作为端侧推理框架和专用加速芯片的中间桥梁,为端侧推理框架提供了统一的Native接口,使能端侧推理框架在专有加速芯片上推理;为芯片厂商提供了统一的HDI接口,使能专有加速芯片接入OpenHarmony社区生态。 +Neural Network Runtime(NNRt, 神经网络运行时)是面向AI领域的跨芯片推理计算运行时,作为中间桥梁连通上层AI推理框架和底层加速芯片,实现AI模型的跨芯片推理计算。 本文介绍芯片厂商如何在将专有加速芯片接入NNRt,接入OpenHarmony社区生态。 @@ -12,12 +12,12 @@ 在开发前,开发者需要先了解以下概念,以便更好地理解全文内容: - NNRt:Neural Network Runtime,神经网络运行时,是本指导主要介绍的部件。 -- OHOS:OpenHarmony Operating System,开源鸿蒙操作系统。 +- OHOS:OpenHarmony Operating System,OpenHarmony操作系统。 - HDI:Hardware Device Interface,硬件设备接口,是OHOS中系统组件与芯片组件通信的接口。 -- IDL: Interface Description Language,接口描述语言,是HDI接口的语言格式。 +- IDL:Interface Description Language,接口描述语言,是HDI接口的语言格式。 ### 约束与限制 -- 系统版本:OpenHarmony 3.2及以上。 +- 系统版本:OpenHarmony 3.2 Beta5及以上版本。 - 开发环境:Ubuntu 18.04及以上。 - 接入设备:OpenHarmony定义的标准设备。 @@ -36,6 +36,7 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ### 场景介绍 下文以rk3568芯片为例,展示rk3568 CPU如何通过HDI接口接入NNRt,并完成AI模型推理。 +> 依赖说明:该教程展示的rk3568 CPU接入NNRt并没有实际去写CPU的驱动,而是借用了Mindspore-Lite的CPU算子,故会依赖MindSpore-Lite的动态库以及头文件,实际开发时并不需要依赖MindSpore-Lite的任何库或者头文件。 ### 开发流程 适配操作的整体流程如下: @@ -47,14 +48,12 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ### 开发步骤 开发者具体可通过以下步骤在芯片侧对接NNRt: 1. 开源社区下载OpenHarmony的代码,编译drivers_interface部件,生成HDI接口的头文件。 - - [下载源码](../get-code/sourcecode-acquire.md)。 + - [下载源码](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md)。 - 编译接口IDL文件。 ```shell - ./build.sh --product-name rk3568 –ccache --target-cpu arm64 --build-target=drivers_interface_nnrt + ./build.sh --product-name rk3568 –ccache --build-target drivers_interface_nnrt ``` - --target-cpu arm64:是64位编译选项,若编译32位,则不需添加--target-cpu arm64 - 编译之后,可以在```out/rk3568/gen/drivers/interface/nnrt```目录下找到生成的头文件,默认生成C++头文件,若需要生成C头文件,则修改```drivers/interface/nnrt/v1_0/BUILD.gn```文件中的language。 ```shell language = "c" @@ -118,115 +117,116 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 - 实现服务接口,主要实现nnrt_device_service.cpp和prepared_model_service.cpp文件,接口定义可以参考```drivers/interface/nnrt```。 - 编译驱动和服务实现为共享库。 - 在```drivers/peripheral/nnrt/hdi_cpu_service/```下新建```BUILD.gn```文件,对驱动入口和服务实现编译为共享库。 - - ```shell - import("//build/ohos.gni") - import("//drivers/hdf_core/adapter/uhdf2/uhdf.gni") - - ohos_shared_library("libnnrt_service_1.0") { - include_dirs = [] - sources = [ - "src/nnrt_device_service.cpp", - "src/prepared_model_service.cpp", - "src/node_registry.cpp", - "src/node_functions.cpp", - "src/node_attr_types.cpp" - ] - public_deps = [ "//drivers/interface/nnrt/v1_0:nnrt_idl_headers" ] - external_deps = [ - "hdf_core:libhdf_utils", - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_single", - "c_utils:utils", - ] - - install_images = [ chipset_base_dir ] - subsystem_name = "hdf" - part_name = "drivers_peripheral_nnrt" - } + 在```drivers/peripheral/nnrt/hdi_cpu_service/```下新建```BUILD.gn```文件,对驱动入口和服务实现编译为共享库。 + + ```shell + import("//build/ohos.gni") + import("//drivers/hdf_core/adapter/uhdf2/uhdf.gni") + + ohos_shared_library("libnnrt_service_1.0") { + include_dirs = [] + sources = [ + "src/nnrt_device_service.cpp", + "src/prepared_model_service.cpp", + "src/node_registry.cpp", + "src/node_functions.cpp", + "src/node_attr_types.cpp" + ] + public_deps = [ "//drivers/interface/nnrt/v1_0:nnrt_idl_headers" ] + external_deps = [ + "hdf_core:libhdf_utils", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_single", + "c_utils:utils", + ] - ohos_shared_library("libnnrt_driver") { - include_dirs = [] - sources = [ "src/nnr_device_driver.cpp" ] - deps = [ "//drivers/peripheral/nnrt/hdi_cpu_service:libnnrt_service_1.0" ] - - external_deps = [ - "hdf_core:libhdf_host", - "hdf_core:libhdf_ipc_adapter", - "hdf_core:libhdf_utils", - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_single", - "c_utils:utils", - ] - - install_images = [ chipset_base_dir ] - subsystem_name = "hdf" - part_name = "drivers_peripheral_nnrt" - } + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_nnrt" + } - group("hdf_nnrt_service") { - deps = [ - ":libnnrt_driver", - ":libnnrt_service_1.0", - ] - } - ``` + ohos_shared_library("libnnrt_driver") { + include_dirs = [] + sources = [ "src/nnr_device_driver.cpp" ] + deps = [ "//drivers/peripheral/nnrt/hdi_cpu_service:libnnrt_service_1.0" ] + + external_deps = [ + "hdf_core:libhdf_host", + "hdf_core:libhdf_ipc_adapter", + "hdf_core:libhdf_utils", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_single", + "c_utils:utils", + ] - 将```group("hdf_nnrt_service")```添加到```drivers/peripheral/nnrt/BUILD.gn```文件中 - ```shell - if (defined(ohos_lite)) { - group("nnrt_entry") { - deps = [ ] + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_nnrt" } - } else { - group("nnrt_entry") { + + group("hdf_nnrt_service") { deps = [ - "./hdi_cpu_service:hdf_nnrt_service", + ":libnnrt_driver", + ":libnnrt_service_1.0", ] } - } - ``` + ``` - 新建```drivers/peripheral/nnrt/bundle.json```用于定义新增的```drivers_peripheral_nnrt```部件。 - ```json - { - "name": "drivers_peripheral_nnrt", - "description": "Neural network runtime device driver", - "version": "3.2", - "license": "Apache License 2.0", - "component": { - "name": "drivers_peripheral_nnrt", - "subsystem": "hdf", - "syscap": [""], - "adapter_system_type": ["standard"], - "rom": "1024KB", - "ram": "2048KB", - "deps": { - "components": [ - "ipc", - "hdf_core", - "hiviewdfx_hilog_native", - "c_utils" - ], - "third_part": [ - "bounds_checking_function" - ] - }, - "build": { - "sub_component": [ - "//drivers/peripheral/nnrt:nnrt_entry" - ], - "test": [ - ], - "inner_kits": [ + 将```group("hdf_nnrt_service")```添加到```drivers/peripheral/nnrt/BUILD.gn```文件中。 + ```shell + if (defined(ohos_lite)) { + group("nnrt_entry") { + deps = [ ] + } + } else { + group("nnrt_entry") { + deps = [ + "./hdi_cpu_service:hdf_nnrt_service", ] } } - } - ``` + ``` + + 新建```drivers/peripheral/nnrt/bundle.json```用于定义新增的```drivers_peripheral_nnrt```部件。 + ```json + { + "name": "drivers_peripheral_nnrt", + "description": "Neural network runtime device driver", + "version": "3.2", + "license": "Apache License 2.0", + "component": { + "name": "drivers_peripheral_nnrt", + "subsystem": "hdf", + "syscap": [""], + "adapter_system_type": ["standard"], + "rom": "1024KB", + "ram": "2048KB", + "deps": { + "components": [ + "ipc", + "hdf_core", + "hiviewdfx_hilog_native", + "c_utils" + ], + "third_part": [ + "bounds_checking_function" + ] + }, + "build": { + "sub_component": [ + "//drivers/peripheral/nnrt:nnrt_entry" + ], + "test": [ + ], + "inner_kits": [ + ] + } + } + } + ``` 3. 声明HDI服务 + 在对应产品的uhdf hcs配置文件中声明用户态驱动与服务,本例中rk3568对应在```vendor/hihope/rk3568/hdf_config/uhdf/device_info.hcs```文件中新增如下配置: ```text nnrt :: host { @@ -245,9 +245,10 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 } } ``` - 注意:修改hcs文件后请删除out目录重新编译,才能生效。 + > 注意:修改hcs文件后请删除out目录重新编译,才能生效。 4. 配置host进程用户和组 + 对于新增host进程的场景,需要新增配置对应进程的用户ID和组ID。 进程的用户ID在文件```base/startup/init/services/etc/passwd```中配置,进程的组ID在文件```base/startup/init/services/etc/group```中配置。 ```text # 在base/startup/init/services/etc/passwd新增 @@ -256,25 +257,26 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 # 在base/startup/init/services/etc/group新增 nnrt_host:x:3311: ``` - 完成上述所有配置后,全量编译版本后应该可以观察到新增host进程启动,也可以通过hilog输出检索新增的服务名称nnrt_interface_service观察到服务发布成功 + 完成上述所有配置后,全量编译版本后应该可以观察到新增host进程启动,也可以通过hilog输出检索新增的服务名称nnrt_interface_service观察到服务发布成功。 5. SELinux配置 + OHOS已经开启SELinux特性,需要对新增的进程和服务配置相应的SELinux规则,用于运行host进程启动访问某些资源、发布HDI服务。对于调用者来说,也需要配置SELinux规则运行获取和调用某个HDI服务。 - 在```base/security/selinux/sepolicy/ohos_policy/drivers/adapter/vendor/type.te```文件中配置nnrt_host进程安全上下文 + 在```base/security/selinux/sepolicy/ohos_policy/drivers/adapter/vendor/type.te```文件中配置nnrt_host进程安全上下文,新增配置如下: ```text - # 新增 + # 新增配置 type nnrt_host, hdfdomain, domain; ``` 由于SeLinux是白名单访问的权限机制,需要根据实际权限需求配置,将服务启动起来之后,通过以下dmesg命令可能查看avc告警, - avc告警会给出缺少的权限,SeLinux的配置也可以参考[OpenHarmony SeLinux子系统的说明](https://gitee.com/openharmony/security_selinux/blob/master/README.md) + avc告警会给出缺少的权限,SeLinux的配置也可以参考[OpenHarmony SeLinux子系统的说明](https://gitee.com/openharmony/security_selinux/blob/master/README.md)。 ```shell hdc_std shell dmesg | grep nnrt ``` - 新建nnrt_host.te配置文件,将权限配置到nnrt_host.te文件中 + 新建nnrt_host.te配置文件,将权限配置到nnrt_host.te文件中。 ```shell # 创建nnrt文件夹 mkdir base/security/selinux/sepolicy/ohos_policy/drivers/peripheral/nnrt @@ -295,35 +297,86 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 allow sh nnrt_host:fd { use }; ``` -6. 删除out目录编译整个系统 +6. 删除out目录编译整个系统。 ```shell + # 删除out目录 + rm -rf ./out + + # 编译 ./build.sh --product-name rk3568 –ccache --jobs=4 ``` ### 调测验证 服务开发完成后,可以使用XTS用例验证基本功能和兼容性,开发者可通过以下步骤进行验证: -1. 开源社区下载[OpenHarmony代码](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md),相关用例在test/xts/hats/hdf/nnrt目录下。 -2. 编译XTS用例。 -```shell -cd test/xts/hats -./build.sh suite=hats system_size=standard --product-name rk3568 -``` -编译好的测试用例会输出到out/rk3568/suites/hats/testcases/HatsHdfNnrtFunctionTest +1. 编译NNRt的hats用例,用例在```test/xts/hats/hdf/nnrt```目录下,编译NNRt的hats用例。 + ```shell + # 进入hats目录 + cd test/xts/hats + # 编译hats测试用例 + ./build.sh suite=hats system_size=standard --product-name rk3568 -3. 将测试用例push到设备上。 -```shell -# 将测试用例可执行文件推送到设备上,HatsHdfNnrtFunctionTest是测试用例可执行文件。 -hdc_std file send out/rk3568/suites/hats/testcases/HatsHdfNnrtFunctionTest /data/local/tmp/ + # 回到代码根目录 + cd - + ``` + 编译好的测试用例会输出到相对代码根目录的out/rk3568/suites/hats/testcases/HatsHdfNnrtFunctionTest路径下。 -# 给测试用例可执行文件加上权限。 -hdc_std shell "chmod +x /data/local/tmp/HatsHdfNnrtFunctionTest" +2. 将测试用例push到设备上。 + ```shell + # 将测试用例可执行文件推送到设备上,HatsHdfNnrtFunctionTest是测试用例可执行文件。 + hdc_std file send out/rk3568/suites/hats/testcases/HartsHdfNnrtFunctionTest /data/local/tmp/ -# 执行测试用例 -hdc_std shell "/data/local/tmp/HatsHdfNnrtFunctionTest" -``` + # 给测试用例可执行文件加上权限。 + hdc_std shell "chmod +x /data/local/tmp/HatsHdfNnrtFunctionTest" + ``` -### 开发实例 -完整[Demo实例](xxx, Demo暂时还在黄区代码仓,超链接需等Demo开源后补充)可以参考社区实现。 +3. 执行用例并查看结果。 + ```shell + # 执行测试用例 + hdc_std shell "/data/local/tmp/HatsHdfNnrtFunctionTest" + ``` + 所有hats用例执行成功,可以看到测试报告通过47个用例: + ```text + ... + [----------] Global test environment tear-down + Gtest xml output finished + [==========] 47 tests from 3 test suites ran. (515 ms total) + [ PASSED ] 47 tests. + ``` + +### 开发实例 +完整Demo代码可以参考[社区实现](../drivers/nnrt/)。 +1. 拷贝```example/driver/nnrt```目录到```drivers/peripheral```路径下。 + ```shell + cp -r example/driver/nnrt drivers/peripheral + ``` +2. 补充bundle.json文件到```drivers/peripheral/nnrt```,bundle.json参考本教程上面的[开发步骤](#开发步骤)章节。 +3. 由于Demo依赖MindSpore-Lite CPU算子,故需要添加MindSpore-Lite依赖文件。 + - 下载MindSpore-Lite的头文件,[mindspore 1.5.0](https://ms-release.obs.cn-north-4.myhuaweicloud.com/1.5.0/MindSpore/lite/release/linux/mindspore-lite-1.5.0-linux-x64.tar.gz)。 + - 在```drivers/peripheral/nnrt```目录下新建mindspore目录,用于存放mindspore依赖库和头文件。 + ```shell + mkdir drivers/peripheral/nnrt/mindspore + ``` + - 解压mindspore-lite-1.5.0-linux-x64.tar.gz文件,将```runtime/include```目录拷贝到```drivers/peripheral/nnrt/mindspore```目录下。 + - Demo还依赖mindspore的schema文件。 + ```shell + # 创建mindspore_schema目录 + mkdir drivers/peripheral/nnrt/hdi_cpu_service/include/mindspore_schema + + # 拷贝mindspore schema文件 + cp third_party/mindspore/mindspore/lite/schema/* drivers/peripheral/nnrt/hdi_cpu_service/include/mindspore_schema/ + ``` + - 编译MindSpore-Lite的动态库,并将动态库放到mindspore目录下。 + ```shell + # 编译mindspore动态库 + ./build.sh --product-name rk3568 -ccaache --jobs 4 --build-target mindspore_lib + + # 将mindspore动态库 + mkdir drivers/peripheral/nnrt/mindspore/mindspore + + # 将mindspore动态拷贝到drivers/peripheral/nnrt/mindspore/mindspore。 + cp out/rk3568/package/phone/system/lib/libmindspore-lite.huawei.so drivers/peripheral/nnrt/mindspore/mindspore/ + ``` + 4. 其他配置请参考本教程上面的[开发步骤](#开发步骤)章节。 \ No newline at end of file diff --git a/example/drivers/arch_diagram.png b/example/drivers/arch_diagram.png index 2e4b44da94089ec9ebd22d3985ad8435b9cb9d2d..ada94aec31cd5e6d713a660ea508a7221ba01f63 100644 Binary files a/example/drivers/arch_diagram.png and b/example/drivers/arch_diagram.png differ diff --git a/example/drivers/dev_flow.png b/example/drivers/dev_flow.png index 1e75ccb0abedf661e64b08c791831308cf84c02c..3b12b59c932bb44aa6b8dc16fbe0668c20cc6e31 100644 Binary files a/example/drivers/dev_flow.png and b/example/drivers/dev_flow.png differ diff --git a/neural_network_runtime_intro.png b/neural_network_runtime_intro.png index b416303dfc7d9267c3178d6c79706aa1d27cdb5e..aa0015e41decb3556d2e5d0e549f0e8eae35a24f 100755 Binary files a/neural_network_runtime_intro.png and b/neural_network_runtime_intro.png differ