YOLOv5s 从 PyTorch 到 RK3588 NPU 部署全流程(附性能对比)
·
以 yolov5s-5.0 为例,完整记录 .pt → ONNX → RKNN 的转换、代码修改及 RK3588 平台推理测试。
一、环境与硬件准备
| 组件 | 说明 |
|---|---|
| 训练好的模型 | yolov5s.pt(v5.0) |
| 转换设备 | x86_64 架构 Linux(Ubuntu 20.04 + Python 3.8 演示) |
| 部署设备 | RK3588 开发板 |
二、PT → ONNX 转换
1. 修改模型 forward 函数(适配 NPU 导出)
在 YOLOv5 的 models/yolo.py 中找到 Detect 类的 forward 方法,修改如下:
修改前(原始):
def forward(self, x):
"""Processes input through YOLOv5 layers, altering shape for detection: `x(bs, 3, ny,
nx, 85)`."""
z = [] # inference output
for i in range(self.nl):
x[i] = self.m[i](x[i]) # conv
bs, _, ny, nx = x[i].shape # x(bs,255,20,20) to x(bs,3,20,20,85)
x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
if not self.training: # inference
if self.dynamic or self.grid[i].shape[2:4] != x[i].shape[2:4]:
self.grid[i], self.anchor_grid[i] = self._make_grid(nx, ny, i)
if isinstance(self, Segment): # (boxes + masks)
xy, wh, conf, mask = x[i].split((2, 2, self.nc + 1, self.no - self.nc - 5),
4)
xy = (xy.sigmoid() * 2 + self.grid[i]) * self.stride[i] # xy
wh = (wh.sigmoid() * 2) ** 2 * self.anchor_grid[i] # wh
y = torch.cat((xy, wh, conf.sigmoid(), mask), 4)
else: # Detect (boxes only)
xy, wh, conf = x[i].sigmoid().split((2, 2, self.nc + 1), 4)
xy = (xy * 2 + self.grid[i]) * self.stride[i] # xy
wh = (wh * 2) ** 2 * self.anchor_grid[i] # wh
y = torch.cat((xy, wh, conf), 4)
z.append(y.view(bs, self.na * nx * ny, self.no))
return x if self.training else (torch.cat(z, 1),) if self.export else (torch.cat(z, 1),
x)
修改后(增加环境变量控制):
def forward(self, x):
z = [] # inference output
for i in range(self.nl):
if os.getenv('RKNN_model_hack', '0') != '0':
x[i] = torch.sigmoid(self.m[i](x[i])) # conv
return x
作用:通过环境变量
RKNM_model_hack控制导出时仅保留 sigmoid 激活后的卷积输出,简化 ONNX 结构。
2. 修改 export.py 脚本
在 export.py 开头增加:
import os
os.environ['RKNM_model_hack'] = 'npu_2'
修改模型输出 shape 获取方式:
修改前:
shape = tuple((y[0] if isinstance(y, tuple) else y).shape) # model output shape
修改后:
shape = tuple(y[0].shape) # model output shape
3. 执行 ONNX 导出
python export.py --weights yolov5s.pt --include onnx
得到 yolov5s.onnx 文件。
三、ONNX → RKNN 转换(在 x86 Linux 上完成)
⚠️ 注意:此步骤不能在 RK3588 上执行,需在 x86_64 主机(或虚拟机/WSL)中进行。
1. 创建 Conda 环境(Python 3.8)
conda create -n RKN python=3.8 -y
conda activate RKN
2. 安装 rknn_toolkit2
git clone https://github.com/rockchip-linux/rknn-toolkit2.git
cd rknn-toolkit2
pip install rknn_toolkit2-1.4.0_22dcfef4-cp38-linux_x86_64.whl
测试安装:
from rknn.api import RKNN
3. 修改转换示例脚本
进入示例目录:
cd rknn-toolkit2-1.6.0/rknn-toolkit2/examples/onnx/yolov5
-
将你的
yolov5s.onnx放入该目录 -
修改
test.py中的模型路径和图片路径 -


:
执行转换:
python3 test.py
成功后会生成 .rknn 模型文件。
四、在 RK3588 平台上部署并推理
1. 下载 rknpu2 工具
git clone https://github.com/rockchip-linux/rknpu2
cd rknpu2-master/examples/rknn_yolov5_demo
2. 修改头文件,设定类别数
进⼊到 /rknpu2-master/examples/rknn_yolov5_demo⽂件夹下,修改头⽂件postprocess.h
#define OBJ_CLASS_NUM 2 // 修改为你的数据集类别数
3. 修改标签文件
替换 model/coco_80_labels_list.txt 内容为你的类别名称。
4. 放置模型和测试图片
-
将
.rknn文件放到model/RK3588/目录下 -
将测试图片(如
test.jpg)放到model/目录下
5. 编译并运行
./build-linux_RK3588.sh # 生成 install 目录
cd install/rknn_yolov5_demo_linux
./rknn_yolov5_demo ./model/RK3588/best.rknn ./model/test.jpg
五、推理性能对比(RK3588 实测)
测试条件:
-
同一张测试图片
-
循环推理 10 次取平均
-
计时范围:预处理 + 推理 + 后处理
-
NPU 单核占用约 30% ~ 44%
| 模型 | 模型大小 | 平均延时 |
|---|---|---|
| yolov5s-cpu(CPU 推理) | 28.5 MB | 398 ~ 456 ms |
| yolov5s-npu(NPU 推理) | 8.2 MB | 27 ~ 29 ms |
| yolov8s(CPU 推理) | 12.2 MB | 224 ~ 240 ms |
🚀 NPU 加速效果显著,延时从数百毫秒降至 30ms 以内,模型体积也大幅缩小。
更多推荐





所有评论(0)