【求助】LicheePi 4A上测试yolov5n示例交叉编译后在开发板运行显示detect num:0


model: Lichee Pi 4A

profile: YOLOv5n

RuyiSDK示例

环境配置

开发板配置

安装python虚拟环境

sudo -i
apt install python3.11-venv
cd /root
python3 -m venv ort
source /root/ort/bin/activate

SHL库安装

# 1. 安装 shl-python
pip3 install shl-python -i https://pypi.tuna.tsinghua.edu.cn/simple

# 2. 查看安装位置并复制动态库到系统目录
python3 -m shl --whereis th1520
# 假设输出为 /home/debian/ort/lib/python3.11/site-packages/shl/install_nn2/th1520

# 3. 根据输出路径复制动态库(注意替换实际路径)
sudo cp /home/debian/ort/lib/python3.11/site-packages/shl/install_nn2/th1520/lib/* /usr/lib/
sudo ldconfig

HHB-onnxruntime 安装
HHB-onnxuruntime 是移植了 SHL 后端(execution providers),让 onnxruntime 能复用到 SHL 中针对玄铁 CPU 的高性能优化代码。
CPU 版本

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 hhb_onnxruntime_c920-2.6.0-cp311-cp311-linux_riscv64.whl

NPU版本

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 hhb_onnxruntime_th1520-2.6.0-cp311-cp311-linux_riscv64.whl

宿主机(x86)环境配置

安装docker

sudo apt update
sudo apt install -y ca-certificates curl
# 下载 Docker 官方安装脚本并执行

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

安装成功后查看docker及其状态:
``bash
docker --version
sudo systemctl status docker


在终端显示如下:
```text
licheepi@licheepi-virtual-machine:~$ docker --version
Docker version 29.4.1, build 055a478
licheepi@licheepi-virtual-machine:~$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled;>
     Active: active (running) since Fri 2026-04-24 13:35:46 CST; 

将当前用户加入 docker 组(免 sudo 运行)

sudo usermod -aG docker $USER
newgrp docker

拉取 HHB Docker 镜像

docker pull hhb4tools/hhb:latest

创建容器,名字为hhb_env

docker run -itd --name hhb_env hhb4tools/hhb:latest
#进入容器
docker exec -it hhb_env /bin/bash

下载Yolov5n模型
下载到示例目录 /home/example/th1520_npu/yolov5n 下:

mkdir -p /home/example/th1520_npu/yolov5n
cd /home/example/th1520_npu/yolov5n
git clone https://gitclone.com/github.com/ultralytics/yolov5.git
cd yolov5
pip3 install ultralytics

如果遇到python版本不兼容的问题:
在 Docker 容器内创建新的 Python 3.9 环境

# 安装 python3.9 和 venv
apt update
apt install -y python3.9 python3.9-venv

# 创建虚拟环境
python3.9 -m venv /opt/yolo-venv

# 激活虚拟环境
source /opt/yolo-venv/bin/activate

在新环境里安装依赖

# 升级 pip
pip install --upgrade pip
# 安装 ultralytics
pip install ultralytics
pip install opencv-python-headless -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pandas
pip install tqdm
pip install seaborn
#下载权重文件
wget https://github.com/ultralytics/yolov5/releases/downloals
d/v7.0/yolov5n.pt
cd /home/example/th1520_npu/yolov5n/yolov5
# 导出模型
python3 export.py --weights yolov5n.pt --include onnx --imgsz 384 640  

退出虚拟环境:

deactivate

HHB编译模型:
将 ONNX 模型交叉编译成 NPU 上可执行的程序,需要使用 hhb 命令。
编译时需要先进入到示例所在目录 /home/example/th1520_npu/yolov5n

cd /home/example/th1520_npu/yolov5n
cp yolov5/yolov5n.onnx .
hhb -D \
  --model-file yolov5n.onnx \
  --board th1520 \
  --input-name "images" \
  --input-shape "1 3 384 640" \
  --data-scale-div 255 \
  --output-name "/model.24/m.0/Conv_output_0;/model.24/m.1/Conv_output_0;/model.24/m.2/Conv_output_0" \
  --calibrate-dataset kite.jpg \
  --quantization-scheme "int8_asym"

在终端显示如下:

root@78776422f7c9:/home/example/th1520_npu/yolov5n# hhb -D \
>   --model-file yolov5n.onnx \
>   --data-scale-div 255 \
>   --board th1520 \
>   --input-name "images" \
>   --output-name "/model.24/m.0/Conv_output_0;/model.24/m.1/Conv_output_0;/model.24/m.2/Conv_output_0" \
>   --input-shape "1 3 384 640" \
>   --calibrate-dataset kite.jpg \
>   --quantization-scheme "int8_asym"
[2026-05-08 02:48:22] (HHB LOG): Start import model.
[2026-05-08 02:48:24] (HHB LOG): Model import completed! 
[2026-05-08 02:48:24] (HHB LOG): Start quantization.
[2026-05-08 02:48:24] (HHB LOG): get calibrate dataset from kite.jpg
[2026-05-08 02:48:24] (HHB LOG): Start optimization.
[2026-05-08 02:48:25] (HHB LOG): Optimization completed!
Calibrating: 100%|███████████████| 316/316 [00:37<00:00,  8.34it/s]
[2026-05-08 02:49:03] (HHB LOG): Start conversion to csinn.
[2026-05-08 02:49:04] (HHB LOG): Conversion completed!
[2026-05-08 02:49:04] (HHB LOG): Start operator fusion.
[2026-05-08 02:49:04] (HHB LOG): Operator fusion completed!
[2026-05-08 02:49:05] (HHB LOG): Start operator split.
[2026-05-08 02:49:05] (HHB LOG): Operator split completed!
[2026-05-08 02:49:05] (HHB LOG): Start layout convert.
[2026-05-08 02:49:05] (HHB LOG): Layout convert completed!
[2026-05-08 02:49:05] (HHB LOG): Quantization completed!

退出docker环境。

exit

在终端显示如下:

root@78776422f7c9:/home/example/th1520_npu/yolov5n# exit
exit
licheepi@licheepi-virtual-machine:~$ 

安装 RuyiSDK

# 下载并安装 ruyi
wget https://mirror.iscas.ac.cn/ruyisdk/ruyi/tags/0.47.0/ruyi-0.47.0.amd64
chmod +x ruyi-0.47.0.amd64
sudo cp ruyi-0.47.0.amd64 /usr/local/bin/ruyi

安装工具链

ruyi update
ruyi install gnu-plct-xthead

会在终端看到如下输出:


info: skipping already installed package gnu-plct-xthead-3.1.0-ruyi.20250526

YOLOV5n测试示例

创建并激活 ruyi 虚拟环境

创建虚拟环境 venv-sipeed

ruyi venv -t gnu-plct-xthead sipeed-lpi4a venv-sipeed 

激活虚拟环境

. venv-sipeed/bin/ruyi-activate 

终端显示如下:

licheepi@licheepi-virtual-machine:~$ ruyi venv -t gnu-plct-xthead sipeed-lpi4a venv-sipeed 
info: Creating a Ruyi virtual environment at venv-sipeed...
info: The virtual environment is now created.

You may activate it by sourcing the appropriate activation script in the
bin directory, and deactivate by invoking `ruyi-deactivate`.

A fresh sysroot/prefix is also provisioned in the virtual environment.
It is available at the following path:

    /home/licheepi/venv-sipeed/sysroot

The virtual environment also comes with ready-made CMake toolchain file
and Meson cross file. Check the virtual environment root for those;
comments in the files contain usage instructions.

licheepi@licheepi-virtual-machine:~$ . venv-sipeed/bin/ruyi-activate 
«Ruyi venv-sipeed» licheepi@licheepi-virtual-machine:~$ 

使用 ruyi 工具链编译示例代码

确认交叉编译器可用

riscv64-plctxthead-linux-gnu-g++ --version
# 复制整个yolov5n 目录
docker cp hhb_env:/home/example/th1520_npu/yolov5n .

把 Docker 里的官方库复制到宿主机

docker cp hhb_env:/usr/local/lib/python3.8/dist-packages/hhb/install_nn2/th1520 ./hhb_th1520

docker cp hhb_env:/usr/local/lib/python3.8/dist-packages/hhb/prebuilt/runtime/riscv_linux ./hhb_runtime

docker cp hhb_env:/usr/local/lib/python3.8/dist-packages/hhb/prebuilt/decode/install/lib/rv ./hhb_decode_lib

修改yolov5n.c源码:

cd ~/yolov5n
sed -i 's/shl_ref_f32_to_input_dtype/shl_c920_f32_to_input_dtype/g' yolov5n.c

最终编译命令:

riscv64-plctxthead-linux-gnu-gcc \
  yolov5n.c \
  -o yolov5n_example \
  hhb_out/io.c \
  hhb_out/model.c \
  -Wl,--gc-sections \
  -O2 -g \
  -mabi=lp64d \
  -I . \
  -I hhb_out/ \
  -I /home/licheepi/hhb_th1520/include/ \
  -I /home/licheepi/hhb_th1520/include/shl_public/ \
  -I /home/licheepi/hhb_th1520/include/csinn/ \
  -L /home/licheepi/hhb_th1520/lib/ \
  -lshl \
  -L /home/licheepi/hhb_decode_lib/ \
  -L /home/licheepi/hhb_runtime/ \
  -lprebuilt_runtime \
  -ljpeg -lpng -lz -lstdc++ -lm \
  -march=rv64gcv0p7_zfh_xtheadc \
  -Wl,-unresolved-symbols=ignore-in-shared-libs

解决 omp.h 缺失问题

mkdir -p /home/licheepi/venv-sipeed/sysroot.riscv64-plctxthead-linux-gnu/usr/include
docker cp hhb_env:/usr/lib/gcc/x86_64-linux-gnu/9/include/omp.h \
    /home/licheepi/venv-sipeed/sysroot.riscv64-plctxthead-linux-gnu/usr/include/
cp ~/omp.h ~/yolov5n/

运行示例并验证结果

把生成文件传递到开发板上:

scp -r /home/licheepi/yolov5n debian@172.16.60.209:~/

先确认开发板驱动是否加载:

lsmod

若在输出中有 img_mem,vha 和 vha_info 这三个模块,NPU驱动即加载成功。
若没有加载,手动加载模块:

sudo modprobe img_mem
sudo modprobe vha
sudo modprobe vha_info

激活开发板上的python虚拟环境,如没有安装,参考yolox文档进行安装
运行程序

cd yolov5n
sudo chmod 666 /dev/vha0
python3 inference.py 

在终端显示如下:

(ort) debian@revyos-lpi4a:~/yolov5n$ python3 inference.py
 ********** preprocess image **********
 ******* run yolov5 and postprocess *******
INFO: NNA clock:406720 [kHz]
INFO: Heap :anonymous (0x2)
INFO: Heap :dmabuf (0x2)
INFO: Heap :unified (0x5)
[14801.386147] ax3xxx-nna fffc800000.vha: vha_map_to_onchip: moving a page to on chip ram failed!
WARNING: Mapping to the on chip ram failed (128 > 0), continuing...
Run graph execution time: 5.62776ms, FPS=177.69
detect num: 0
id:     label   score           x1              y1              x2              y2
 ********** draw bbox **********

感觉是很常见的问题 :thinking: 再核对一下配置呢或者可以找ai看一下

是常见的问题吗?一般是什么原因造成的呢?我问ai重新配置了好多遍,一直这样 :smiling_face_with_tear: :face_with_spiral_eyes:

(来自 Grok)

问题核心:YOLOv5n NPU 示例在 LicheePi 4A (TH1520) 上能跑通(有 FPS 输出),但 detect num: 0,无检测框。 这是量化/编译/后处理链路中常见的不匹配导致的模型输出无效(置信度过低或 boxes 异常)。官方 Sipeed Wiki 示例能正常 detect num: 4,说明流程可行。

可能原因(按概率排序)

  1. 量化/校准问题:HHB 量化(int8_asym)依赖 kite.jpg 校准。如果图像预处理、输入 shape 或数据缩放不匹配,输出 logits 会异常,导致 NMS 后无有效框。
  2. 后处理/C 代码不匹配yolov5n.c 中的后处理(NMS、置信度阈值、anchor 等)与导出的 ONNX 或量化模型不符。用户做了 sed 替换 shl_ref_f32_to_input_dtype,但可能引入问题。
  3. 工具链/库不匹配:RuyiSDK + riscv64-plctxthead-linux-gnu-gcc vs 官方常用 riscv64-unknown-linux-gnu-gcc + HHB 预构建库。复制的 hhb_th1520 / runtime 库版本不一致。
  4. 输入预处理差异:Python inference.py 中的 preprocess(resize/pad/normalize)与 HHB 生成的 io.c/process.c 不一致。
  5. NPU 运行时警告(vha_map_to_onchip failed):可能影响内存布局,但通常会继续运行,性能仍高(~177 FPS),不是主因。

推荐修复步骤(从最简单开始)

  1. 严格跟随官方 Wiki 示例重新走一遍(推荐):

    • 用官方 Docker + HHB 环境(不要混用 RuyiSDK 编译)。
    • 下载 kite.jpg(校准图)和标准 yolov5n.c(从 Sipeed 示例目录或 wiki 关联资源)。
    • HHB 命令完全一致:
      hhb -D \
        --model-file yolov5n.onnx \
        --board th1520 \
        --input-name "images" \
        --input-shape "1 3 384 640" \
        --data-scale-div 255 \
        --output-name "/model.24/m.0/Conv_output_0;/model.24/m.1/Conv_output_0;/model.24/m.2/Conv_output_0" \
        --calibrate-dataset kite.jpg \
        --quantization-scheme "int8_asym"
      
    • 编译时用 wiki 中的 gcc 命令(riscv64-unknown-linux-gnu-gcc + 对应 include/lib 路径)。
    • 复制整个目录到板子上,运行 python3 inference.py 测试 kite.jpg。
  2. 检查/替换关键文件

    • 确认 yolov5n.c:确保未被错误修改。必要时从官方示例重新获取。检查其中 NMS 阈值(conf_thres ~0.25-0.5, iou_thres ~0.45)和输出解析是否正确。
    • 验证 ONNX 导出:在 Docker 中用 python export.py --weights yolov5n.pt --include onnx --imgsz 384 640(确保 opset 版本兼容 HHB)。
    • 校准数据集:只用一张 kite.jpg 有时不够稳。尝试加几张类似场景的图片到校准目录(–calibrate-dataset 支持目录)并重新量化。
  3. RuyiSDK 特定调整(如果你坚持用):

    • 激活 venv 后,确认 riscv64-plctxthead-linux-gnu-gcc 路径和 sysroot 正确。
    • 编译链接时,确保 -I/-L 指向正确的 hhb_th1520(从 Docker 复制的最新版本)。
    • 去掉或验证 sed 修改:shl_c920_f32_to_input_dtype 可能只适用于 CPU 后端,NPU 用 shl_th1520 相关。
    • 尝试静态链接或添加 -static 测试。
  4. 调试技巧

    • 打印中间输出:修改 inference.py 或 C 代码,保存模型原始输出 tensor,检查值范围(是否接近 0 或异常)。
    • 对比 CPU 模式:用 --board c920 重新编译 HHB(不量化或轻量化),看是否能 detect(排除 NPU 特有问题)。
    • 检查 preprocess:确保输入图像 resize 到 384x640 + pad + /255 与 HHB 一致。
    • NPU 驱动:确认 lsmod 有 img_mem/vha/vha_info,sudo chmod 666 /dev/vha0 已执行。
    • 查看 detect.txt 或日志中的 raw scores/boxes。
  5. 其他常见坑

    • Python 环境(ort venv)中依赖版本(opencv, numpy 等)必须匹配板子架构。
    • ONNX 输出节点名称必须精确匹配(wiki 中那三个 Conv_output)。
    • 模型输入是 BGR/RGB?预处理顺序。

如果按官方 Wiki 重新做仍为 0,提供以下信息 方便进一步诊断:

  • HHB 编译完整 log(尤其是 quantization 部分)。
  • yolov5n.c 关键片段(postprocess 函数)。
  • inference.py 输出(除了 detect num:0 还有无其他 warning?)。
  • 使用的 kite.jpg 是否是标准那张(kite 风筝图)。

这个例子在官方文档中是验证通过的,多数情况下是环境/复制/小参数差异导致。照 Wiki 重新编译一次大概率就能看到 detect num: 4 和框。

有进展或更多 log 随时贴,我继续帮你看!