避坑指南:YOLOv5模型从PyTorch到RKNN的跨平台转换与RK3588 NPU部署实战

张开发
2026/4/6 12:09:04 15 分钟阅读

分享文章

避坑指南:YOLOv5模型从PyTorch到RKNN的跨平台转换与RK3588 NPU部署实战
1. 为什么你的YOLOv5模型总是转换失败每次看到终端里蹦出那一串红色报错信息我就想起自己第一次尝试把YOLOv5模型部署到RK3588开发板上的惨痛经历。当时花了两周时间反复折腾最后发现问题的根源竟然是一个简单的版本兼容性问题。版本选择是第一个大坑。很多新手会直接克隆YOLOv5的最新版本开始训练结果在转换阶段就会遇到各种莫名其妙的错误。我实测过从v5.0到v7.0各个版本发现只有v5.0版本能稳定转换到RKNN格式。这是因为瑞芯微的RKNN-Toolkit2工具链对ONNX算子支持有特定要求而新版本YOLOv5使用的某些算子无法被正确转换。具体操作时你需要找到这个commit idc5360f6e7009eb4d05f14d1cc9dae0963e949213。这个版本的YOLOv5不仅训练稳定更重要的是它的模型结构能被RKNN-Toolkit2完美支持。我建议直接在Linux系统上使用以下命令克隆指定版本git clone https://github.com/ultralytics/yolov5.git cd yolov5 git checkout c5360f6e7009eb4d05f14d1cc9dae0963e949213训练完成后在导出ONNX模型前还有个关键步骤。你需要修改export.py文件中的输出层设置默认的Detect层会导致转换失败。找到这段代码# 修改前 y.append(x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()) # 修改后 y.append(x[i].view(bs, -1, ny, nx).permute(0, 2, 3, 1).contiguous())这个改动是为了适配RKNN的算子支持不改的话后面转换时会报Unsupported ONNX opcode: Shape错误。我当初就是卡在这里三天最后在GitHub的issue里找到了解决方案。2. 从PyTorch到ONNX那些官方文档没告诉你的细节模型转换就像玩俄罗斯套娃每一步都得严丝合缝。在Windows上把.pt转成.onnx时我遇到过最坑的问题是动态维度。RKNN模型要求输入尺寸必须是固定的但YOLOv5默认会导出带动态维度的ONNX模型。解决方法是在导出时加上--dynamic参数的反参数python export.py --weights best.pt --img 640 --batch 1 --include onnx --opset 12这里有几个关键点需要注意--img 640必须和训练时的尺寸一致--opset 12指定ONNX算子集版本太高或太低都会出问题绝对不要使用--dynamic参数否则后续转换必定失败转换完成后建议用Netron工具打开生成的ONNX文件检查结构。重点看三个地方输入节点是否固定为[1,3,640,640]格式输出节点是否保持为3个检测头是否有不支持的算子如GridSample有一次我发现转换后的模型精度骤降排查后发现是ONNX的ScatterND算子不被RKNN支持。后来在YOLOv5的export.py里添加--grid参数才解决。这些细节在官方文档里根本找不到都是踩坑踩出来的经验。3. Linux环境配置躲开依赖地狱的终极指南从ONNX到RKNN的转换必须在Linux环境下进行这里藏着最令人头疼的依赖问题。我试过Ubuntu 18.04/20.04/22.04三个版本最终发现20.04是最稳定的选择。Python环境要用conda单独配置千万别用系统自带的Python。我推荐使用miniconda创建专用环境wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh conda create -n rknn python3.8 conda activate rknn安装RKNN-Toolkit2时要注意whl文件的版本匹配。以1.4.0版本为例pip install rknn_toolkit2-1.4.0_22dcfef4-cp38-cp38-linux_x86_64.whl这里最容易出错的是protobuf版本冲突。如果遇到TypeError: Descriptors cannot not be created directly.这样的错误需要强制指定protobuf版本pip install protobuf3.20.1我整理了一份完整的依赖清单放在转换脚本同目录下的requirements.txt里numpy1.21.6 onnx1.12.0 onnxruntime1.12.1 opencv-python4.5.5.64 protobuf3.20.1 scipy1.7.34. RK3588部署实战让NPU火力全开的秘诀当你好不容易得到RKNN模型准备在RK3588上大展拳脚时新的坑又来了。首先是系统选择官方提供的Android系统对NPU支持有限建议刷Ubuntu 20.04镜像。部署时需要准备三个关键组件rknpu2运行时库OpenCV的ARM编译版本针对RK3588优化的rknn_yolov5_demo示例程序我建议直接使用官方预编译的库自己交叉编译太容易出错。下载后按这个目录结构部署/rknn_demo ├── model │ └── best.rknn ├── lib │ ├── librknnrt.so │ └── opencv └── rknn_yolov5_demo运行前需要设置环境变量export LD_LIBRARY_PATH./lib:$LD_LIBRARY_PATH实测发现NPU的性能与内存分配密切相关。通过调整RKNN的core_mask参数可以获得最佳性能rknn.config( core_maskRKNN.NPU_CORE_0_1_2, # 使用三个NPU核心 ... )在我的缺陷检测项目中优化前后的推理速度对比惊人默认设置98ms调优后63msCPU版本2150ms最后分享一个调试技巧在板子上运行cat /sys/kernel/debug/rknpu/load可以实时查看NPU利用率。当发现利用率低于70%时说明模型没有充分优化可能需要调整rknn.config()中的batch_size或core_mask参数。

更多文章