这个系列做到第二篇了。上一篇我把从 RK3588 到 YOLOv5s 的整条部署链路整体透了一遍这一篇开始真正动手先解决环境搭建和模型获取两个前置问题。这里先把结论放在前面——别急着在板子上把一切都装齐RK3588 部署 YOLOv5s 的正确姿势通常是“PC 端负责模型转换板端只负责推理”的双机配合。我最初也试过把所有工具链都折腾到板子上结果反而在 x86、ARM 两套架构之间来回踩坑。这篇我就按实际操作的顺序把环境怎么搭、模型怎么拿、格式怎么转一步步写清楚全程基于我手头这块 RK3588 开发板的真实过程尽量让同样刚入手的同学能照着做。1. 整体思路为什么“PC 转换 板端推理”是最高效的组合开始装软件之前先用一小节把部署 YOLOv5s 到 RK3588 的整体流转讲清楚避免后面装了半天发现装错了地方。1.1 整套模型流转链路是怎样的一个 YOLOv5s 模型要从 PyTorch 权重变成 RK3588 芯片上 NPU 能直接跑的模型中间至少要经过两次格式转换先是pt → ONNX再由ONNX → RKNN。RKNN 是瑞芯微 NPU 专用的模型格式RK3588 的 3 个 NPU 核只认这种格式它内部会做算子映射、权重重排以及可能的 INT8 量化。所以完整链路是拿到yolov5s.pt权重 → 导出成yolov5s.onnx→ 用 RKNN-Toolkit2 转成yolov5s.rknn→ 把 rknn 文件丢到开发板上用板端的推理库加载运行。其中第 2 步到第 3 步的转换工具是 PC 端x86的 Python 包板端也有简化版但实际体验差别很大。这就自然引出了环境上的分工PC 端负责模型转换和量化调试板端负责最终推理和性能验证。如果你非要反着来在板子上安装全套 RKNN-Toolkit2 和 PyTorch倒也能跑但 ARM 平台编译依赖容易出各种奇怪的问题而且模型转换是重计算任务PC 端明显更顺手。1.2 系统与工具链选型Ubuntu 20.04 Python 3.8 最稳拿我这次用的环境来说PC 端我用的是 Ubuntu 20.04Python 3.8装了 RKNN-Toolkit2 和 YOLOv5 官方仓库板端同样刷了基于 Ubuntu 20.04 的官方固件板端只需要再装一个 RKNN Toolkit Lite2 和基本的 Python 环境。为什么这么保守因为 RKNN-Toolkit2 官方文档和社区反馈里Ubuntu 20.04 Python 3.8 的兼容性最好依赖的多个底层库在 3.8 下都能找到合适版本。Python 3.10 或 Ubuntu 22.04 也能跑但装 tensorflow、opencv 这些老依赖时容易遇到版本冲突对新手很不友好。我这里不是建议你永远不用新版本而是说第一遍跑通全流程时请尽量复刻已经被验证过的环境组合少消耗一点排查问题的时间。如果你用的 Windows想处理模型转换正确的姿势也还是WSL 里装一个 Ubuntu 20.04而不是直接在 Windows 上尝试跑 RKNN-Toolkit2。官方虽然也有 Windows 版本支持但体验明显不如 Linux一些依赖库在 Windows 上的坑更多。在动手装之前把链路想明白能帮你省掉后面至少一半的折腾。2. 板端环境RK3588 烧录系统后的基础配置先把板子这一侧搞定。RK3588 芯片本身是一颗 8 核 SoC4 个 A76 大核加 4 个 A55 小核NPU 算力 6 TOPS跑 YOLOv5s 这种量级的模型绰绰有余。但芯片再强系统起不来一切都是空谈。2.1 烧录前要准备的东西USB 线与 MaskRom 模式拿到 RK3588 开发板以后第一件事是把系统烧进去。多数开发板出厂会预装系统但版本往往比较旧或者自带了厂商一堆用不上的服务所以我建议直接用自己下到的 Ubuntu 20.04 镜像重烧一遍。你需要准备一根质量靠谱的 USB Type-C 数据线能传数据不能是纯充电线、一个 5V/4A 左右的电源RK3588 满载功耗不低便宜电源会让系统随机重启、以及一台 Windows 或 Linux 电脑。烧录前要让开发板进入 MaskRom 模式。做法一般是先按住板上标着 MaskRom 或者 Recovery 的按键再插 USB 线连接电脑最后上电。具体按键位置不同板子不一样但逻辑相同。进入成功后Windows 设备管理器里会看到一个 USB 设备变化Linux 下用lsusb也能看到新的设备。2.2 RKDevTool 与 upgrade_tool 两种烧录方式Windows 下我推荐用瑞芯微官方的 RKDevTool。打开软件后进入“升级固件”页面点击“选择文件”找到下载的update.img整包然后点“执行”开始烧录。这里有个细节如果之前烧过其他版本先点一下“擦除 Flash”再烧能避免底层分区不一致导致启动失败。Linux 下对应的工具叫upgrade_tool命令行操作也差不多这个逻辑。烧录过程大约持续几分钟期间不要拔线、不要断电等进度条走完板子会自动重启进入 Ubuntu。如果你手头只有 SD 卡槽版本也可以直接用balenaEtcher之类的工具把镜像写入 TF 卡插入卡槽后从 SD 卡启动。两种方式本质没区别我习惯用 USB 整包烧写因为后面升级内核、换系统更方便。2.3 开机后的基础环境调整SSH、apt 源、Python系统起来以后先别急着装任何东西按这个顺序把基础环境弄顺先登入桌面或串口终端执行sudo apt update sudo apt install -y openssh-server sudo systemctl enable --now ssh然后把开发板接到路由器上查一下它的 IP电脑上用 MobaXterm 或 Windows Terminal 直接 SSH 登录后续都不需要再插显示器和键盘了。这一步很关键因为我后续的所有操作都是在 SSH 里完成的。接下来换 apt 源。Ubuntu 20.04 的默认官方源在国内更新速度太慢我把sources.list换成了清华源方法就是用 sed 批量替换sudo sed -i s/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g /etc/apt/sources.list sudo sed -i s/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g /etc/apt/sources.list sudo apt update然后装基础开发包sudo apt install -y python3-pip python3-venv cmake build-essentialUbuntu 20.04 自带的 Python 版本就是 3.8这一点非常重要。pip装包之前建议配置好国内镜像pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple到这里板端的基础环境就绪了。2.4 验证 NPU 驱动是否正常RK3588 芯片的 NPU 驱动在官方固件里是默认编译进内核的但最好确认一下。在 SSH 终端执行dmesg | grep rknpu如果能看到类似rknn或rknpu初始化的日志说明 NPU 驱动已经正常加载。部分固件在运行时还可以查看 NPU 负载cat /sys/kernel/debug/rknpu/load 2/dev/null || cat /proc/rknpu/load 2/dev/null如果这些路径都不存在也不要慌先确认你是不是用的官方固件。非官方固件或精简固件可能把 NPU 驱动裁掉了那后面运行 rknn 模型时会直接报“Cannot load rknn model”之类的错误。NPU 驱动这一步很多人会忽略但它决定了后面推理环节能不能跑起来。我建议一次性确认好省得到时候排查半天找不到方向。3. PC 端环境RKNN-Toolkit2、PyTorch 与权重下载板端只是运行环境真正麻烦的模型转换工作都在 PC 端完成。这一节我把 PC 端环境的搭建细节写透。3.1 用 conda 隔离环境别污染系统 PythonRKNN-Toolkit2、PyTorch、OpenCV 这些库的依赖关系比较敏感。我强烈建议在 PC 端用 conda 单独建一个虚拟环境不要往系统 Python 里硬塞。先装好 Miniconda然后执行conda create -n rknn python3.8 -y conda activate rknn这里用 Python 3.8 的原因我在前面提过是为了和 RKNN-Toolkit2 的依赖兼容。环境建好以后后续所有包都装在这个环境里出问题直接删掉重建不影响系统。Python 版本确认无误后先把 pip 源也配置成国内镜像pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple3.2 RKNN-Toolkit2 安装最容易踩的依赖坑RKNN-Toolkit2 是以 whl 包形式提供的从官方 GitHub 仓库或网盘下载后直接 pip 安装。假设你下载到的文件是rknn_toolkit2-2.0.0b0-cp38-cp38-linux_x86_64.whl那就pip install rknn_toolkit2-2.0.0b0-cp38-cp38-linux_x86_64.whl它会自动拉取一堆依赖。这里有一个非常经典的坑依赖里的numpy如果被装到了 2.x 版本大概率会在转换模型时报类似module numpy has no attribute bool的错误因为在 numpy 1.24 以后np.bool这个别名被移除了。RKNN-Toolkit2 内部有些旧代码还引用它。解决办法就是把 numpy 降级pip install numpy1.23.5如果你不够走运还遇到libGL.so.1: cannot open shared object file的报错说明系统缺少 OpenCV 依赖的动态库装一下就行sudo apt install -y libgl1 libglib2.0-0装完之后用一条命令确认导入成功python -c from rknn.api import RKNN; print(rknn ok)能正常打印rknn ok这一关就算过了。3.3 YOLOv5 官方仓库与 yolov5s 权重下载模型转换环节需要用到 YOLOv5 的官方仓库做 PT 到 ONNX 的导出以及预训练权重。克隆仓库并安装依赖git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt这里requirements.txt会装 PyTorch、torchvision、OpenCV 等。PC 端不需要 CUDACPU 版 PyTorch 足够完成推理和导出。国内如果拉取慢可以找 gitee 上同步的镜像仓库或者用git clone --depth 1只拉最新代码。权重文件是官方在 COCO 数据集上预训练好的yolov5s.pt目标检测入门常用它验证全流程。下载方式mkdir weights wget -c https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt -O weights/yolov5s.pt如果 GitHub 下载速度太慢到国内一些模型镜像站点也能找到同名文件注意核对文件大小。yolov5s.pt大小在 14MB 上下权重是 FP32 的如果下载下来只有几 KB那大概率是下载到了错误页面。下载完可以先快速验证一下模型是否完好python detect.py --weights weights/yolov5s.pt --img 640 --conf 0.25 --source data/images/bus.jpg能看到检测框正常出现说明权重没问题接下来就可以做导出转换了。4. 模型获取到 RKNN 模型从 PT 到 ONNX 再到 RKNN环境准备好后进入本篇的重头戏把yolov5s.pt变成yolov5s.rknn。这里每一步都值得仔细看因为后面板端推理时很多诡异问题都源自这一步的错误选择。4.1 官方权重 vs 自训练模型第一步就要想清楚你手上要转的模型是直接用官方 COCO 预训练权重还是自己训练出来的自定义模型这一步看似简单实际影响后面的所有配置。如果用官方权重那么类别数固定是 80anchors 也是 COCO 默认那组YOLOv5 的导出脚本直接跑就行。如果用的是自己训练的模型比如只检测 2 个类别的模型那导出 ONNX 时类别数不同后续 RKNN 转换脚本里的后处理逻辑也要同步改。很多人拿到自定义模型后不管类别数差异转换倒是成功了但板端推理结果全是乱的就是这个原因。另外如果你的自定义模型是从某个旧版 YOLOv5 改出来的anchors可能也不一样。转换 RKNN 模型本身不受 anchors 影响但板端后处理如果你手工写了锚框解码就务必保证数值与模型训练时一致。4.2 导出 ONNX官方 export.py 的正确用法YOLOv5 官方仓库提供了一个现成的导出脚本进入 YOLOv5 目录执行python export.py --weights weights/yolov5s.pt --img 640 --include onnx --opset 12这里几个参数的含义--img 640导出模型的训练输入分辨率跟训练时保持一致即可。--include onnx只导出 ONNX不导出其他格式。--opset 12ONNX 算子集版本RKNN-Toolkit2 对 opset 12 支持比较成熟。导出成功后会在目录下生成yolov5s.onnx体积大概 30MB。建议用 Netron 打开看一眼结构。YOLOv5s 的 ONNX 会输出三个检测头输出的 shape 一般是[1, 3, 80, 80, 85]、[1, 3, 40, 40, 85]、[1, 3, 20, 20, 85]其中 85 5 80对应 4 个框坐标、1 个置信度和 80 个类别分数。看明白了输出结构后面写板端解码逻辑时心里就有数。4.3 转成 RKNNtarget_platform 与量化参数详解RKNN-Toolkit2 自带 YOLOv5 示例目录一般在rknn-toolkit2/examples/onnx/yolov5。我建议直接基于官方示例改不要自己从零写脚本因为官方脚本里已经包含了 YOLOv5 的输出后处理能省很大功夫。关键配置在代码里体现为这样一段from rknn.api import RKNN rknn RKNN() rknn.config(target_platformrk3588, mean_values[[0, 0, 0]], std_values[[255, 255, 255]]) rknn.load_onnx(modelyolov5s.onnx) rknn.build(do_quantizationTrue, datasetdataset.txt) rknn.export_rknn(yolov5s.rknn)这里每个参数都要理解target_platformrk3588明确告诉转换工具目标芯片是 RK3588工具会据此选择算子映射和 NPU 指令集。mean_values和std_values决定输入图片如何做归一化。YOLOv5 官方推理时是把图片像素除以 255所以 mean 是 0std 是 255。dataset.txt量化校准图片列表文件。每行写一张图片的完整路径至少要几十张建议 100~200 张图片内容尽量覆盖你后面要检测的场景。这些图片会被用来统计激活值分布决定 INT8 量化参数。千万不要只放两三张图就量化精度会掉得很厉害。do_quantizationTrue启用 INT8 量化。如果设成 False会生成 FP16 模型精度更好一点但模型体积更大、推理速度更慢NPU 的优势也发挥不出来。转换过程如果顺利会生成yolov5s.rknn。INT8 量化后的模型体积基本在 7~8MB相比 30MB 的 ONNX 小了很多这也是模型部署时最直观的轻量化收益。4.4 模型轻量化是怎么回事INT8、输入分辨率与换结构说到轻量化很多新手会直接想到把模型换小、把图片分辨率调低但实际部署 RK3588 时轻量化是几个手段叠加的效果。其实在模型选择上YOLOv5s 本身就是 YOLOv5 系列里轻量化的代表。以 COCO 数据集为例YOLOv5s 的参数量约 7.2M计算量约 16.5 GFLOPs检测精度 mAP 约 37.2和更大的 YOLOv5m参数量 21.2MmAP 约 44.5相比换来的收益是推理速度成倍增加。而 RK3588 的 6 TOPS 算力跑 YOLOv5s 很从容跑 YOLOv5m 就明显吃紧所以 s 是板端部署的甜点型号。量化的减重效果也很明显。同一个模型FP16 的 RKNN 模型跑起来比 INT8 模型慢不少因为 NPU 对 INT8 的矩阵计算有专门加速INT8 量化还能把模型体积压到四分之一左右。代价是精度有小幅下降如果实测掉点严重可以先用do_quantizationFalse生成 FP16 对比一下确定是量化掉点还是别的问题。输入分辨率则是另一个杠杆。YOLOv5 默认--img 640对 RK3588 来说算力是够的。如果你的检测场景里小目标不多可以降到 416 或 320推理速度立刻翻倍但小目标漏检率也会明显上升。在我的实测里640 和 320 对中大型目标的检测结果差别不大但小目标差异悬殊所以分辨率怎么选取决于你的实际场景没有绝对最优。除了这些常规手段还有一些进阶的轻量化路线比如知识蒸馏、通道剪枝以及干脆换成 YOLOv8n / YOLOv8s。RKNN-Toolkit2 对 YOLOv8 的支持也比较完整转换链路和 YOLOv5 基本一致。新手第一次跑通建议先把 YOLOv5s 吃透后面换结构时一通百通。5. 实操中遇到的坑与排查方法最后这部分我把自己实际操作中踩过的坑集中记下来。环境搭建和模型转换这两个阶段零零散散的问题非常多但这些坑解决一次后面就能少走很多弯路。5.1 PC 端 pip 安装失败的典型报错最常遇到的就是在 conda 环境里执行pip install rknn_toolkit2-xxx.whl时报ERROR: No matching distribution found。这个报错十有八九是 Python 版本不匹配比如当前环境是 Python 3.11而 whl 包只支持 cp38。先执行python --version确认当前环境不对就用conda activate rknn切回正确环境。还有一个高频报错是安装 OpenCV 相关依赖时出现Building wheel for opencv-python ... error。这个通常是因为 pip 在尝试从源码编译耗时很长还容易编译失败。建议直接先sudo apt install -y python3-opencv装系统版 OpenCV或者指定版本安装预编译好 aarch64/x86 的 wheel。在 Ubuntu 20.04 Python 3.8 下用opencv-python4.8.1.78这种稍老一点的版本最省心。5.2 RKNN 转换阶段的问题排查转换时如果报E RKNN: RKNN API error: some ops are not supported或者类似算子不支持的错误先检查 ONNX 是从哪个版本的 YOLOv5 导出的。有些最新版 YOLOv5 的导出脚本会加入一些新算子而 RKNN-Toolkit2 还没完全覆盖。解决方式是把 ONNX opset 降到 12 或 11重新导出。另一个常见错误是转换过程中内存爆掉报Killed或者 OOM。RKNN 转换在生成量化表时需要加载大量中间数据PC 内存低于 8GB 时会比较吃力。实在不行可以减少 dataset.txt 的图片数量比如从 200 张降到 50 张能明显降低内存消耗但量化精度会有一定妥协。转换成功率最高的方式是把量化和不量化的转换测试分开跑。先用do_quantizationFalse验证模型能转通再开量化。两件事混在一堆里排查会浪费很多时间。5.3 板端推理结果不对怎么办模型转换成功后把 rknn 文件用 scp 传到板子上用 RKNN Toolkit Lite2 加载运行。如果发现检测结果完全不对第一反应应该是检查输入预处理是否和转换时一致。比如你在转换时设置了mean_values[[0,0,0]]、std_values[[255,255,255]]那板端推理前就要把图片像素除以 255不能自己在代码里再减 0.485、除 0.229 之类的 ImageNet 归一化那样结果必然错乱。如果框的位置基本对但类别全乱那就需要检查类别数是否匹配。用官方 COCO 权重时类别数是 80后处理里类别循环也要是 80。这个 bug 比较隐蔽因为模型能推理、能画框但框上的标签完全对不上。还有一个我自己调试时用过的小技巧先在 PC 上跑通同样的 rknn 模型用 PC 版的 RKNN-Toolkit2它也能推理和板端结果比对。两边结果一致说明模型没转错结果不一致那就是板端推理库或输入输出的环节出了问题。这个二分定位法能快速把问题缩小到具体环节。5.4 常见问题速查表现象可能原因处理方法pip 安装 whl 包提示 No matching distributionPython 版本和 whl 不匹配conda 切换到 Python 3.8 环境导入 rknn 报 numpy bool 错误numpy 版本过高pip install numpy1.23.5推理时报 Cannot load rknn model固件缺少 NPU 驱动或版本不匹配换官方 Ubuntu 20.04 固件确认 dmesg 里有 rknpuRKNN 转换时算子不支持ONNX opset 版本过高导出 ONNX 时改用--opset 12转换过程中进程被 Killed内存不足减少 dataset.txt 图片数量或加大内存检测框全乱、类别错位类别数或归一化参数不匹配核对 num_classes、mean/std、anchorsSSH 连接不稳定掉线电源供电不足或 WiFi 信号弱换电源使用有线网口连接以上这些坑我每一行都实际遇到或见群里有人遇到过。其实大部分问题都是版本和参数不一致引起的所以我在前面反复强调环境复刻的重要性。最后分享一个我个人的习惯每次搭完环境我都会把用到的版本号记录下来写成一个requirements.txt和一个部署脚本方便下次重建。模型转换这条链路参数多、依赖多、版本关系盘根错节靠记忆力去维护迟早翻车。下一篇我会写板端推理部分就是把 rknn 模型真正跑起来处理输入输出并做一次性能测试看看 RK3588 跑 YOLOv5s 实际能达到多少帧。到时候我会连后处理代码、NPU 占用观察方法一起放出来继续沿着这条路往下走。