典型应用
更新历史
日期 | 版本 | 作者 | 更新内容 |
---|---|---|---|
2023-09-12 | v1.2 | ztd |
|
2023-07-20 | v1.1 | ztd |
|
2023-05-08 | v1.0 | wonder |
|
一、llama.cpp#
llama 是 META 开源的大语言模型,llama.cpp 是 ggerganov 开源的纯 cpp 运行的 llama 推理项目。
感谢 llama.cpp 这个优秀的项目,我们可以在 LicheePi 4A 上运行 LLM。
笔者在早些时候稍微修改了 llama.cpp https://github.com/Zepan/llama.cpp,使其可以在更小内存(低至 700MB 左右)运行 7B 模型。
可以看到 TH1520 花费约 6s 计算一个 token(未使用 V 扩展加速,V 扩展加速预计可加速 4~8 倍,如果你加入了 V 扩展支持,欢迎投稿!)
同时还简单测试了下在入门级 C906 内核上运行7B模型的可行性,由于 D1 的内存过小,使用了 mmap 方式只读扩展,所以引入了大量低速 IO 操作,使得运行速度大为降低,最后仅 18s/token
二、YOLOX 目标检测#
本教程是一个如何在 LPi4A(LicheePi 4A) 开发板平台上部署 YOLOX 模型完成目标检测的示例(CPU推理)。
教程中包括了:
- 在 LPi4A 开发版上安装 Python 环境
- 使用 YOLOX 项目中的源码执行模型
教程遵循通常的模型部署流程:
- LPi4A 上的基础 Python 环境配置
- 获取 yolox 源码和模型
- 安装 yolox 所依赖的 python 包
- LPi4A 上的使用 HHB-onnxruntime 执行示例
基础 Python 环境配置
基本软硬件配置
参考 LPi4A 的 《开箱体验》中的描述,正确安装好开发板,上电启动后以 root 权限进入。
确保已联网的状态下,更新 apt 源
安装一些软件,用于示例中后续使用
安装 SHL 库
Python 环境配置
LPi4A 烧录的系统中已默认安装 python 3.11 版本。可以使用如下命令确认
后续均以 python3.11 版本为例,其他版本在安装依赖时需要修改到对应版本的命令。
各种 python 程序软件依赖的软件包大多可通过 pip 安装,可以使用如下命令安装 pip
安装其他python包之前,先安装 venv 包,用于创建python虚拟环境
创建 python虚拟环境,并激活
至此,基本 python 环境已经创建完成,与其他体系结构类似,可以直接通过 pip install 安装纯 python 包。
opencv 安装是会依赖其他 python 包,如果 pip 不能自动下载,则可以先手动安装依赖项的安装包。如何获取安装包可以参考 下载 riscv whl。
获取 YOLOX 模型
YOLOX 是一个类 YOLO 的目标检测模型,有相当优异的性能表现。
可以直接下载 github 上的源码和模型
修改源码
本教程将使用 HHB-onnxruntime 执行模型,因此切换到。在源码中的 onnxruntime 示例目录,修改文件 demo/ONNXRuntime/onnx_inference.py 的开头新增两行代码
代码中使用 sys.path.insert 指定搜索路径,以此免去从源码中安装 YOLOX 的安装包的操作。
安装依赖包
RISC-V 体系结构的 python 生态还有欠缺,未来完善之后,YOLOX 中依赖的包可以通过 requirements.txt 文件直接安装。
本教程中的 YOLOX 示例依赖了较多的 python 包,下载预编译好的 python 包
可以按照以下顺序,手工处理。
安装过程中会涉及到其他纯 python 依赖包,pip 会自动从官方源下载。
安装 HHB-onnxruntime
HHB-onnxuruntime 是移植了 SHL 后端(execution providers),让 onnxruntime 能复用到 SHL 中针对玄铁 CPU 的高性能优化代码。
执行
在示例目录中执行 onnx_inference.py 示例
python3 onnx_inference.py -m yolox_s.onnx -i soccer.jpg -o outdir -s 0.3 --input_shape640,640
参数说明:
- -m:指定模型
- -i:指定图片
- -o:指定输出目录
- -s:指定检测的阈值
- --input_shape:指定检测时使用的图片尺寸
参考结果
本教程中输入如下图,是运动员踢足球的图片,预期的检测结果是检测到两个人和一个足球。
图片来源于网络
示例正常执行后,会在 outdir 目录下生成结果图片 soccer.jpg。图片中会用框画出检测到的目标,并标注概率,效果如下图:
三、MobilenertV2#
本教程是一个如何在 LicheePi4A 平台上部署 mobilenetv2 模型完成图像分类的示例。
教程中包括了:
- 使用 HHB 编译 onnx 模型为 LicheePi4A 上可用的二进制
- 在 LicheePi4A 上使用 opencv c++ 版本做 mobilenetv2 模型的预处理
- 在 LicheePi4A 上使用 CPU 和 NPU 的差异
3.1. NPU#
3.1.1. 环境配置#
参考外设使用文档搭建好 NPU 使用相关环境后,进入到 HHB 环境的 Docker 镜像中。
首先获取本节教程的模型,下载到示例目录 /home/example/th1520_npu/onnx_mobilenetv2_c++
下:
mobilenetv2-12.onnx
并获取本次教程所使用的优化版本 opencv 所需的库文件,前往 github仓库下载下载到上一级目录 /home/example/th1520_npu/
下。
3.1.2. 编译#
HHB 编译模型:
将 ONNX 模型交叉编译成 NPU 上可执行的程序,需要使用 hhb 命令。注意,NPU 上仅支持8位或者16位定点运算,本示例中指定为 int8 非对称量化。编译时需要先进入到示例所在目录 /home/example/th1520_npu/onnx_mobilenetv2_c++
:
选项说明:
- -D :指定 HHB 流程执行到生成可执行文件的阶段为止
- --model-file :指定当前目录中已经下载好的 mobilenet 模型
- --data-mean :指定均值
- --data-scale :指定缩放值
- --board :指定目标平台为 th1520
- --input-name: 模型的输入名
- --output-name:模型的输出名
- --input-shape:模型的输入大小
- --postprocess:保存输出结果,并且打印 top5 结果
- --calibrate-dataset:指定量化时所需的校准图片
- --quantization-scheme:指定量化方式为 int8 非对称
命令执行完成后,会在当前目录生成 hhb_out 子目录,里面的包括了 hhb_runtime,model.c 等多个文件:
- hhb.bm:HHB 的模型文件,包括了量化后的权重数据等信息
- hhb_runtime:th1520 平台上的可执行文件,由目录中的c文件编译而成
- main.c:临时文件,示例程序的参考入口
- model.c:临时文件,模型结构文件,与模型结构相关
- model.params:临时文件,权重数值
- io.c:临时文件,读写文件的辅助函数
- io.h:临时文件,读写文件的辅助函数声明
- process.c:临时文件,图像预处理函数
- process.h:临时文件,图像预处理函数声明
更详细的 HHB 选项说明可以参考 HHB用户手册中的命令行选项说明。
g++编译示例:
编译命令正确执行完成后会在示例目录生成 mobilenetv2_example 文件。
3.1.3. 执行#
交叉编译完成后,即可将程序执行所需的文件复制到开发板的目录中。可以使用 scp 命令:
先确认开发板中驱动是否加载:
若在输出中有 img_mem
,vha
和 vha_info
这三个模块,NPU驱动即加载成功。
参考 YOLOX章节 安装并配置好 python 虚拟环境:
在开发板相应目录下运行刚刚编译好的示例:
执行完成后,会在终端上提示执行到的各个阶段:
- 预处理
- 模型执行
- 后处理
mobilenetv2_example 执行会使用到的文件:
- persian_cat.jpg:输入图片
- input_img.bin:预处理阶段,根据输入图片生成的中间结果
- hhb_out/hhb_runtime:模型执行阶段使用的文件,由x86主机上 HHB 生成
- hhb_out/hhb.bm:模型执行阶段使用的文件,由x86主机上 HHB 生成
- input_img.bin_output0_1_1000.txt:模型执行阶段的输出文件,包括了模型执行输出的 1000 个结果数值
3.1.4. 参考结果#
3.2. CPU#
将上述 NPU 步骤中的 HHB 编译命令替换为:
g++ 编译后处理命令替换为:
再将编译的到的二进制文件发送到开发板上运行即可。参考结果如下:
四、Yolov5n#
4.1. NPU#
4.1.1. 环境配置#
参考外设使用文档搭建好 NPU 使用相关环境后,进入到 HHB 环境的 Docker 镜像中。
首先获取本节教程的模型,下载到示例目录 /home/example/th1520_npu/yolov5n
下:
4.1.2. 编译#
HHB 编译模型:
将 ONNX 模型交叉编译成 NPU 上可执行的程序,需要使用 hhb 命令。注意,NPU 上仅支持8位或者16位定点运算,本示例中指定为 int8 非对称量化。编译时需要先进入到示例所在目录 /home/example/th1520_npu/yolov5n
:
选项说明:
- -D :指定 HHB 流程执行到生成可执行文件的阶段为止
- --model-file :指定当前目录中已经下载好的 yolov5 模型
- --data-mean :指定均值
- --data-scale :指定缩放值
- --board :指定目标平台为 th1520
- --input-name: 模型的输入名
- --output-name:模型的输出名
- --input-shape:模型的输入大小
- --postprocess:保存输出结果,并且打印 top5 结果
- --calibrate-dataset:指定量化时所需的校准图片
- --quantization-scheme:指定量化方式为 int8 非对称
命令执行完成后,会在当前目录生成 hhb_out 子目录,里面的包括了 hhb_runtime,model.c 等多个文件:
- hhb.bm:HHB 的模型文件,包括了量化后的权重数据等信息
- hhb_runtime:th1520 平台上的可执行文件,由目录中的c文件编译而成
- main.c:临时文件,示例程序的参考入口
- model.c:临时文件,模型结构文件,与模型结构相关
- model.params:临时文件,权重数值
- io.c:临时文件,读写文件的辅助函数
- io.h:临时文件,读写文件的辅助函数声明
- process.c:临时文件,图像预处理函数
- process.h:临时文件,图像预处理函数声明
更详细的 HHB 选项说明可以参考 HHB用户手册中的命令行选项说明。
g++编译示例:
编译命令正确执行完成后会在示例目录生成 yolov5n_example 文件。
4.1.3. 执行#
交叉编译完成后,即可将程序执行所需的文件复制到开发板的目录中。可以使用 scp 命令:
先确认开发板中驱动是否加载:
若在输出中有 img_mem
,vha
和 vha_info
这三个模块,NPU驱动即加载成功。
参考 YOLOX章节 安装并配置好 python 虚拟环境:
在开发板相应目录下运行刚刚编译好的示例:
执行完成后,会在终端上提示执行到的各个阶段:
- 预处理:将原图填充缩放到 384 * 640 的大小
- 模型执行和后处理:执行模型推理,并做 nms 等后处理
- 画框:将检测结果画在 384 *640 尺寸的图上,并输出新图片
inference.py 执行会使用到的文件:
- kite.jpg:输入图片
- image_preprocessed.bin:预处理阶段,根据输入图片生成的中间结果
- yolov5n_example:模型执行阶段使用的文件,由x86主机上 gcc 编译生成
- hhb_out/hhb.bm:模型执行阶段使用的文件,由x86主机上 HHB 生成
- detect.txt:后处理阶段的输出文件,包括了图片中检测出来的 4 个目标
- kite_result.jpg:输出图片,将检测框加入到输入图上的结果
4.1.4. 参考结果#
示例图片来源于网络。
4.2. CPU#
将上述 NPU 步骤中的 HHB 编译命令替换为:
gcc 编译后处理命令替换为:
再将编译的到的二进制文件发送到开发板上运行即可。参考结果如下:
五、Yolov5s#
参考 yolov5n 的编译步骤,只需将 yolov5n.onnx 文件替换为 yolov5s.onnx,并将 HHB 和 GCC 编译命令中的参数 yolov5n.onnx
更改为 yolov5s.onnx
即可。
5.1. 环境配置#
在 x86 主机中,参考外设使用文档搭建好 NPU 使用相关环境后,进入到 HHB 环境的 Docker 镜像中。
在 1520 上,参考 YOLOX章节 安装并配置好 python 虚拟环境。
5.2. CPU#
5.2.1. 编译过程#
HBB 编译
HHB 命令中截取到最后的卷积层为止,卷积层之后的后处理,由 yolov5s.c 文件处理。yolov5s.c
可以参考 yolov5n 示例下的 yolov5n.c
文件。
GCC 编译
5.2.2. 参考结果#
5.3. NPU#
5.3.1. 编译过程#
参考 yolov5n 即可。
HHB 编译
GCC 编译
HHB 命令中截取到最后的卷积层为止,卷积层之后的后处理,由 yolov5s.c 文件处理。yolov5s.c
可以参考 yolov5n 示例下的 yolov5n.c
文件。
5.3.2. 参考结果#
六、BERT#
6.1. CPU#
6.1.1. 环境配置#
参考外设使用文档搭建好 NPU 使用相关环境后,进入到 HHB 环境的 Docker 镜像中。
首先获取模型,本教程中使用的模型来自 google bert 仓库,已转换成 onnx 版本的 BERT 模型,可以用如下命令下载到 /home/example/c920/bert_small
目录下:
6.1.2. 编译#
HHB 编译模型:
将 ONNX 模型交叉编译成 NPU 上可执行的程序,需要使用 hhb 命令。注意,NPU 上仅支持8位或者16位定点运算,本示例中指定为 int8 非对称量化。编译时需要先进入到示例所在目录 /home/example/c920/bert_small
:
选项说明:
- -D :指定 HHB 流程执行到生成可执行文件的阶段为止
- --model-file :指定当前目录中已经下载好的 bert 模型
- --data-mean :指定均值
- --data-scale :指定缩放值
- --board :指定目标平台为 th1520
- --input-name: 模型的输入名
- --output-name:模型的输出名
- --input-shape:模型的输入大小
- --postprocess:保存输出结果,并且打印 top5 结果
- --calibrate-dataset:指定量化时所需的校准图片
- --quantization-scheme:指定量化方式为 int8 非对称
命令执行完成后,会在当前目录生成 hhb_out 子目录,里面的包括了 hhb_runtime,model.c 等多个文件:
- hhb.bm:HHB 的模型文件,包括了量化后的权重数据等信息
- hhb_runtime:th1520 平台上的可执行文件,由目录中的c文件编译而成
- main.c:临时文件,示例程序的参考入口
- model.c:临时文件,模型结构文件,与模型结构相关
- model.params:临时文件,权重数值
- io.c:临时文件,读写文件的辅助函数
- io.h:临时文件,读写文件的辅助函数声明
- process.c:临时文件,图像预处理函数
- process.h:临时文件,图像预处理函数声明
更详细的 HHB 选项说明可以参考 HHB用户手册 中的命令行选项说明。
编译命令正确执行完成后会在示例目录生成可执行文件,将该示例目录拷贝至开发板中即可运行。
6.1.3. 执行#
执行示例程序的前置步骤同 YOLOv5n,此处不在赘述。
前置步骤准确无误后,即可在示例目录执行命令
6.1.4. 参考结果#
本示例中的参考输入来自 SQuAD 数据集,SQuAD 是一个阅读理解数据集,由一组维基百科文章提出的问题组成,其中每个问题的答案都是来自相应阅读文章或问题的一段文本。
本示例的输入如下,文章内容描述了一次橄榄球比赛的赛况,提出的问题是谁参加了比赛。
根据阅读理解的结果,预期输出将是 Denver Broncos
七、Docker#
首先安装所需要的软件包
安装完成后,使用 sudo docker info
命令验证安装是否成功:
若想让普通用户也有 Docker 的执行权限,可以执行以下命令来实现:
这些命令添加普通用户权限的用户名到 docker
用户组,并激活组权限。若不添加,则每次执行 Docker 相关命令时,需要以 sudo 权限来执行。
接下来,我们拉取 hello-world 镜像体验 Docker 的使用:
接下来,启动刚刚拉取下来的容器:
查看 hello-world 镜像的相关信息:
若要体验更完整的镜像,去这里搜索想要使用的发行版名称,拉取即可。
八、K3s-RISCV#
该章节将展示如何在 LPi4A 上运行轻量级的 Kubernetes 发行版本 K3s。
先下载预编译的 K3s包:
https://github.com/CARV-ICS-FORTH/k3s/releases
然后将下载下来的包合并为一个 .gz
文件并解压,完成后给 k3s 添加执行权限:
验证是否能成功运行,成功运行的典型输出如下:
现在,下载并运行 k3s 的安装脚本:
运行完成后,使用如下命令检查 k3s 是否正常运行。典型输出如下:
接下来我们新建一个配置文件,运行 k3s 容器:
然后使用这个配置文件启动一个容器。典型输入如下:
然后查看 pods 情况(若输出中没显示 IP 地址,可以多等待一会儿再查看):
接下来使用 curl 测试 k3s 容器是否运行成功,典型输出如下:
至此,k3s容器已经运行成功。
页面效果如下:
九、Minecraft Server#
这里以1.20.1
版本为例,LPi4A 作为 Server,电脑端(Ubuntu 22.04)作为 Client。
首先在这里下载由 Fizzed 优化的 nitro JDK 19,下载完成后解压,重命名文件夹并移动到 /opt/
目录下:
测试该 JDK 是否可用:
若出现版本号则可用。若已经预装了别的版本的 JDK,那么可以更改下软连接,先查看原先的软链接信息,记录下方便后面改回来:
然后更改软链接指向刚刚安装的 JDK:
使用命令验证软链接是否配置成功:
出现版本,则配置成功。
接下来,在这里下载原版服务端 jar 文件到 LPi4A,注意版本为1.20.1
,然后在 LPi4A 上先执行:
若出现提示
则将当前目录下的 eula.txt
文件中对应行改为的 false 改为 true:
保存后退出,重新启动服务器,第一次启动会比较慢,耐心等待,启动完成后会显示启动用时(下列用时并非第一次启动用时):
接下来,在 PC 端启动客户端后即可连接,建议使用第三方客户端启动器 HMCL(下载链接https://hmcl.huangyuhui.net/download/%EF%BC%89%E3%80%82
下载完成后,启动 HMCL:
可以直接在启动器中下载1.20.1
版本,并且配置好游戏账户,然后即可进入游戏,进入游戏后,输入 服务器 IP(LPi4A 的 IP)添加服务器后即可连接(确保电脑和 LPi4A 处于同一网络下),效果如下:
注意,若想改回原来版本的 JDK,则执行:
十、Wine-CE#
首先在这里下载 wine-ce_dlls_8.9.0.all.tar.xz
,wine-ce_core_8.9.0.riscv64.tar.xz
这两个文件,这里假设下载到用户主目录(撰写该文档时最新版本为8.9)。
然后根据文档中的步骤进行安装:
接下来进行一些初始化设置:
这里使用的设置如下:
设置完成后,即可运行 Windows 下的程序,比如这里的命令运行 Windows 下的记事本
十一、使用优化 GCC 工具链#
实验性 feature 如果发现问题可以进行 issue 申报。
安装步骤
测试 gcc-10 (gcc10.4 启用 xtheadc+v0p7)
测试 gcc-13 (gcc13.2 启用 xthead extension)
gcc-10/gcc-13 区别:
除了v0p7,其他优化都可以用 gcc-13 代替 gcc-10。
后者的优化可以主线报问题,是已经主线化的功能。
十二、SuperTuxKart#
SuperTuxKart 是一款 3D 开源街机赛车游戏,有各种角色、赛道和模式可供选择。在 LPi4A 上也可以通过源码编译来体验:
首先安装依赖:
接下来参考文档步骤编译:
编译完成后,在当前目录下的 bin/
文件夹中即可找到 supertuxkart
程序。运行即可:
效果如下:
十三、llama2.c#
项目链接
我们可以根据项目链接文档中的步骤来运行一个 Llama 2 的小模型。
首先 clone 该项目,并切换到改项目目录下:
然后下载 model.bin 文件,并放到指定目录下:
然后编译并运行:
可以得到如下输出:
也可以修改一些编译参数来加速:
13.1. Stable Diffusion#
本示例通过这个项目在 LPi4A 上运行 Stable Diffusion。
首先,我们需要构建 XNNPACK:
接下来,构建 Stable Diffusion example:
现在我们得到了可运行的 Stable Diffusion example 文件 sd
,使用如下参数运行:
其中,--models-path
是从该项目 Release 页面中下载的模型文件,可以放到 sd
文件的所在目录下。
运行时的配置如下:
得到的结果为result.png
文件,上述 prompt 得到的图片如下:
十四、PSP模拟器#
本示例通过这个项目在 LPi4A 上运行 PSP模拟器。
首先,我们需要构建 PPSSPP:
编译可能需要一段时间,出现以下输出时,编译成功:
安装完之后可以试运行一下(root模式下):
如图:
游戏下载:
psp游戏下载
下载完成:
我们只需要用到压缩包里的EBOOT.PBP文件
1.如果是使用图形界面则直接解压
2.如果使用命令行的话,需要将压缩包改成zip后缀再进行解压
开始游戏:在PPSSPPSDL命令下打开EBOOT.PBP即可
运行效果如图:
十五、opencv 的使用#
首先安装依赖,以及python3环境
opencv读取图片demo:
运行程序:
运行结果:
PIL-numpy-opencv 综合测试demo:
使用 USB 摄像头 demo
十六、ncnn 的使用#
首先,git源码和安装相关的依赖库
编译源码
下载相关的模型文件以及参数,将它们放在与可执行文件同个文件夹下
下载链接
执行
运行结果
十七、Kdenlive 的使用#
安装步骤:
若通过上面的命令安装的 Kdenlive 无法正常运行,可以尝试运行下面的命令:
安装完成后即可使用命令打开 kdenlive:
视频编辑效果如下:
十八、GStreamer#
GStreamer 是一个基于管道的多媒体框架,基于 GObject,以 C 语言写成。凭借 GStreamer,可以很容易地创建各种多媒体功能组件,包括简单的音频回放、音频和视频播放、录音、流媒体和音频编辑。基于流水线设计,可以创建诸如视频编辑器、流媒体广播和媒体播放器等等的很多多媒体应用。
接下来,展示如何在 LPi4A 上运行 GStreamer 的 demo。
首先,需要安装相关的依赖:
然后拉取相关源码仓库
进入到 gst-docs/examples/tutorials
目录下,编译出 basic-tutorial-1
可执行程序
编译成功后会在当前目录下生成可执行程序,使用下面的命令运行即可看到效果:
十九、Kicad#
注意,仅20231023及以上版本支持 kicad !
首先安装 Kicad :
安装完毕后,需要先运行以下命令才能运行 kicad:
打开 kicad:
在使用完 kicad 后,需要运行下面的命令以避免兼容性问题:
二十、KODI#
直接安装运行即可:
二十一、其它#
欢迎投稿~ 投稿接受后可得¥5~150($1~20)优惠券!
Gitalking ...