【漂移菌】犀牛派 A1 NPU 推理项目搭建记录

骑驴玩儿漂移 2026-09-17 16:29:27

设备:犀牛派 A1(AidLux)
SoC:Qualcomm QCS6490
NPU/AI 加速:Qualcomm Hexagon DSP(通过 QNN236 后端调用)
目标:让 YOLOv26 模型走 NPU 而非 CPU 推理,并通过浏览器查看最高帧率的实时视频流。

作者: 漂移菌

1. 硬件与运行时调研

  • 硬件:犀牛派A1

img

摄像头: 叙利亚战损版USB摄像头,UVC协议

img

1.1 系统识别

$ uname -a
Linux aidlux 5.15.x ... aarch64 GNU/Linux

$ cat /proc/cpuinfo | grep "model name" | head
Qualcomm Technologies, Inc QCS6490

结论:该设备不是 Rockchip,无法使用 RKNN。应使用高通自己的 AI SDK:SNPE / QNN。AidLux 系统已预装封装库 AidLite。

1.2 AidLite 可用后端

import aidlite
print(aidlite.FrameworkType.__members__)
# TYPE_ONNX, TYPE_QNN, TYPE_QNN216, TYPE_QNN223, TYPE_QNN229, TYPE_QNN231, TYPE_QNN236,
# TYPE_SNPE, TYPE_SNPE2, TYPE_SNPE216, TYPE_SNPE223, TYPE_SNPE229, ...

print(aidlite.AccelerateType.__members__)
# TYPE_CPU, TYPE_GPU, TYPE_DSP, TYPE_NPU

AidLite 版本信息(本机实测):

Aidlite library version      : Aidlux_Aidlite_C4L_V2.2.8.206_160a6dd_20250820
Aidlite python library version : Aidlux_Aidlite_P4L_V2.2.8.206_160a6dd_20250820

⚠️ 关键坑点:QNN236 的 .ctx.bin 模型**只能使用 TYPE_DSP**。如果设置 TYPE_NPU,初始化会报错:

QNN's .bin model can only use DSP

因此本项目中 QNN236 后端统一指定 AccelerateType.TYPE_DSP。


2. 当前模型状态

模型文件路径格式能否在本机 NPU 跑备注
yolo26n.onnxaidcode/models/yolo26n.onnxONNX❌ 只能 CPUAidLite ONNX 后端仅支持 CPU,实测约 109 ms/帧
yolo26n_for_qnn.onnxaidcode/models/yolo26n_for_qnn.onnxONNX❌ 只能 CPU已剥离 NMS,输出 [1, 8400, 84],为 PC 端 QNN 转换准备
yolo26n.qnn236.ctx.bin尚未生成QNN236 ctx.bin✅ 可以 DSP 加速需要在 PC 端用 QNN SDK 转换后再拷贝到设备
yolo26n.ptaidcode/models/yolo26n.ptPyTorch❌ 不能直接推理训练/导出源文件
系统示例模型/usr/local/share/aidlite/examples/aidlite_qnn236/data/qnn_yolov5_multi/cutoff_yolov5s_640_sigmoid_w8a8.qnn236.ctx.binQNN236✅ 已验证用于验证 NPU 通路,约 13 ms/帧

3. 项目结构

在 /home/aidlux/aidcode/npu/ 下创建:

aidcode/
├── models/
│   ├── yolo26n.onnx              # 原始模型,带内嵌 NMS,输出 [1,300,6]
│   ├── yolo26n_for_qnn.onnx      # 已剥离 NMS,输出 [1,8400,84]
│   ├── yolo26n_simplified.onnx   # onnxsim 简化后的原始模型
│   └── yolo26n.qnn236.ctx.bin    # 需用户后续在 PC 端转换后放入
├── npu/
│   ├── yolo26_npu.py             # 主程序:NPU/CPU 自动切换 + 浏览器 MJPEG 流
│   ├── bench_qnn_demo.py         # 使用系统示例模型验证 QNN236+DSP 通路
│   ├── prepare_for_qnn.py        # 在设备端剥离 NMS,生成 yolo26n_for_qnn.onnx
│   ├── requirements.txt          # 依赖说明
│   └── NPU_SETUP_LOG.md          # 本文件
└── outputs/
    └── npu/
        └── yolo26_npu_preview.jpg

4. 代码实现要点

4.1 后端自动切换

yolo26_npu.py 启动时按以下顺序尝试:

  1. 若 models/yolo26n.qnn236.ctx.bin 存在,则加载 AidLite + QNN236 + TYPE_DSP。
  2. 若 QNN 模型不存在/失败,且 models/yolo26n_for_qnn.onnx 存在,则加载 AidLite ONNX CPU,后处理在 CPU 完成。
  3. 最后 fallback 到原始 models/yolo26n.onnx,使用 AidLite ONNX CPU。

4.2 输入输出配置

后端输入形状输出形状数据类型布局后处理
ONNX CPU(原始)[1, 3, 640, 640][1, 300, 6]float32NCHW简单阈值 + NMS
ONNX CPU(for_qnn)[1, 3, 640, 640][1, 8400, 84]float32NCHWTopK 解码 + NMS
QNN236 DSP[1, 640, 640, 3][1, 8400, 84]float32NHWCTopK 解码 + NMS

注:YOLOv26 原始 ONNX 输出是 [1, 300, 6](已内嵌 NMS)。直接转 QNN 时,NMS / TopK 等算子大概率不被支持,因此本项目已把 NMS 剥离,让 NPU 只跑 backbone + head 的卷积部分,后处理在 CPU 完成。

4.3 多线程流水线

为了最大化帧率,程序拆成 3 个线程:

  1. 采集线程:不断从摄像头读帧,使用 queue.Queue(maxsize=2),丢弃旧帧,避免推理堆积。
  2. 推理线程:从队列取最新帧,预处理 → AidLite 推理 → 后处理 → 绘制 → 更新 latest_frame。
  3. HTTP 服务线程:通过 multipart/x-mixed-replace 持续推送 latest_frame。

4.4 HTTP 流地址

  • 主页:http://<犀牛派IP>:9002/
  • 视频流:http://<犀牛派IP>:9002/stream
  • 状态接口:http://<犀牛派IP>:9002/status(返回 FPS、推理耗时、检测数量、后端类型)

注意:浏览器前端使用 <img src="/stream">,不要用带时间戳的 /frame?t=...,否则路径匹配可能 404。


5. 设备端模型准备工作(已完成)

5.1 为什么需要剥离 NMS

原始 yolo26n.onnx 内部后处理节点包含:

TopK / GatherElements / Flatten / Mod / Div / Gather / Tile / Cast / Concat

这些算子在 QNN 后端支持有限,直接转换大概率失败。因此我们在设备端用 onnx + onnxsim 把模型截断到 NMS 之前,输出原始检测候选 [1, 8400, 84]。

5.2 执行剥离

cd /home/aidlux/aidcode/npu
python3 prepare_for_qnn.py

生成的文件:

models/yolo26n_for_qnn.onnx   # 输出 [1, 8400, 84]
models/yolo26n_simplified.onnx

5.3 数值等价性验证

使用 ONNX Runtime 对比:

  • 原始 yolo26n.onnx 输出 [1, 300, 6]
  • yolo26n_for_qnn.onnx 输出 [1, 8400, 84],再按原模型内嵌逻辑做 TopK 后处理

结果:

 nonempty 行数一致
 boxes 最大差异: 0.0
 conf 最大差异: 0.0
 cls 匹配率: 100%

证明剥离后的模型与原模型完全等价。


  1. 实测数据

6.1 示例 YOLOv5 QNN236 DSP 模型测速

运行 npu/bench_qnn_demo.py:

Aidlite library version      : Aidlux_Aidlite_C4L_V2.2.8.206_160a6dd_20250820
Aidlite python version       : Aidlux_Aidlite_P4L_V2.2.8.206_160a6dd_20250820
✅ QNN236 DSP 模型加载成功

✅ QNN236 DSP 测速完成 (repeats=50)
   平均: 14.02 ms | P50: 13.38 ms | P90: 14.22 ms | 等效 FPS: 71.3

结论:NPU/DSP 通路可用,速度约为 CPU ONNX 的 8 倍以上。

6.2 YOLOv26 ONNX CPU fallback 测速

运行 npu/yolo26_npu.py(无 QNN 模型时):

平均推理: ~118 ms/帧 | FPS: ~8.5

6.3 HTTP 流验证

接口状态码结果
/200正常
/status200JSON 正常
/stream200MJPEG 流正常

7. PC 端模型转换步骤(必须在本机外完成)

当前设备上没有 QNN 模型转换工具,需要在一台 x86_64 Linux 开发机上安装 Qualcomm QNN SDK。

7.1 安装 QNN SDK

  1. 访问 Qualcomm AI Engine Direct SDK 下载对应版本(建议 QNN 2.x,与设备 AidLite QNN236 兼容)。
  2. 解压并设置环境:
export QNN_SDK_ROOT=/opt/qcom/aistack/qnn2.x.x
export PATH=$QNN_SDK_ROOT/bin/x86_64-linux-clang:$PATH
export LD_LIBRARY_PATH=$QNN_SDK_ROOT/lib/x86_64-linux-clang:$LD_LIBRARY_PATH

7.2 从设备拷贝已剥离 NMS 的 ONNX

adb pull /home/aidlux/aidcode/models/yolo26n_for_qnn.onnx ./

7.3 ONNX → QNN context binary 转换

# 1. ONNX 转 QNN 中间模型(生成 .cpp + .bin)
qnn-onnx-converter \
  --input_network yolo26n_for_qnn.onnx \
  --input_dim images 1,3,640,640 \
  --output_path yolo26n \
  --model_name yolo26n

# 2. 编译成 aarch64 设备端 .so
qnn-model-lib-generator \
  -c yolo26n.cpp \
  -b yolo26n.bin \
  -o yolo26n.so \
  -t aarch64-android-clang

# 3. 生成 context binary(.ctx.bin),后端使用 HTP/DSP
qnn-context-binary-generator \
  --model_path ./yolo26n.so \
  --backend ${QNN_SDK_ROOT}/lib/aarch64-android/libQnnHtp.so \
  --binary_file yolo26n.qnn236 \
  --output_dir ./out

# 4. 拷贝回犀牛派
adb push ./out/yolo26n.qnn236.ctx.bin /home/aidlux/aidcode/models/

⚠️ 不同 QNN 版本的命令、后端库名可能略有差异。常见后端库名还有 libQnnDsp.so、libQnnHtp.so。如果 libQnnHtp.so 失败,换成 libQnnDsp.so 再试。

7.4 验证转换结果

在 PC 端可用 qnn-net-run 跑一张预处理后的图片,确认输出形状为 [1, 8400, 84]:

qnn-net-run \
  --model yolo26n.so \
  --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so \
  --input_list raw_list.txt \
  --output_dir ./output

8. 运行方式

8.1 验证 NPU 通路

cd /home/aidlux/aidcode/npu
python3 bench_qnn_demo.py

img

8.2 运行实时检测流

cd /home/aidlux/aidcode/npu
python3 yolo26_npu.py

img

然后在同一网络下的浏览器打开:http://<犀牛派IP>:9002

img

img

8.3 停止

在终端按 Ctrl+C。


9. 常见问题与注意事项

问题原因解决方案
QNN 初始化报错 QNN's .bin model can only use DSP设置了 TYPE_NPU 而非 TYPE_DSP代码中已固定 AccelerateType.TYPE_DSP
浏览器看不到视频路径写成了 /frame?t=... 或被防火墙拦截使用 /stream,确认端口 9002 可访问
帧率无法提高单线程串行,推理阻塞采集已使用采集/推理/推流三线程解耦
检测框位置偏移预处理与模型训练时不一致使用 letterbox + 114 灰边,与 Ultralytics 导出一致
QNN 模型加载失败模型尚未转换或输出 shape 不匹配在 PC 端用 QNN SDK 转换后放入 models/
AidLite 找不到Python 环境不对AidLite 安装在系统 Python3.10,不要激活其他 venv
yolo26n.onnx 直接转 QNN 报错内嵌 NMS / TopK 算子不被 QNN 支持使用已剥离 NMS 的 yolo26n_for_qnn.onnx

10. 后续优化方向

  1. 完成 YOLOv26 QNN 转换:这是提升帧率的关键,转换后即可从 ~8.5 FPS 提升到 ~70+ FPS。
  2. 多 batch / 异步推理:当前每帧同步 invoke,可尝试双缓冲进一步压榨 DSP。
  3. 更小的输入分辨率:如果业务允许 320×320,可将模型改为 320 输入,进一步提速。
  4. GStreamer / V4L2 零拷贝:OpenCV 默认 V4L2 拷贝开销较大,可改用 GStreamer 捕获。
  5. WebRTC:如果 MJPEG 延迟不满足要求,可替换为 WebRTC 推流。

11. 结论

  • 设备 NPU 对应 Hexagon DSP,通过 AidLite + QNN236 + TYPE_DSP 调用。
  • 系统示例模型已验证 NPU 通路可用,约 14 ms/帧,等效 71 FPS。
  • yolo26n.onnx 当前只能走 CPU,约 118 ms/帧。
  • 已创建 npu/ 项目,支持 自动 NPU/CPU 切换、浏览器 MJPEG 实时流、三线程流水线。
  • 已在设备端把 yolo26n.onnx 剥离 NMS,生成 yolo26n_for_qnn.onnx(输出 [1, 8400, 84]),并验证与原模型数值等价。
  • 待办:在 PC 端用 QNN SDK 把 yolo26n_for_qnn.onnx 转换为 yolo26n.qnn236.ctx.bin,拷贝到 aidcode/models/ 后即可自动启用 NPU 加速。
  • PC端已经下载好,但是官方文档的配置是通过X86架构的Linux下实现,目前因为我公司电脑是windows,家里电脑是MacOS,得弄个x86架构的linux主机才能实现这个操作。
  • 第一波测试算是结束了,慢慢摸到一些门道了,继续摸索,等玩儿明白了搞点儿项目出来。
...全文
173 回复 打赏 收藏 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
内容概要:本文研究了基于转子磁场定向的飞轮储能系统在机侧与网侧的协调控制策略,重点实现了机侧PQ控制与网侧恒压双闭环控制的Simulink仿真实现。通过转子磁场定向技术,对飞轮储能系统的有功与无功功率进行精确解耦控制,有效提升了系统在并网运行时的稳定性与动态响应性能。网侧采用恒压双闭环控制策略,确保直流母线电压稳定,实现能量的高效双向流动。文中详细阐述了控制策略的设计原理、数学建模过程及仿真模型的构建方法,并通过仿真验证了该协调策略在功率平滑、电压支撑、动态调节及系统稳定性方面的有效性。; 适合人群:具备电力电子、电力系统或自动控制基础知识,从事新能源储能系统、飞轮储能技术、电力系统仿真等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 掌握飞轮储能系统在并网工况下的机侧PQ解耦控制原理;② 学习基于转子磁场定向的矢量控制方法在储能系统中的应用;③ 实现并优化机侧与网侧双闭环协调控制策略,提升系统动态性能与稳定性;④ 为后续开展混合储能系统、微电网能量管理及高比例可再生能源接入系统的控制研究提供技术基础与仿真参考。; 阅读建议:建议结合Simulink仿真模型逐步理解控制结构设计,重点关注坐标变换、PI控制器参数整定、双闭环耦合关系及仿真结果分析,可尝试修改控制参数或工况设置以深入掌握系统响应特性。

7,855

社区成员

发帖
与我相关
我的任务
社区描述
本论坛以AI、IoT、PC 、XR、Auto等核心板块组成,为开发者提供便捷及高效的学习和交流平台。 高通开发者专区主页:https://qualcomm.csdn.net/
物联网人工智能开源 企业社区 北京·东城区
社区管理员
  • csdnsqst0050
  • chipseeker
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧