基础环境配置
环境配置将配置一台 x86 计算机和荔枝派开发板,为在开发板 NPU 或 CPU 上运行模型做好准备。
为了在开发板上运行模型,需要首先在 x86 机器上将 onnx 等通用模型使用 hhb 工具转换为开发板 CPU/NPU 能够执行的计算图和胶水代码,并将胶水代码及相关应用代码交叉编译为开发板能够执行的二进制程序。
由于 x86 机器一般来说性能较好,且转换所需的 hhb 工具仅支持 x86 体系结构,因此额外需要一台 x86 计算机完成模型转换工作。
开发板配置
Lichee Pi 4A 是 Sipeed 使用 TH1520 芯片推出的开发板,基本开发板开箱配置可以参考官网中的开发板硬件配置。开发板的操作系统选择 RevyOS 20250526 版本。你可以在镜像刷写教程模块查看如何将 RevyOS 刷写进系统。
基础工具安装
RevyOS 系统默认没有安装 pip
等基础工具。在此一并安装上。
debian@revyos-lpi4a:~$ sudo apt install python3-pip python3-venv wget curl git # 安装相关软件包
debian@revyos-lpi4a:~$ mkdir npu # 创建Python虚拟环境
debian@revyos-lpi4a:~$ cd npu
debian@revyos-lpi4a:~/npu$ python3 -m venv .venv
debian@revyos-lpi4a:~/npu$ . .venv/bin/activate # 激活虚拟环境
(.venv) debian@revyos-lpi4a:~/npu$ # 进入了虚拟环境
如果成功安装并进入了虚拟环境,命令提示符前应当有 (.venv)
标识,括号内代表虚拟环境所在的文件夹。
SHL 库安装
SHL(Structure of Heterogeneous Library,中文名石斛兰)是 T-Head 提供的异构计算高性能库。SHL 主要的函数接口使用了 T-Head 针对玄铁 CPU 平台的神经网络库 API:CSI-NN2,并且提供了一系列已优化的二进制库。用户手册
使用虚拟环境内的 pip
安装 SHL 库。
(.venv) debian@revyos-lpi4a:~/npu$ pip3 install shl-python -i https://pypi.tuna.tsinghua.edu.cn/simple
...
Successfully installed shl-python-3.2.2
pypi
服务器默认处于国外,在国内使用可能遇到网络问题。因此,可以使用 pip
的 -i
参数设置临时 pypi
镜像服务器。有关设置镜像服务器的更多信息,可参考清华大学镜像站pypi使用帮助
安装后,使用 SHL 模块命令 --whereis
查看安装位置。
- NPU
- 仅 CPU
(.venv) debian@revyos-lpi4a:~/npu$ python3 -m shl --whereis th1520
/home/debian/npu/.venv/lib/python3.11/site-packages/shl/install_nn2/th1520
(.venv) debian@revyos-lpi4a:~/npu$ python3 -m shl --whereis c920
/home/debian/npu/.venv/lib/python3.11/site-packages/shl/install_nn2/c920
根据命令打印的位置(如上高亮行所示),通过设置环境变量 LD_LIBRARY_PATH
来指定动态库搜索路径。例如,以上个代码块中输出的路径为例,可以使用如下命令:
- NPU
- 仅 CPU
$ export SHL_PATH=/home/debian/npu/.venv/lib/python3.11/site-packages/shl/install_nn2/th1520/lib # 这里填写上面输出的路径
$ export SHL_PATH=/home/debian/npu/.venv/lib/python3.11/site-packages/shl/install_nn2/c920/lib # 这里填写上面输出的路径
并使用 export
命令将其添加到环境变量中。这样,系统在运行时就能找到 SHL 的动态库。
$ export LD_LIBRARY_PATH=$SHL_PATH:$LD_LIBRARY_PATH
如需长期生效,可将上述 export
命令添加到 ~/.bashrc
或 ~/.profile
文件末尾。
HHB-onnxruntime 安装
HHB-onnxuruntime 是移植了 SHL 的后端(execution providers),让 onnxruntime 能复用到 SHL 中针对玄铁 CPU 的高性能优化代码。
- NPU
- 仅 CPU
$ wget https://github.com/zhangwm-pt/prebuilt_whl/raw/refs/heads/python3.11/numpy-1.25.0-cp311-cp311-linux_riscv64.whl
$ wget https://github.com/zhangwm-pt/onnxruntime/releases/download/riscv_whl_v2.6.0/hhb_onnxruntime_th1520-2.6.0-cp311-cp311-linux_riscv64.whl
$ pip install numpy-1.25.0-cp311-cp311-linux_riscv64.whl hhb_onnxruntime_th1520-2.6.0-cp311-cp311-linux_riscv64.whl
$ wget https://github.com/zhangwm-pt/prebuilt_whl/raw/refs/heads/python3.11/numpy-1.25.0-cp311-cp311-linux_riscv64.whl
$ wget https://github.com/zhangwm-pt/onnxruntime/releases/download/riscv_whl_v2.6.0/hhb_onnxruntime_c920-2.6.0-cp311-cp311-linux_riscv64.whl
$ pip install numpy-1.25.0-cp311-cp311-linux_riscv64.whl hhb_onnxruntime_c920-2.6.0-cp311-cp311-linux_riscv64.whl
如果你在中国大陆访问 GitHub 时遇到网络问题,可以考虑使用网络代理工具来加速访问。
NPU 驱动配置
相比 CPU 执行,在使用 NPU 推理模型前,还需要确保 NPU 的驱动模块 vha
已正确加载,使用 lsmod
命令可罗列当前已加载的驱动。
$ lsmod | grep vha
vha 970752 0
img_mem 827392 1 vha
如果上面的命令没有输出 vha
模块(高亮行),则需要手动加载该模块。
$ sudo modprobe vha vha_info img_mem
除了内核态驱动之外,执行 NPU 还有一些用户态驱动支撑,可以查看 /usr/lib
目录,确保已有如下动态库:
libimgdnn.so
libnnasession.so
libimgdnn_execute.so
由于 RevyOS 已预装这些动态库,因此一般无需手动安装。
NPU 设备权限配置
在加载 NPU 驱动后,NPU 设备 /dev/vha0
的权限可能需要调整,以便用户能够访问。
为了方便起见,你可以将设备的权限改为 0666(所有用户可读写):
$ sudo chmod 0666 /dev/vha0 # 将设备权限改为 0666
然而,为了安全起见,建议配置 udev
规则来管理设备权限,你可以询问 AI 如何配置 udev
规则。
x86 机器配置
和语雀原版不同,本教程使用构建好的 Docker 镜像完成安装。请在计算机上安装好 Docker。
获取并启动 HHB 镜像
$ docker pull hhb4tools/hhb:2.6.17 # 拉取 HHB 镜像
$ docker run --rm -it hhb4tools/hhb:2.6.17 bash # 进入一个临时 HHB 镜像容器
HHB 镜像较大(~7G),下载可能需要一些时间,请耐心等待,并提前确认磁盘空间充足。
运行上述两条命令后,容器就已经启动,能够在其中运行操作了。
容器内的文件系统是临时的,容器退出后,所有在容器内创建的文件都会被删除。因此,建议在容器内运行完命令后,将生成的文件拷贝到主机上,或运行一个持久化的容器。
有关 Docker 的更多信息,请参考 Docker 官方文档或询问 AI 。
示例代码获取
本教程配套的示例代码已更新到 Github 中,使用 git
命令将其克隆到本地。
$ git clone https://github.com/zhangwm-pt/lpi4a-example.git
OpenCV 获取
教程中使用的 OpenCV 4.5 版本,针对 C920 所用的 RISC-V vector spec 0.7.1 做了针对性优化。 教程中使用已经预编译好的二进制库,其源码可通过 OCC 下载页面 下载。
C++ 接口的预编译好的二进制库已经保存在 Github,可通过下面的命令更新示例程序的子模块下载。
$ # 假设已经处在仓库根目录
$ git submodule update --init --recursive