未验证 提交 bd2bd616 编写于 作者: O openharmony_ci 提交者: Gitee

!16828 修复AI子系统NNRt部件的设备开发指导文档

Merge pull request !16828 from win10wei/master
...@@ -26,15 +26,15 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -26,15 +26,15 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
![架构图](./figures/nnrt_arch_diagram.png) ![架构图](./figures/nnrt_arch_diagram.png)
整个架构主要分为三层,AI应用在应用层,AI推理框架和NNRt在系统层,设备服务在芯片层。AI应用如要使用专用加速芯片模型推理,需要经过AI推理框架和NNRt才能调用到底层专用加速芯片,而NNRt就是负责适配底层各种专用加速芯片,它开放了标准统一的设备接口,众多的第三方芯片设备都可以通过HDI接口接入OHOS 整个架构主要分为三层,AI应用在应用层,AI推理框架和NNRt在系统层,设备服务在芯片层。AI应用如要使用专用加速芯片模型推理,需要经过AI推理框架和NNRt才能调用到底层专用加速芯片,而NNRt就是负责适配底层各种专用加速芯片,它开放了标准统一的设备接口,众多的第三方芯片设备都可以通过HDI接口接入OpenHarmony
程序运行时,AI应用、AI推理框架、NNRt都在用户进程中,底层设备服务在服务进程中,NNRt根据HDI接口实现了HDI Client,服务端也需要根据HDI接口实现HDI Service,使得两个进程间能够跨进程通信。 程序运行时,AI应用、AI推理框架、NNRt都在用户进程中,底层设备服务在服务进程中,NNRt根据HDI接口实现了HDI Client,服务端也需要根据HDI接口实现HDI Service,使得两个进程间能够跨进程通信。
## NNRt开发指导 ## 开发指导
### 场景介绍 ### 场景介绍
当需要将一款AI加速芯片接入NNRt的时候,可以参考下文,下文以rk3568芯片为例,展示rk3568 CPU如何通过HDI接口接入NNRt,并完成AI模型推理。 当需要将一款AI加速芯片接入NNRt的时候,可以参考下文。下文以RK3568芯片为例,展示RK3568 CPU如何通过HDI接口接入NNRt,并完成AI模型推理。
> 依赖说明:该教程展示的rk3568 CPU接入NNRt并没有实际去写CPU的驱动,而是借用了Mindspore-Lite的CPU算子,故会依赖MindSpore-Lite的动态库以及头文件,实际开发时并不需要依赖MindSpore-Lite的任何库或者头文件。 > 依赖说明:该教程展示的RK3568 CPU接入NNRt并没有实际去写CPU的驱动,而是借用了MindSpore Lite的CPU算子,故会依赖MindSpore Lite的动态库以及头文件,实际开发时并不需要依赖MindSpore Lite的任何库或者头文件。
### 开发流程 ### 开发流程
专用加速芯片接入NNRt的整体流程如下: 专用加速芯片接入NNRt的整体流程如下:
...@@ -45,17 +45,18 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -45,17 +45,18 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
### 开发步骤 ### 开发步骤
开发者具体可通过以下步骤实现芯片对接NNRt: 开发者具体可通过以下步骤实现芯片对接NNRt:
1. 开源社区下载OpenHarmony的代码,编译drivers_interface部件,生成HDI接口的头文件。 #### 生成HDI头文件
开源社区下载OpenHarmony的代码,编译drivers_interface部件,生成HDI接口的头文件。
1. [下载源码](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md)。 1. [下载源码](../get-code/sourcecode-acquire.md)
2. 编译接口IDL文件。 2. 编译接口IDL文件。
```shell ```shell
./build.sh --product-name productname –ccache --build-target drivers_interface_nnrt ./build.sh --product-name productname –ccache --build-target drivers_interface_nnrt
``` ```
> productname为产品名称,此处为rk3568. > productname为产品名称,此处为RK3568。
编译完成后,在```out/rk3568/gen/drivers/interface/nnrt```目录下生成HDI头文件,默认语言类型为C++;若需要生成C类型的头文件,请在编译之前使用如下命令对```drivers/interface/nnrt/v1_0/BUILD.gn```文件中的```language```配置项进行设置。 编译完成后,在```out/rk3568/gen/drivers/interface/nnrt```目录下生成HDI头文件,默认语言类型为C++。若需要生成C类型的头文件,请在编译之前使用如下命令对```drivers/interface/nnrt/v1_0/BUILD.gn```文件中的```language```配置项进行设置。
```shell ```shell
language = "c" language = "c"
...@@ -92,9 +93,9 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -92,9 +93,9 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
└── prepared_model_stub.h └── prepared_model_stub.h
``` ```
2. 实现HDI服务。 #### 实现HDI服务
1. 在drivers/peripheral目录下新建开发目录,用于HDI服务开发,开发目录结构如下所示。 1. 在drivers/peripheral目录下新建开发目录,用于HDI服务开发,开发目录结构如下所示:
```text ```text
drivers/peripheral/nnrt drivers/peripheral/nnrt
├── BUILD.gn # 代码编译脚本文件 ├── BUILD.gn # 代码编译脚本文件
...@@ -116,12 +117,13 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -116,12 +117,13 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
└── prepared_model_service.cpp # 编译AI模型对象服务端实现文件 └── prepared_model_service.cpp # 编译AI模型对象服务端实现文件
``` ```
2. 实现设备驱动,无特殊需求可直接使用步骤1中生成的nnrt_device_driver.cpp文件,否则根据具体驱动开发。 2. 实现设备驱动,无特殊需求可直接使用步骤1中生成的nnrt_device_driver.cpp文件,否则根据具体驱动开发。
3. 实现服务接口,可参考nnrt_device_service.cpp和prepared_model_service.cpp实现文件,接口定义可以参考[NNRt的HDI接口定义](https://gitee.com/openharmony/drivers_interface/tree/master/nnrt)。
4. 编译驱动和服务的实现文件为共享库 3. 实现服务接口,可参考nnrt_device_service.cpp和prepared_model_service.cpp实现文件,接口定义可以参考[NNRt的HDI接口定义](https://gitee.com/openharmony/drivers_interface/tree/master/nnrt)
在```drivers/peripheral/nnrt/hdi_cpu_service/```下新建```BUILD.gn```文件,文件内容如下所示,相关参数配置内容可参考[Build教程](https://gitee.com/openharmony/build). 4. 编译驱动和服务的实现文件为共享库。
在```drivers/peripheral/nnrt/hdi_cpu_service/```下新建```BUILD.gn```文件,文件内容如下所示,相关参数配置内容可参考[Build教程](https://gitee.com/openharmony/build)。
```shell ```shell
import("//build/ohos.gni") import("//build/ohos.gni")
...@@ -229,9 +231,9 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -229,9 +231,9 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
} }
``` ```
3. 声明HDI服务。 #### 声明HDI服务
在对应产品的uhdf hcs配置文件中声明用户态驱动与服务,例如,针对rk3568服务需要在```vendor/hihope/rk3568/hdf_config/uhdf/device_info.hcs```文件中新增如下配置: 在对应产品的uhdf hcs配置文件中声明用户态驱动与服务,例如针对RK3568服务需要在```vendor/hihope/rk3568/hdf_config/uhdf/device_info.hcs```文件中新增如下配置:
```text ```text
nnrt :: host { nnrt :: host {
hostName = "nnrt_host"; hostName = "nnrt_host";
...@@ -249,10 +251,9 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -249,10 +251,9 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
} }
} }
``` ```
> 注意:修改hcs文件需要删除out目录重新编译,才能生效。 > 注意:修改hcs文件需要删除out目录重新编译,才能生效。
4. 配置host进程用户和组。
#### 配置host进程用户ID和组ID
对于新增的nnrt_host进程的场景,需要配置对应进程的用户ID和组ID。 进程的用户ID在文件```base/startup/init/services/etc/passwd```中配置,进程的组ID在文件```base/startup/init/services/etc/group```中配置。 对于新增的nnrt_host进程的场景,需要配置对应进程的用户ID和组ID。 进程的用户ID在文件```base/startup/init/services/etc/passwd```中配置,进程的组ID在文件```base/startup/init/services/etc/group```中配置。
```text ```text
# 在base/startup/init/services/etc/passwd新增 # 在base/startup/init/services/etc/passwd新增
...@@ -262,25 +263,25 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -262,25 +263,25 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
nnrt_host:x:3311: nnrt_host:x:3311:
``` ```
5. SeLinux配置。 #### 配置SELinux
OHOS已经开启SELinux特性,需要对新增的进程和服务配置相应的SELinux规则,用于运行host进程启动访问某些资源、发布HDI服务。 OpenHarmony已经开启SELinux特性,需要对新增的进程和服务配置相应的SELinux规则,用于运行host进程启动访问某些资源、发布HDI服务。
1. 在```base/security/selinux/sepolicy/ohos_policy/drivers/adapter/vendor/type.te```文件中配置nnrt_host进程安全上下文,新增配置如下: 1.```base/security/selinux/sepolicy/ohos_policy/drivers/adapter/vendor/type.te```文件中配置nnrt_host进程安全上下文,新增配置如下:
```text ```text
# 新增配置 # 新增配置
type nnrt_host, hdfdomain, domain; type nnrt_host, hdfdomain, domain;
``` ```
> nnrt_host为上文配置的进程名称。 > nnrt_host为上文配置的进程名称。
2. 由于SeLinux是白名单访问的权限机制,需要根据实际权限需求配置,将服务启动起来之后,通过以下dmesg命令可能查看avc告警, 2. 由于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 ```shell
hdc_std shell hdc_std shell
dmesg | grep nnrt dmesg | grep nnrt
``` ```
3. 新建nnrt_host.te配置文件,将权限配置到nnrt_host.te文件中。 3. 新建nnrt_host.te配置文件,将权限配置到nnrt_host.te文件中。
```shell ```shell
# 创建nnrt文件夹 # 创建nnrt文件夹
mkdir base/security/selinux/sepolicy/ohos_policy/drivers/peripheral/nnrt mkdir base/security/selinux/sepolicy/ohos_policy/drivers/peripheral/nnrt
...@@ -292,7 +293,7 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -292,7 +293,7 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
touch base/security/selinux/sepolicy/ohos_policy/drivers/peripheral/nnrt/vendor/nnrt_host.te touch base/security/selinux/sepolicy/ohos_policy/drivers/peripheral/nnrt/vendor/nnrt_host.te
``` ```
4. 将所需的权限写入nnrt_host.te文件中,比如: 4. 将所需的权限写入nnrt_host.te文件中,比如:
```text ```text
allow nnrt_host dev_hdf_kevent:chr_file { ioctl }; allow nnrt_host dev_hdf_kevent:chr_file { ioctl };
allow nnrt_host hilog_param:file { read }; allow nnrt_host hilog_param:file { read };
...@@ -301,18 +302,32 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -301,18 +302,32 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
allow sh nnrt_host:fd { use }; allow sh nnrt_host:fd { use };
``` ```
6. 删除out目录编译整个系统。 #### 配置部件编译入口
```shell 以RK3568产品为例:
# 删除out目录 ```shell
rm -rf ./out vim //productdefine/common/inherit/chipset_common.json
```
# 编译 在"subsystems", "subsystem":"hdf", "components"中添加:
./build.sh --product-name rk3568 –ccache --jobs=4 ```shell
``` {
"component": "drivers_peripheral_foo",
"features": []
}
```
#### 删除out目录并编译整个系统
```shell
# 删除out目录
rm -rf ./out
# 编译
./build.sh --product-name rk3568 –ccache --jobs=4
```
### 调测验证 ### 调测验证
服务开发完成后,可以使用XTS用例验证基本功能和兼容性,开发者可通过以下步骤进行验证: 服务开发完成后,可以使用XTS用例验证基本功能和兼容性,开发者可通过以下步骤进行验证:
1. 编译NNRt的hats用例,用例在```test/xts/hats/hdf/nnrt```目录下。 1. 编译NNRt的hats用例,用例在```test/xts/hats/hdf/nnrt```目录下。
```shell ```shell
# 进入hats目录 # 进入hats目录
...@@ -341,7 +356,7 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -341,7 +356,7 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
hdc_std shell "/data/local/tmp/HatsHdfNnrtFunctionTest" hdc_std shell "/data/local/tmp/HatsHdfNnrtFunctionTest"
``` ```
所有hats用例执行成功,可以看到测试报告通过47个用例,说明服务通过了兼容性测试。 所有hats用例执行成功,可以看到测试报告显示已通过47个用例,说明服务通过了兼容性测试。
```text ```text
... ...
[----------] Global test environment tear-down [----------] Global test environment tear-down
...@@ -352,13 +367,16 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -352,13 +367,16 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
### 开发实例 ### 开发实例
完整Demo代码可以参考[社区实现](https://gitee.com/openharmony/ai_neural_network_runtime/tree/master/example/drivers) 完整Demo代码可以参考[社区实现](https://gitee.com/openharmony/ai_neural_network_runtime/tree/master/example/drivers)
1. 拷贝```example/driver/nnrt```目录到```drivers/peripheral```路径下。 1. 拷贝```example/driver/nnrt```目录到```drivers/peripheral```路径下。
```shell ```shell
cp -r example/driver/nnrt drivers/peripheral cp -r example/driver/nnrt drivers/peripheral
``` ```
2. 补充bundle.json文件到```drivers/peripheral/nnrt```,bundle.json参考本教程上面的[开发步骤](#开发步骤)章节。 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) 3. 由于Demo依赖MindSpore Lite CPU算子,故需要添加MindSpore Lite依赖文件。
- 下载MindSpore Lite的头文件,[MindSpore Lite 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依赖库和头文件。 -```drivers/peripheral/nnrt```目录下新建mindspore目录,用于存放mindspore依赖库和头文件。
```shell ```shell
mkdir drivers/peripheral/nnrt/mindspore mkdir drivers/peripheral/nnrt/mindspore
...@@ -372,7 +390,7 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -372,7 +390,7 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
# 拷贝mindspore schema文件 # 拷贝mindspore schema文件
cp third_party/mindspore/mindspore/lite/schema/* drivers/peripheral/nnrt/hdi_cpu_service/include/mindspore_schema/ cp third_party/mindspore/mindspore/lite/schema/* drivers/peripheral/nnrt/hdi_cpu_service/include/mindspore_schema/
``` ```
- 编译MindSpore-Lite的动态库,并将动态库放到mindspore目录下。 - 编译MindSpore Lite的动态库,并将动态库放到mindspore目录下。
```shell ```shell
# 编译mindspore动态库 # 编译mindspore动态库
./build.sh --product-name rk3568 -ccaache --jobs 4 --build-target mindspore_lib ./build.sh --product-name rk3568 -ccaache --jobs 4 --build-target mindspore_lib
...@@ -383,4 +401,4 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程 ...@@ -383,4 +401,4 @@ NNRt通过HDI接口实现与设备芯片的对接,由HDI接口实现跨进程
# 将mindspore动态拷贝到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/ cp out/rk3568/package/phone/system/lib/libmindspore-lite.huawei.so drivers/peripheral/nnrt/mindspore/mindspore/
``` ```
4. 其他配置请参考本教程上面的[开发步骤](#开发步骤)章节。 4. 其他配置请参考本教程上面的[开发步骤](#开发步骤)章节。
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册