【Linux】RK3568-OpenCV+YOLO(八)

### 文章目录

  • [@TOC](#文章目录 @[TOC] 1. 版本 2. 纯终端 vs 远程开发 3. CPU+YOLO 4. 开发板环境准备 5.虚拟机操作 6.NPU+YOLO 环境准备)
  • [1. 版本](#文章目录 @[TOC] 1. 版本 2. 纯终端 vs 远程开发 3. CPU+YOLO 4. 开发板环境准备 5.虚拟机操作 6.NPU+YOLO 环境准备)
  • [2. 纯终端 vs 远程开发](#文章目录 @[TOC] 1. 版本 2. 纯终端 vs 远程开发 3. CPU+YOLO 4. 开发板环境准备 5.虚拟机操作 6.NPU+YOLO 环境准备)
  • [3. CPU+YOLO](#文章目录 @[TOC] 1. 版本 2. 纯终端 vs 远程开发 3. CPU+YOLO 4. 开发板环境准备 5.虚拟机操作 6.NPU+YOLO 环境准备)
  • [4. 开发板环境准备](#文章目录 @[TOC] 1. 版本 2. 纯终端 vs 远程开发 3. CPU+YOLO 4. 开发板环境准备 5.虚拟机操作 6.NPU+YOLO 环境准备)
  • [5.虚拟机操作](#文章目录 @[TOC] 1. 版本 2. 纯终端 vs 远程开发 3. CPU+YOLO 4. 开发板环境准备 5.虚拟机操作 6.NPU+YOLO 环境准备)
  • [6.NPU+YOLO 环境准备](#文章目录 @[TOC] 1. 版本 2. 纯终端 vs 远程开发 3. CPU+YOLO 4. 开发板环境准备 5.虚拟机操作 6.NPU+YOLO 环境准备)

1. 版本

一、硬件平台

项目 内容
开发板 100ASK DShanPI R1(RK3568)
CPU 四核 Cortex-A55 @ 2.0GHz
NPU 1 TOPS INT8
内存 2GB LPDDR4
存储 15GB eMMC
对比型号 RK3576(6 TOPS,性价比)、RK3588(6 TOPS,旗舰)

二、系统与内核

项目 版本/选择 说明
发行版 Armbian 25.11 Minimal(无桌面版) 内存占用约115MB,远低于带桌面版(300MB+)
底层 Debian trixie 稳定、软件包丰富
内核 6.1.115-vendor-rk35xx Rockchip厂商内核,含NPU驱动
NPU驱动 rknpu 0.9.8 需加载设备树overlay启用
桌面环境 不安装 通过SSH + 推流开发,释放内存给模型

三、软件环境版本全览

  1. 开发板端(Armbian)
软件 版本 用途/备注
系统Python 3.13.5 仅用于OpenCV/numpy脚本
虚拟环境Python 3.12.7 RKNN-Toolkit-Lite2所需,通过python-build-standalone安装
OpenCV(系统) 5.0.0.93 用于CPU版YOLO推理
OpenCV(venv) 4.10.0.84 兼容numpy 1.26.4,避免与RKNN冲突
numpy 1.26.4 RKNN-Toolkit-Lite2依赖
RKNN-Toolkit-Lite2 2.3.2 板端NPU推理库
librknnrt.so 2.0.0b0 NPU运行时库,需放入/usr/lib
  1. PC端(Ubuntu虚拟机)
软件 版本 用途/备注
Ubuntu 推荐22.04 LTS或24.04 LTS 20.04偏旧,但可用
Python 3.10(22.04)或3.12(24.04) 与RKNN-Toolkit2匹配
RKNN-Toolkit2 2.3.2 模型转换与量化
ONNX 1.18.0(<1.19.0) 避免YOLO26转换报错
ONNX opset 12 导出ONNX时指定
PyTorch 2.4.0+cpu 仅CPU版,190MB,满足RKNN依赖
YOLOv8n ONNX 来自官方或OpenCV镜像 12MB,用于CPU和NPU部署

四、版本兼容性核心规则

  1. RKNN-Toolkit2 与 Ubuntu/Python 对应关系
RKNN-Toolkit2 Ubuntu (x64) 推荐Python
v2.3.x 24.04 LTS 3.12
22.04 LTS 3.10 / 3.11
20.04 LTS 3.8 / 3.9
18.04 LTS 3.6 / 3.7
  1. YOLO版本与工具链
YOLO版本 推荐ONNX版本 RKNN-Toolkit2最低版本 特点
YOLOv8n <1.19.0(如1.18.0) ≥2.0.0 成熟,资料最多
YOLO26n <1.19.0 ≥2.3.0 无NMS,边缘优化
  1. 板端与PC端版本匹配
  • RKNN-Toolkit2(PC) 与 RKNN-Toolkit-Lite2(板) 大版本需一致(如均为2.3.2)
  • librknnrt.so 版本尽量与工具链匹配,避免推理报错

五、部署流程回顾与关键坑

阶段一:CPU推理(理解全流程)

  • 用 cv2.dnn.readNetFromONNX 加载YOLOv8n
  • 预处理:blobFromImage 除255、缩放640、BGR转RGB
  • 推理输出 (1,84,8400)
  • 后处理:置信度过滤、NMS、画框
  • 速度:1~3 FPS

阶段二:NPU部署(加速)

  • PC端:ONNX → RKNN(INT8量化,需校准集)
  • 板端:RKNNLite 加载 .rknn,调用NPU推理
  • 关键坑1 :RKNN内部已归一化,预处理不能除255(用1.0)
  • 关键坑2 :INT8量化需用场景匹配的校准集,否则类别分数全0
  • 关键坑3:FP16虽不量化但速度慢(RK3568对INT8优化更好)
  • 实测速度:FP16约380ms/帧,INT8(好校准集)可到150~200ms/帧

六、选型思考:RK3568 / RK3576 / RK3588

型号 NPU 多路视频能力 价格 适合场景
RK3568 1 TOPS 有限,适合2路以内 已有 学习、轻量控制
RK3576 6 TOPS 4路1080P@25fps ~899元 性价比之选,中高端AIoT
RK3588 6 TOPS 16路以上,带宽翻倍 ~1500元+ 多路高并发、旗舰视觉

决策逻辑:

  • 预算紧、学习为主 → 先用RK3568深入掌握部署全流程
  • 需4路以内AI检测、追求性价比 → RK3576
  • 多路高并发、一步到位 → RK3588

七、职业方向思考

  • 岗位统称:AI嵌入式开发工程师、端侧AI部署工程师、边缘AI工程师
  • 核心技能:模型量化、NPU部署、C++/Python、Linux驱动、性能优化
  • 嵌入式背景优势:懂硬件、系统、内存管理,能解决兼容性与性能瓶颈
  • 面试表述:突出"在资源受限平台上完成模型部署与优化"的实战经验
  • 学习建议:从Python入手,逐步深入C++推理、多核调度、跟踪算法

八、常用命令与资源

  • NPU检查 :ls /dev/rknpu*、dmesg | grep -i rknpu
  • 模型转换 :python3 convert.py yolov8n.onnx rk3568 i8
  • 板端推理 :使用 RKNNLite,注意输入不除255
  • 校准集生成 :ffmpeg -i video.mp4 -vf "fps=2" -frames:v 100 calib_%03d.jpg

版本兼容问题确实是部署中最容易让人头疼的一环,很多时间都花在了环境配置上。我帮你把 RKNN 工具链、Python、Ubuntu 以及 YOLO 模型之间的对应关系梳理了一下,希望能帮你理清头绪。

📊 核心兼容性速查表

下面这张表是官方推荐的版本对应关系,可以作为你搭建环境时的核心参考:

RKNN-Toolkit2 版本 Ubuntu 版本 (x64) 推荐 Python 版本
v2.3.x (最新) Ubuntu 24.04 LTS 3.12
Ubuntu 22.04 LTS 3.10 或 3.11
Ubuntu 20.04 LTS 3.8 或 3.9
Ubuntu 18.04 LTS 3.6 或 3.7

注意:对于开发板(ARM64),RKNN-Toolkit-Lite2 的 Python 版本要求与你的 Armbian 系统(Debian 12)匹配,通常也是 Python 3.10 - 3.12。

🎯 针对你的情况:如何选择?

结合你之前用 Ubuntu 20.04 + Python 3.8 遇到的情况,建议如下:

  • 首选方案(最稳妥) :使用 Ubuntu 22.04 LTS + Python 3.10。这是目前社区资料最丰富、最稳定的组合,也是瑞芯微官方 Demo 常用的环境,可以避开很多新版本的坑。
  • 次选方案(追求最新) :使用 Ubuntu 24.04 LTS + Python 3.12。这是官方目前推荐的最新组合,能获得最新的工具链支持。
  • 关于 Ubuntu 20.04 + Python 3.8 :这个组合仍然可用,但已经偏旧。如果你之前的环境能跑通,可以继续用;如果重新搭建,建议升级到 22.04。

🤖 YOLO 版本与工具链的兼容性

你提到的 YOLOv8n 和 YOLO26n,在部署时有不同的要求:

  • YOLOv8n :非常成熟。官方 rknn_model_zoo 有完整的示例,对 RKNN-Toolkit2 的版本要求比较宽松,v2.0.0 及以上的版本都可以。
  • YOLO26n :部署时需要注意 ONNX 版本 。有 PR 明确指出,ONNX 版本必须低于 1.19.0 ,否则会出现 AttributeError: module 'onnx' has no attribute 'mapping' 的错误。此外,需要 RKNN-Toolkit2 ≥ 2.3.0 以获得更好的支持。

🔗 关键依赖:ONNX 与 ONNX opset 版本

这是从 PyTorch 导出 ONNX 时最容易忽略的环节。

  • ONNX 版本 :建议在环境中明确安装 onnx<1.19.0(例如 1.18.0),以避免上述的兼容性错误。

  • ONNX opset :导出时建议指定 opset=11 或 opset=12。有些转换脚本为了兼容性,甚至会自动限制最高 opset 为 19 。你可以在导出命令中明确指定:

    bash 复制代码
    # 导出时指定 opset 版本
    yolo export model=yolov8n.pt format=onnx opset=12

⚙️ 环境搭建与版本管理建议

为了避免未来再次陷入"版本地狱",推荐使用 Miniforge (Conda) 来管理不同的项目环境。你可以为 YOLOv8 和 YOLO26 分别创建独立的虚拟环境,互不干扰。

例如,创建一个专门用于 YOLOv8 部署的环境:

bash 复制代码
# 创建一个名为 yolo8_deploy 的环境,指定 Python 3.10
conda create -n yolo8_deploy python=3.10 -y

# 激活环境
conda activate yolo8_deploy

# 在此环境中安装指定版本的 ONNX 和 RKNN-Toolkit2
pip install onnx==1.18.0
pip install rknn_toolkit2==2.3.2

🔧 常见问题排查

  • RKNN-Toolkit2 安装失败 :首先检查 Python 版本是否与 Ubuntu 版本匹配(如上表所示)。其次,确保是在正确的虚拟环境中执行安装命令。
  • 模型转换时报错 :如果遇到与 onnx 相关的 AttributeError,优先检查 ONNX 版本是否过高 ,尝试降级到 1.18.0 或更低版本。
  • 开发板端推理报错 :确保开发板上的 librknnrt.so 版本与 PC 端 RKNN-Toolkit2 的版本保持一致或兼容。版本不匹配是导致推理失败的一个常见原因。

2. 纯终端 vs 远程开发

对比项 MobaXterm(纯 SSH 终端) Trae / VS Code Remote-SSH
架构 本地只负责显示字符、发送按键 本地是前端界面,开发板运行后端服务
开发板进程 仅 sshd + 你执行的命令 sshd + Trae/VS Code Server + 语言服务器 + 插件
内存占用 几 MB ~ 十几 MB 100MB ~ 500MB+(大型项目可超 1GB)
CPU 占用 极低(仅传输文本) 中高(文件索引、语法分析、AI 请求)
典型功能 命令行操作、文件传输 智能补全、跳转定义、调试、AI 辅助
适用场景 编译、运行、监控、系统操作 写代码、重构、复杂项目开发

结论:MobaXterm 是"远程打字机",Remote-SSH 是"远程电脑"。打字机不耗电,远程电脑要耗电。


二、Remote-SSH 资源消耗详解

Remote-SSH 会在开发板上安装一个服务端,主要消耗来自:

  • Trae/VS Code Server 基础进程:100~150MB
  • 语言服务器(如 Pylance、clangd):200~400MB
  • 扩展插件(Git、Linter、AI 助手):100~200MB
  • 项目索引:100~300MB(视项目大小)

对于 2GB 内存的 RK3568,长时间运行 Remote 会严重挤占 YOLO 等 AI 任务的资源,甚至导致 OOM。


三、Remote-SSH 优化配置(没成功)

  1. 强制插件在本地运行(最关键)
    在Trae的远程窗口中,按 Ctrl+Shift+P,输入 Preferences: Open Remote Settings (JSON) 并回车
    在远程窗口 的 settings.json 中添加:
json 复制代码
{
  "extensions.experimental.affinity": {
    "*": 0
  }
}
  • "*": 0 表示所有插件仅在本地电脑运行,不占用开发板资源。
  • 0=仅本地,1=仅远程,2=自动(默认,最耗资源)。
  1. 排除文件监听,防止内存暴涨

同样在远程 settings.json 中添加:

json 复制代码
{
  "files.watcherExclude": {
    "**/node_modules/**": true,
    "**/dist/**": true,
    "**/build/**": true,
    "**/.git/**": true
  }
}

四、更轻量的替代方案(工业级推荐)

如果优化后 2GB 开发板依然吃力,可切换以下方案,资源占用极低:

方案 原理 开发板占用 适用场景
sshfs + 本地编辑器 将开发板目录挂载到本地,本地编辑,编译运行仍在开发板 极低(仅文件系统) 喜欢本地 IDE 编辑,接受命令行编译
rsync + gdbserver 本地交叉编译,rsync 同步二进制,gdbserver 远程调试 极低(gdbserver 仅 5-15MB) 嵌入式行业标准工作流
rtty 超轻量 Web 终端,客户端仅 692KB 极低 远程终端维护、简单编辑

推荐 :rsync + gdbserver 是嵌入式开发的最佳实践,构建与目标硬件分离,极致节省资源。


五、针对 RK3568(2GB)的实用建议

  1. 分时复用工具 :
    • 写代码/看代码 → 用 Trae Remote(优化后)
    • 编译/跑 YOLO/监控资源 → 用 MobaXterm(纯终端)
  2. 用完即断:不需要 Remote 时,立即断开连接,释放开发板内存。
  3. 监控资源 :在 MobaXterm 中 htop 或 free -h,观察 Trae Server 实际占用。
  4. 只装必要扩展:远程端仅保留 Python / C++ 核心支持,禁用主题、GitLens、AI 助手等。
  5. 终极方案:若长期受内存困扰,考虑升级到 4GB/8GB 开发板(如 RK3576/RK3588)。

  • 核心区别:远程开发 vs. 本地挂载

    远程开发 (Remote Development):在开发板上安装一个完整的服务端(VS Code Server),所有代码分析、补全、索引都在板子上运行。功能强大,但资源占用极高。

  • 本地挂载 (Local Mount):通过 SFTP 等协议将开发板的目录"挂载"为本地文件夹。代码编辑、AI 补全等都在你的电脑上运行,开发板几乎不消耗资源。

  • 插件对比

  • Open Remote - SSH (jeanp413)

原理:远程开发。微软官方 Remote-SSH 的开源替代品,功能几乎一致,专为 VSCodium 等非官方 VSCode 设计。

开发板占用:极高,和官方 Remote-SSH 一样,需要安装完整服务端。

  • Remote SSH (Microsoft)

原理:远程开发。微软官方插件,功能最全,体验最好。

开发板占用:极高。这是资源消耗的"元凶",2GB 内存的板子会非常吃力。

  • SSH FS (Kelvin)

原理:本地挂载。通过 FUSE 技术,将远程目录挂载为本地工作区,编辑体验接近本地。

开发板占用:几乎为零。它不需要在板子上安装任何服务,资源占用极低。


SSH FS 是目前最符合你要求的扩展,它将"本地挂载"和"远程终端"两大功能整合在了一起。

文件挂载与实时同步:它通过 SFTP 协议将开发板的目录直接挂载为 VS Code 的本地工作区文件夹。你在编辑器中的任何保存操作都会实时同步到开发板,无需手动上传下载。

集成远程终端:扩展内置了远程终端功能。你可以通过侧边栏按钮或命令面板,一键在开发板的指定目录中打开一个终端,直接运行 gcc、make 等命令。

极低资源占用:它的工作原理是纯客户端的,不会在开发板上安装任何后台服务,因此对开发板的内存和 CPU 消耗几乎为零。

其他实用功能:支持配置编辑、连接复用、SSH 跳板等,使用体验很流畅。

安装与关键配置:在 VS Code 扩展商店搜索 SSH FS (作者 Kelvin Schoofs) 安装即可。为了确保文件保存后直接写入远程,建议在 VS Code 设置中将 sshfs.saveMode 改为 direct


3. CPU+YOLO

一、环境准备

  1. 开发板系统信息
  • 发行版:Armbian 25.11 Minimal(无桌面)
  • 内核:6.1.115-vendor-rk35xx
  • Python:系统自带 3.13
  • 内存:2GB
  1. 安装依赖(系统 Python 3.13)
bash 复制代码
# 安装 pip(若未安装)
sudo apt update
sudo apt install -y python3-pip

# 安装 numpy 2.x(Python 3.13 不支持 numpy 1.26.4,会编译失败)
pip3 install "numpy<2.3" --break-system-packages

# 安装 OpenCV headless(无 GUI,省内存)
pip3 install opencv-python-headless==4.10.0.84 --break-system-packages

# 验证
python3 -c "import cv2, numpy; print('OpenCV:', cv2.__version__, 'NumPy:', numpy.__version__)"

预期输出:

复制代码
OpenCV: 4.10.0 NumPy: 2.2.6

⚠️ 踩坑记录:

  • 直接装 numpy==1.26.4 会失败,因为 Python 3.13 没有对应的预编译 whl,pip 会尝试源码编译,缺 Python.h 报错。
  • 系统 Python 3.13 用 numpy 2.x 完全够用;后续 NPU 推理会在独立的 Python 3.12 venv 中安装 numpy 1.26.4,互不影响。

二、下载 YOLOv8n ONNX 模型

bash 复制代码
cd ~/yolo
wget --user-agent="Mozilla/5.0" -O yolov8n.onnx https://dl.opencv.org/models/yolov8/yolov8n.onnx
ls -lh yolov8n.onnx   # 应约 12~13MB

注意:OpenCV 镜像可能返回 403,但文件有时已缓存成功。若失败,可从其他源下载(如 GitHub Release 或从 PC 传输)。


三、CPU 推理代码(带详细注释)

创建 cpu_infer.py:

python 复制代码
import cv2                      # 导入 OpenCV 库,用于图像处理和深度学习模型推理
import numpy as np              # 导入 NumPy 库,用于数组运算和数值计算
import time                     # 导入时间模块,用于测量推理耗时

# 1. 加载模型
print("加载 ONNX 模型...")       # 打印提示信息,告诉用户正在加载模型
net = cv2.dnn.readNetFromONNX('yolov8n.onnx')  # 读取 ONNX 格式的 YOLOv8n 模型,返回一个网络对象
print("模型加载成功")            # 打印成功信息

# 2. 读取图片
img = cv2.imread('testd.jpg')   # 读取当前目录下的 testd.jpg 图片,返回 NumPy 数组
if img is None:                 # 判断图片是否读取成功(失败返回 None)
    print("❌ 找不到 testd.jpg")  # 如果失败,打印错误信息
    exit(1)                     # 退出程序,返回码 1 表示异常退出
h, w = img.shape[:2]            # 获取图片的高度和宽度(shape 返回 (高, 宽, 通道))
print(f"图片尺寸: {w}x{h}")      # 打印图片的宽和高

# 3. 预处理(CPU 版要除 255)
# 使用 blobFromImage 对图像进行预处理:缩放、归一化、BGR 转 RGB、调整维度
# 参数:图像, 缩放因子 1/255.0(将像素值从 0~255 归一化到 0~1), 目标尺寸 (640,640),
#       均值 (0,0,0) 不做减均值, swapRB=True 将 BGR 转为 RGB, crop=False 不裁剪
blob = cv2.dnn.blobFromImage(img, 1/255.0, (640, 640), (0,0,0), swapRB=True, crop=False)
net.setInput(blob)              # 将预处理后的图像输入到神经网络

# 4. 推理
start = time.time()             # 记录推理开始时间
outputs = net.forward()         # 执行前向传播,得到模型输出
print(f"推理耗时: {(time.time()-start)*1000:.1f} ms")  # 计算并打印推理耗时(毫秒)

# 5. 后处理
outputs = outputs[0].T          # 输出形状为 (1,84,8400),取第一个元素并转置得到 (8400,84),每行一个预测框
# 定义 COCO 数据集的 80 个类别名称,模型输出的类别索引对应这些名称
class_names = ['person','bicycle','car','motorcycle','airplane','bus','train','truck','boat','traffic light','fire hydrant','stop sign','parking meter','bench','bird','cat','dog','horse','sheep','cow','elephant','bear','zebra','giraffe','backpack','umbrella','handbag','tie','suitcase','frisbee','skis','snowboard','sports ball','kite','baseball bat','baseball glove','skateboard','surfboard','tennis racket','bottle','wine glass','cup','fork','knife','spoon','bowl','banana','apple','sandwich','orange','broccoli','carrot','hot dog','pizza','donut','cake','chair','couch','potted plant','bed','dining table','toilet','tv','laptop','mouse','remote','keyboard','cell phone','microwave','oven','toaster','sink','refrigerator','book','clock','vase','scissors','teddy bear','hair drier','toothbrush']

boxes, confs, ids = [], [], []   # 初始化三个空列表,分别存放边界框坐标、置信度和类别索引
for row in outputs:              # 遍历每一个预测框(共 8400 个)
    scores = row[4:]             # 取第 4 个元素之后的所有值,即 80 个类别的概率
    cid = int(np.argmax(scores)) # 找到概率最大的类别索引
    conf = float(scores[cid])    # 取该最大概率值作为置信度
    if conf > 0.25:              # 如果置信度大于 0.25,则认为检测有效
        xc, yc, bw, bh = row[0], row[1], row[2], row[3]  # 提取中心坐标 x,y 和宽高 w,h
        xc, yc = xc/640*w, yc/640*h   # 将中心坐标从 640x640 缩放回原图尺寸
        bw, bh = bw/640*w, bh/640*h   # 将宽高从 640x640 缩放回原图尺寸
        # 计算左上角和右下角坐标,并转为整数
        boxes.append([int(xc-bw/2), int(yc-bh/2), int(xc+bw/2), int(yc+bh/2)])
        confs.append(conf)       # 保存置信度
        ids.append(cid)          # 保存类别索引

# 使用非极大值抑制(NMS)去除重叠的检测框
# 参数:所有框, 置信度, 置信度阈值 0.25, NMS 阈值 0.4
indices = cv2.dnn.NMSBoxes(boxes, confs, 0.25, 0.4)
print(f"检测到 {len(indices)} 个目标")  # 打印最终检测到的目标数量

# 6. 画框
if len(indices) > 0:             # 如果检测到了目标
    for i in np.array(indices).flatten():  # 将 indices 转为扁平数组并遍历每个保留框的索引
        x1, y1, x2, y2 = boxes[i]  # 获取对应框的左上角和右下角坐标
        cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)  # 在原图上画绿色矩形框,线宽 2
        # 在框的左上角上方写类别名称和置信度,颜色绿色,字体大小 0.6,线宽 2
        cv2.putText(img, f'{class_names[ids[i]]} {confs[i]:.2f}', (x1, y1-5),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

cv2.imwrite('cpu_result.jpg', img)  # 将画好框的图像保存为 cpu_result.jpg
print("已保存 cpu_result.jpg")       # 打印保存成功信息

四、运行与结果

bash 复制代码
cd ~/yolo
python3 cpu_infer.py

实测输出:

复制代码
加载 ONNX 模型...
模型加载成功
图片尺寸: 1024x768
推理耗时: 1740.4 ms
检测到 6 个目标
已保存 cpu_result.jpg

结果图片 :cpu_result.jpg 中6头牛全部被绿色框标出,置信度 0.89~0.93,类别 cow。


五、关键知识点与对比

项目 CPU 版(ONNX + OpenCV DNN) NPU 版(RKNN)
模型格式 .onnx .rknn(INT8量化)
预处理归一化 必须除以 255 (代码中 1/255.0) 不能除以 255(RKNN 内部已处理)
推理速度 约 300~500 ms/帧(2~3 FPS) 目标 50~150 ms/帧(10~20 FPS)
内存占用 中等(模型+OpenCV) 低(量化后模型更小)
适用 Python 系统 Python 3.13 独立 Python 3.12 venv
校准集 不需要 需要(建议用场景匹配的牛图)

⚠️ 最易踩坑 :从 CPU 迁移到 NPU 时,预处理必须把 1/255.0 改成 1.0,否则输入被双重归一化,检测结果全为 0。


4. 开发板环境准备

步骤 1:确认切换到 NPU 的目标

背景 :CPU 视频推理实测 1400 ms/帧,295 帧需要约 7 分钟,太慢。

决定:把 YOLOv8n 从 ONNX 转成 RKNN 格式,用 RK3568 的 NPU 推理。

涉及概念:

  • ONNX:CPU 能跑的通用模型格式,不能调用 NPU
  • RKNN:瑞芯微专用模型格式,能调用 NPU
  • RKNN-Toolkit2:把 ONNX 转 RKNN 的工具,只能在 x86_64 上跑
  • RKNN-Toolkit-Lite2 :在开发板上加载 .rknn 推理的库

步骤 2:检查开发板 NPU 驱动状态

在开发板上执行:

bash 复制代码
# 检查内核中是否包含 rknpu 驱动
grep rknpu /usr/lib/modules/$(uname -r)/modules.builtin

输出:

复制代码
kernel/drivers/rknpu/rknpu.ko

解释:内核已编译 rknpu 驱动模块。


bash 复制代码
# 检查设备树中 NPU 节点状态
cat /sys/firmware/devicetree/base/npu@fde40000/status

输出:

复制代码
okay

解释:设备树中 NPU 节点是使能状态。


bash 复制代码
# 检查 NPU 初始化日志
dmesg | grep -i rknpu

输出(关键错误):

复制代码
RKNPU fde40000.npu: can't request region for resource [mem 0xfde40000-0xfde4ffff]
RKNPU fde40000.npu: error -ENXIO: IRQ npu_irq not found

解释:驱动无法申请内存区域、找不到中断号。


bash 复制代码
# 检查 NPU 设备节点
ls -l /dev/rknpu*

输出:

复制代码
ls: cannot access '/dev/rknpu*': No such file or directory

解释 :设备节点未创建,NPU 实际不可用。需要在开发板上加载设备树 overlay(未解决)。


c 复制代码
* 查看 DRM 渲染节点
ls -l /dev/dri/
输出
crw-rw---- 1 root video  226,   0  card0
crw-rw---- 1 root render 226, 128  renderD128   ← 显示控制器
crw-rw---- 1 root render 226, 129  renderD129   ← NPU
crw-rw---- 1 root render 226, 130  renderD130   ← GPU

dmesg | grep -i rknpu | head -10
输出
OF: reserved mem: initialized node rknpu
RKNPU fde40000.npu: RKNPU: rknpu iommu is disabled, using non-iommu mode   ← 核心!
RKNPU fde40000.npu: assigned reserved memory node rknpu
RKNPU fde40000.npu: RKNPU: initialize reserved memory for rknpu device!
[drm] Initialized rknpu 0.9.8 20240828 for fde40000.npu on minor 1

5.虚拟机操作

环境:Ubuntu 24.04 LTS / Python 3.12

目标:把 yolov8n.onnx 转换成 RK3568 NPU 可用的 yolov8n.rknn


步骤 1:确认系统环境

命令:

bash 复制代码
# 查看系统版本
lsb_release -a

# 查看 Python 版本
python3 --version

# 查看 pip 是否可用
pip3 --version

输出:

  • Ubuntu 24.04.5 LTS(Noble)
  • Python 3.12.3
  • pip3 未安装

说明:

  • Ubuntu 24.04 默认 Python 3.12,符合 RKNN-Toolkit2 官方推荐
  • pip 需要后续手动安装

步骤 2:安装系统基础工具

命令:

bash 复制代码
# 更新软件包索引(拉取最新包列表)
sudo apt update

# 安装编译工具 + Python 开发环境
sudo apt install -y build-essential git wget curl python3-pip python3-venv python3-dev

工具作用:

工具 作用
build-essential gcc、g++、make,编译 C/C++ 程序
git 克隆仓库(如 rknn-toolkit2)
wget / curl 下载文件
python3-pip Python 包管理器
python3-venv 创建虚拟环境
python3-dev Python 头文件(编译扩展用)

输出:新安装 59 个包,共 72.3 MB。


步骤 3:创建 Python 虚拟环境

命令:

bash 复制代码
# 用系统 Python 3.12 创建虚拟环境(放在 home 目录下)
python3 -m venv ~/rknn_env

# 激活虚拟环境
source ~/rknn_env/bin/activate

# 确认 python 指向虚拟环境
which python
# 输出:/home/user/rknn_env/bin/python

# 确认 Python 版本
python --version
# 输出:Python 3.12.3

说明:

  • 虚拟环境隔离系统 Python,避免污染
  • 后续所有 pip install 都装在这个环境里

涉及文件:

  • ~/rknn_env/:Python 3.12 虚拟环境目录
  • ~/rknn_env/bin/python:虚拟环境的解释器

步骤 4:配置 pip 源(踩坑)

第一次尝试清华源:

bash 复制代码
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

测试失败:

bash 复制代码
pip install numpy==1.26.4
# 输出:Failed to establish a new connection: [Errno 101] 网络不可达

诊断网络:

bash 复制代码
# ping 通
ping -c 3 mirrors.tuna.tsinghua.edu.cn

# 但 HTTPS 443 端口被封
curl -v https://pypi.tuna.tsinghua.edu.cn/simple/
# 输出:connect to 101.6.15.130 port 443 failed: 连接被拒绝

# 官方 PyPI 能通
curl -v https://pypi.org/simple/
# 输出:Connected to pypi.org port 443

切换到官方源:

bash 复制代码
pip config set global.index-url https://pypi.org/simple/

说明:

  • 清华源 443 端口被封(虚拟机网络环境限制)
  • 官方源速度慢(100 kB/s)但能通

涉及文件:

  • ~/.config/pip/pip.conf:pip 配置文件

步骤 5:安装 RKNN-Toolkit2 依赖

命令:

bash 复制代码
pip install numpy==1.26.4 onnx==1.18.0 onnxruntime==1.19.2 protobuf==4.25.4 \
  psutil ruamel.yaml scipy tqdm opencv-python-headless==4.10.0.84 fast-histogram

每个包的作用:

包 版本 作用
numpy 1.26.4 RKNN-Toolkit2 严格要求(2.x 会报错)
onnx 1.18.0 读取 ONNX 模型,必须 <1.19.0
onnxruntime 1.19.2 ONNX 推理后端
protobuf 4.25.4 ONNX 依赖的序列化库
psutil 最新 系统监控(RKNN 内部使用)
ruamel.yaml 最新 解析 YAML 配置
scipy 1.17.1 科学计算(量化时用)
tqdm 最新 进度条
opencv-python-headless 4.10.0.84 图像处理(headless 版无 GUI,省资源)
fast-histogram 最新 快速直方图统计(量化用)

输出:约 10 分钟下载完(速度 100 kB/s)。


步骤 6:下载 PyTorch CPU 版

为什么需要 PyTorch :RKNN-Toolkit2 内部会 import torch。

测试阿里云镜像:

bash 复制代码
# curl 探测文件存在
curl -I https://mirrors.aliyun.com/pytorch-wheels/cpu/torch-2.4.0%2Bcpu-cp312-cp312-linux_x86_64.whl
# 返回 HTTP/2 200

# 但 wget 直连被拒(防盗链)
wget -c https://mirror.aliyun.com/pytorch-wheels/cpu/torch-2.4.0%2Bcpu-cp312-cp312-linux_x86_64.whl
# 输出:连接被拒绝

改用上海交大镜像:

bash 复制代码
# 下载(支持断点续传)
wget -c https://mirror.sjtu.edu.cn/pytorch-wheels/cpu/torch-2.4.0%2Bcpu-cp312-cp312-linux_x86_64.whl

输出:

复制代码
185.95M  7.51MB/s   用时 28s

说明:

  • GPU 版 797MB(含 CUDA),虚拟机无显卡用不上
  • CPU 版 186MB,够用
  • 上海交大镜像速度 7.5 MB/s,非常快

涉及文件:

  • ~/yolo/torch-2.4.0+cpu-cp312-cp312-linux_x86_64.whl:PyTorch CPU 安装包(186MB)

步骤 7:安装 PyTorch

命令:

bash 复制代码
# 切换到文件所在目录
cd ~/yolo

# 本地安装(不重新下载)
pip install ./torch-2.4.0+cpu-cp312-cp312-linux_x86_64.whl

输出:

复制代码
Successfully installed MarkupSafe-3.0.3 filelock-4.0.4 fsspec-2026.9.0 
jinja2-3.1.6 networkx-3.7 setuptools-84.0.0 torch-2.4.0+cpu

验证:

bash 复制代码
python -c "import torch; print('PyTorch:', torch.__version__)"
# 输出:PyTorch: 2.4.0+cpu

⚠️ 注意 :此时 setuptools 被自动升级到 84.0.0,埋下后续 pkg_resources 缺失的坑。


步骤 8:下载 RKNN-Toolkit2 的 whl

命令:

bash 复制代码
# 用 ghproxy.net 代理下载(迅雷也能下)
wget -c https://ghproxy.net/https://github.com/airockchip/rknn-toolkit2/raw/master/rknn-toolkit2/packages/x86_64/rknn_toolkit2-2.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

输出:

复制代码
37.03M  85.5 KB/s   用时 7m 23s

说明:

  • 从 GitHub raw 下载,用 ghproxy.net 代理加速
  • 选择 cp312 版本(对应 Python 3.12)
  • x86_64 架构(虚拟机是 x86_64)

涉及文件:

  • ~/yolo/rknn_toolkit2-2.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:RKNN-Toolkit2 安装包(38MB)

步骤 9:安装 RKNN-Toolkit2

命令:

bash 复制代码
# 激活虚拟环境
source ~/rknn_env/bin/activate

# 安装(--no-deps 跳过已装依赖)
pip install --no-deps ./rknn_toolkit2-2.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

输出:

复制代码
Successfully installed rknn-toolkit2-2.3.2

验证:

bash 复制代码
python -c "from rknn.api import RKNN; print('RKNN-Toolkit2 就绪!')"
# 输出:RKNN-Toolkit2 就绪!

说明:

  • --no-deps:只装 RKNN-Toolkit2 本身,依赖已手动装好
  • 不加可能重新下载/升级依赖,浪费时间

步骤 10:克隆 rknn_model_zoo 仓库

先试 GitHub(失败):

bash 复制代码
git clone --depth 1 https://ghfast.top/https://github.com/airockchip/rknn_model_zoo.git
# 卡住不动

改用 Gitee 镜像(成功):

bash 复制代码
git clone --depth 1 https://gitee.com/seaflyren/rknn_model_zoo.git

输出:

复制代码
205.80 MiB | 9.60 MiB/s   完成

说明:

  • Gitee 是国内代码托管平台,速度极快(9.6 MB/s)
  • 仓库包含转换脚本、校准集、示例代码

涉及文件:

  • ~/yolo/rknn_model_zoo/:仓库根目录(205MB)

目录结构:

复制代码
~/yolo/rknn_model_zoo/
├── examples/
│   └── yolov8/
│       └── python/
│           ├── convert.py       ← 转换脚本
│           └── yolov8.py        ← 推理示例
└── datasets/
    └── COCO/
        ├── coco_subset_20.txt   ← 校准集列表
        └── subset/              ← 校准图片

步骤 11:修复 pkg_resources 缺失

执行转换时报错:

bash 复制代码
python convert.py ~/yolo/yolov8n.onnx rk3568
# ModuleNotFoundError: No module named 'pkg_resources'

原因:

  • PyTorch 安装时自动升级 setuptools 到 84.0.0
  • 新版 setuptools(80+)移除了 pkg_resources 模块
  • RKNN-Toolkit2 内部代码依赖 pkg_resources

解决:降级 setuptools:

bash 复制代码
pip install "setuptools<80"

输出:

复制代码
Uninstalling setuptools-84.0.0
Successfully installed setuptools-79.0.1

验证:

bash 复制代码
python -c "import pkg_resources; print('pkg_resources 就绪')"
# 输出:pkg_resources 就绪

步骤 12:执行 ONNX → RKNN 转换

命令:

bash 复制代码
# 进入转换脚本目录
cd ~/yolo/rknn_model_zoo/examples/yolov8/python

# 确认虚拟环境激活
source ~/rknn_env/bin/activate

# 执行转换
python convert.py ~/yolo/yolov8n.onnx rk3568

参数说明:

  • ~/yolo/yolov8n.onnx:输入 ONNX 模型路径
  • rk3568:目标 NPU 平台
  • 默认 dtype=i8(INT8 量化)
  • 默认校准集 ../../../datasets/COCO/coco_subset_20.txt

输出(关键行):

复制代码
I rknn-toolkit2 version: 2.3.2
--> Config model
done
--> Loading model
I Loading : 100%|██████████| 127/127
done
--> Building model
I OpFusing 0: 100%|██████████|
I Quantizating : 100%|██████████| 176/176
done
--> Export rknn model
done

可忽略的警告:

  • found outlier value:某些权重有离群值,量化正常现象
  • Unkown op target: 0:少数算子回退 CPU,影响不大
  • input dtype changed to int8:RKNN 内部把输入 dtype 改成 int8

输出文件:

复制代码
~/yolo/rknn_model_zoo/examples/yolov8/model/yolov8.rknn

步骤 13:验证转换结果

命令:

bash 复制代码
ls -lh ~/yolo/rknn_model_zoo/examples/yolov8/model/yolov8.rknn

输出:

复制代码
-rw-rw-r-- 1 user user 4.2M ... yolov8.rknn

对比:

文件 大小 说明
yolov8n.onnx 12MB 原始模型(FP32)
yolov8n.rknn 约 4MB NPU 模型(INT8 量化后)

结论 :模型压缩到 1/3,已生成可供 RK3568 NPU 使用的 .rknn 文件。


📋 全部涉及文件清单

文件 位置 作用
~/rknn_env/ 虚拟机 home Python 3.12 虚拟环境
~/.config/pip/pip.conf 虚拟机 home pip 配置文件(index-url)
~/yolo/yolov8n.onnx 虚拟机 输入模型(12MB,FP32)
~/yolo/torch-2.4.0+cpu-*.whl 虚拟机 PyTorch CPU 安装包(186MB)
~/yolo/rknn_toolkit2-2.3.2-cp312-*.whl 虚拟机 RKNN-Toolkit2 安装包(38MB)
~/yolo/rknn_model_zoo/ 虚拟机 转换脚本+校准集仓库(205MB)
~/yolo/rknn_model_zoo/examples/yolov8/python/convert.py 虚拟机 转换脚本
~/yolo/rknn_model_zoo/datasets/COCO/coco_subset_20.txt 虚拟机 校准集列表
~/yolo/rknn_model_zoo/examples/yolov8/model/yolov8.rknn 虚拟机 输出模型(4.2MB,INT8)

📌 关键经验

问题 解决方案
清华源 443 被封 改用官方 pypi.org
PyTorch 下载慢 用上海交大镜像(7.5 MB/s)
GitHub 克隆慢 用 Gitee 镜像(9.6 MB/s)
pkg_resources 缺失 降级 setuptools<80
依赖版本冲突 严格锁定 numpy=1.26.4、onnx=1.18.0

✅ 到此为止的成果

虚拟机最终产出:

复制代码
~/yolo/rknn_model_zoo/examples/yolov8/model/yolov8.rknn

6.NPU+YOLO 环境准备

  • 接第4章,开发板环境准备
    目前是CPU+YOLO已经完成
    虚拟机准备的rknn已经就绪
    准备开发板使用NPU的环境
    因为系统 Python 是 3.13,而 RKNNLite 最高只支持 3.12,所以我们必须重新搭建 Python 3.12 环境
  1. 搭建 Python 3.12 环境
    下载镜像:由于网络限制,最终使用迅雷下载中科大镜像
    中科大镜像:
    https://mirrors.ustc.edu.cn/github-release/astral-sh/python-build-standalone/20241016/cpython-3.12.7%2B20241016-aarch64-unknown-linux-gnu-install_only.tar.gz
    迅雷下载
bash 复制代码
cd ~/yolo

# 1. 删掉之前可能没下载完的 py312.tar.gz,避免混淆
rm -f py312.tar.gz

# 2. 解压迅雷下载的完整压缩包(名字很长,可以用 Tab 键补全)
tar -xzf cpython-3.12.7+20241016-aarch64-unknown-linux-gnu-install_only.tar.gz

# 3. 验证解压成功
./python/bin/python3.12 --version
# 预期输出:Python 3.12.7

# 4. 创建并激活虚拟环境
./python/bin/python3.12 -m venv ~/rknn_env_312
source ~/rknn_env_312/bin/activate

# 5. 确认已进入虚拟环境(提示符前面应该有 (rknn_env_312))
which python
# 预期输出:/home/user/rknn_env_312/bin/python
  1. 安装 RKNNLite 和 Python 依赖库
    在激活的虚拟环境中((rknn_env_312)),执行以下安装命令
bash 复制代码
pip config set global.index-url https://pypi.org/simple/
说明:
清华源 443 端口被封(虚拟机网络环境限制)
官方源速度慢(100 kB/s)但能通
  • 安装依赖(numpy 必须锁定 1.26.4)
    pip install numpy==1.26.4
  • 安装 RKNNLite
    pip install rknn-toolkit-lite2
bash 复制代码
python -c "from rknnlite.api import RKNNLite; print('✅ RKNNLite 就绪!')"
只要看到 ✅ RKNNLite 就绪!,说明 Python 环境已经全部打通
  1. 检查 NPU 底层库
    环境好了,还要确认底层调用库在不在:
bash 复制代码
ls -l /usr/lib/librknnrt.so
如果文件存在:直接进入下一步。

如果提示找不到:说明你重刷系统后,把这个库弄丢了。需要下载:

bash
cd ~/yolo
wget https://ghproxy.net/https://github.com/airockchip/rknn-toolkit2/raw/master/rknpu2/runtime/Linux/librknn_api/aarch64/librknnrt.so
sudo cp librknnrt.so /usr/lib/
sudo ldconfig
bash 复制代码
(rknn_env_312) user@dshanpi-r1:~/yolo$ ls
cpu_infer.py                                                           librknnrt.so  yolov8n.onnx
cpu_result.jpg                                                         python        yolov8.rknn
cpython-3.12.7+20241016-aarch64-unknown-linux-gnu-install_only.tar.gz  testd.jpg
(rknn_env_312) user@dshanpi-r1:~/yolo$ sudo cp librknnrt.so /usr/lib/
[sudo] user 的密码:
(rknn_env_312) user@dshanpi-r1:~/yolo$ 
(rknn_env_312) user@dshanpi-r1:~/yolo$ sudo ldconfig
(rknn_env_312) user@dshanpi-r1:~/yolo$ groups
user tty disk dialout sudo audio video plugdev games users netdev docker render input systemd-journal
(rknn_env_312) user@dshanpi-r1:~/yolo$ 

(rknn_env_312) user@dshanpi-r1:~/yolo$ ls -l /usr/lib/librknnrt.so
-rw-r--r-- 1 root root 8189368 11月 7日 23:49 /usr/lib/librknnrt.so
  1. 环境检查
bash 复制代码
1. 检查 NPU 硬件节点
bash
ls -l /dev/dri/renderD129
期望:显示 crw-rw---- ... root render ... renderD129

2. 检查用户组权限
bash
groups
期望:输出里必须包含 render 和 video。如果没有,执行 sudo usermod -a -G video,render $USER,然后 exit 重新 SSH 登录。

3. 检查底层库
bash
ls -l /usr/lib/librknnrt.so
期望:显示该文件存在,大小约 7.8MB。

4. 检查模型文件
bash
ls -l ~/yolo/yolov8.rknn
期望:显示该文件存在,约 4.2MB。

5. 检查 Python 虚拟环境及核心库(⚠️ 最重要)
bash
cd ~/yolo
source ~/rknn_env_312/bin/activate
python -c "import numpy; print('numpy:', numpy.__version__)"

python -c "from rknnlite.api import RKNNLite; print('✅ RKNNLite 就绪!')"

期望:打印出 numpy: 1.26.4 以及 ✅ RKNNLite 就绪!
bash 复制代码
(rknn_env_312) user@dshanpi-r1:~/yolo$ ls -l /dev/dri/renderD129
crw-rw---- 1 root render 226, 129 11月 6日 23:49 /dev/dri/renderD129
(rknn_env_312) user@dshanpi-r1:~/yolo$ groups
user tty disk dialout sudo audio video plugdev games users netdev docker render input systemd-journal
(rknn_env_312) user@dshanpi-r1:~/yolo$ ls -l /usr/lib/librknnrt.so
-rw-r--r-- 1 root root 8189368 11月 7日 23:49 /usr/lib/librknnrt.so
(rknn_env_312) user@dshanpi-r1:~/yolo$ ls -l ~/yolo/yolov8.rknn
-rw-rw-r-- 1 user user 4367248 11月 7日 21:48 /home/user/yolo/yolov8.rknn
(rknn_env_312) user@dshanpi-r1:~/yolo$ source ~/rknn_env_312/bin/activate
(rknn_env_312) user@dshanpi-r1:~/yolo$ python -c "import numpy; print('numpy:', numpy.__version__)"
numpy: 1.26.4
(rknn_env_312) user@dshanpi-r1:~/yolo$ python -c "from rknnlite.api import RKNNLite; print('✅ RKNNLite 就绪!')"
bash: !': event not found
(rknn_env_312) user@dshanpi-r1:~/yolo$ 
(rknn_env_312) user@dshanpi-r1:~/yolo$ python -c "from rknnlite.api import RKNNLite; print('✅ RKNNLite 就绪!')"
bash: !': event not found
(rknn_env_312) user@dshanpi-r1:~/yolo$ 
(rknn_env_312) user@dshanpi-r1:~/yolo$ python -c "from rknnlite.api import RKNNLite; print('✅ RKNNLite 就绪!')"
✅ RKNNLite 就绪!
相关推荐
民乐团扒谱机3 小时前
【微实验】NSGA-II(非支配排序遗传算法)——解决多目标优化问题的“自然选择模拟器”
linux·人工智能·算法
물の韜4 小时前
ZYNQ/FMQL系列Linux之I2C开发实战
linux·arm开发·嵌入式硬件·设备树·iic·zynq
qq_371802114 小时前
Ubuntu Linux中安装WorkBuddy
linux·运维·服务器·ubuntu
无足鸟ICT4 小时前
【RHCA+】iptraf-ng(网络监控分析)
linux·网络
独隅4 小时前
WebStorm 在 Linux 环境下的实战安装与高效开发指南
linux·ide·webstorm
坤坤子吖6 小时前
Linux网络编程:TCP服务器的多进程与多线程实现
linux·服务器·开发语言·网络·c++·笔记·学习
阡陌数智6 小时前
Claude API新版本重大变更与安全升级指南
java·linux·安全
奶茶树7 小时前
【Linux】环境开发工具(vim,gcc,g++,Makefile)
linux·运维·vim
木子欢儿10 小时前
国内 macOS/Linux 安装 rust
linux·运维·服务器·macos·rust