1. 环境准备与系统配置
在RK3566(泰山派)开发板上部署YOLOv5s_relu模型前,需要确保系统环境和依赖项正确配置。以下是详细的环境准备步骤:
1.1 系统基础验证
首先确认开发板运行的是基于Rockchip内核的Ubuntu 22.04系统。通过以下命令检查系统信息:
bash复制uname -a # 查看内核版本
lsb_release -a # 查看系统发行版信息
关键点在于内核版本应为5.10.0-1012.12,这是Rockchip官方为RK3566优化的内核版本,包含了NPU驱动支持。如果版本不符,需要重新刷写系统。
1.2 NPU驱动检查
RK3566的神经网络处理单元(NPU)是实现AI加速的核心组件。执行以下命令验证驱动状态:
bash复制dmesg | grep -i rknpu
正常输出应包含类似rknpu: rknpu initialized的信息,且驱动版本建议不低于0.9。如果未显示相关信息,可能是驱动未正确加载,需要检查以下几点:
- 确认内核配置中启用了NPU支持
- 检查
/lib/modules/$(uname -r)/kernel/drivers/rknpu目录下是否存在驱动模块 - 尝试手动加载驱动:
sudo modprobe rknpu
注意:驱动版本过低可能导致性能下降或功能异常。如果版本低于0.9,建议升级内核或单独更新NPU驱动。
1.3 基础软件安装
安装Python环境和OpenCV等基础依赖:
bash复制sudo apt update
sudo apt install -y python3 python3-opencv python3-pip
这里选择系统自带的Python3和OpenCV包,可以确保版本兼容性。安装完成后验证OpenCV是否正常工作:
python复制python3 -c "import cv2; print(cv2.__version__)"
2. RKNN运行时环境部署
2.1 获取RKNN Toolkit2资源
从Rockchip官方GitHub仓库获取必要的运行时组件:
bash复制git clone https://github.com/airockchip/rknn-toolkit2.git --depth 1
cd rknn-toolkit2/rknpu2/runtime/Linux
关键文件位于以下路径:
- Runtime库:
librknn_api/aarch64/librknnrt.so - Server程序:
rknn_server/aarch64/usr/bin/*
2.2 部署运行时组件
将获取的文件部署到开发板的正确位置:
bash复制# 复制Runtime库
sudo cp librknn_api/aarch64/librknnrt.so /usr/lib/
# 复制Server程序
sudo cp -r rknn_server/aarch64/usr/bin/* /usr/bin/
部署完成后,验证版本一致性:
bash复制strings /usr/lib/librknnrt.so | grep -i "librknnrt version"
restart_rknn.sh --version
两个命令显示的版本号必须一致(如2.3.2),否则会导致兼容性问题。如果版本不一致,需要重新下载匹配的组件。
2.3 启动RKNN服务
使用提供的脚本启动服务:
bash复制sudo restart_rknn.sh
检查服务状态:
bash复制ps aux | grep rknn_server
正常应看到rknn_server进程正在运行。如果服务启动失败,可以尝试以下排查步骤:
- 检查
/usr/bin/rknn_server是否有可执行权限 - 查看系统日志:
journalctl -u rknn_server - 尝试手动启动:
/usr/bin/rknn_server &
3. RKNN Lite环境配置
3.1 安装Python Wheel包
根据Python版本选择对应的RKNN Lite安装包。首先确认Python版本:
bash复制python3 --version
例如Python 3.10对应安装包为rknn_toolkit_lite2-2.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl。安装步骤:
bash复制pip3 install rknn_toolkit_lite2-2.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
3.2 验证安装
执行简单测试验证安装是否成功:
python复制python3 -c "from rknnlite.api import RKNNLite; print('OK')"
如果输出"OK"表示安装成功。常见问题及解决方案:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| ImportError | 版本不匹配 | 检查Python版本与wheel包是否对应 |
| 依赖缺失 | 缺少系统库 | 安装缺失依赖:sudo apt install libblas3 liblapack3 |
| 权限问题 | 安装目录不可写 | 使用pip3 install --user或sudo安装 |
4. 模型转换与部署
4.1 获取模型文件
从Rockchip模型库获取YOLOv5s_relu模型:
bash复制git clone https://github.com/airockchip/rknn_model_zoo.git --depth 1
cd rknn_model_zoo/examples/yolov5/python
模型文件位于../model/yolov5s_relu.onnx。转换命令:
bash复制python convert.py ../model/yolov5s_relu.onnx rk3566 i8 ../model/yolov5s_relu.rknn
转换参数说明:
rk3566:指定目标平台i8:使用8位整数量化- 最后一个参数为输出RKNN模型路径
4.2 转换过程详解
模型转换涉及以下关键步骤:
- 模型解析:读取ONNX模型结构
- 量化校准:将FP32权重量化为INT8
- 平台适配:针对RK3566 NPU进行优化
- 模型验证:确保转换前后精度损失在可接受范围
转换过程中可能遇到的问题:
- 如果遇到
Unsupported ONNX opcode错误,可能是ONNX版本不兼容,尝试导出时指定opset版本 - 量化失败通常是由于缺少校准数据集,可以在convert.py中添加
dataset参数指定校准图片路径 - 输出模型过大可能是未启用压缩,添加
do_quantization=False参数测试
5. 模型测试与验证
5.1 基础测试脚本
创建test_yolov5.py测试脚本,核心代码如下:
python复制from rknnlite.api import RKNNLite
import cv2
import numpy as np
# 初始化RKNN
rknn = RKNNLite()
ret = rknn.load_rknn('yolov5s_relu.rknn')
ret = rknn.init_runtime()
# 加载测试图像
img = cv2.imread('bus.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (640, 640))
# 执行推理
outputs = rknn.inference(inputs=[img])
# 后处理...
5.2 常见问题解决
执行测试时可能遇到的典型问题及解决方案:
问题1:failed to open rknpu module, need to insmod rknpu dirver
原因:用户没有访问NPU设备的权限
解决方案:
bash复制sudo usermod -aG video $(whoami) # 将当前用户加入video组
sudo reboot # 重启生效
验证权限:
bash复制groups # 确认输出中包含video
ls -l /dev/rknpu # 检查设备权限
问题2:推理结果异常或性能低下
可能原因及排查步骤:
- 检查模型输入尺寸是否与代码一致
- 确认图像预处理(归一化、通道顺序)符合模型要求
- 使用
rknn.query_perf_detail()获取各层耗时,定位性能瓶颈 - 尝试不同量化精度(如FP16)比较结果
5.3 官方测试脚本适配
Rockchip提供的官方测试脚本需要少量修改才能正常运行:
- 修改
rknn_executor.py中的RKNN初始化部分:
python复制# 原代码
# self.rknn = RKNN()
# 修改为
self.rknn = RKNNLite()
- 调整
yolov5.py中的推理调用:
python复制# 原代码
# outputs = model.inference([input_data])
# 修改为
outputs = model.run([np.expand_dims(input_data, 0)])
修改后执行测试:
bash复制python3 yolov5.py --model_path ../model/yolov5s_relu.rknn --img_show
6. 性能优化技巧
6.1 NPU利用率优化
通过以下方法提高NPU利用率:
- 批处理优化:尽量使用批量推理
python复制# 同时处理多帧
outputs = rknn.inference(inputs=[img1, img2, img3])
- 异步推理:重叠数据准备和计算
python复制rknn.init_runtime(async_mode=True)
future = rknn.inference(inputs=[img], data_format='nhwc')
outputs = future.get()
- 内存优化:复用输入输出缓冲区
python复制input_buf = np.zeros((1,640,640,3), dtype=np.uint8)
output_buf = [np.zeros((1,85,6300), dtype=np.float32) for _ in range(3)]
rknn.inference(inputs=[input_buf], outputs=output_buf)
6.2 模型量化策略
不同量化方式的性能对比:
| 量化类型 | ���度 | 推理速度 | 适用场景 |
|---|---|---|---|
| FP32 | 高 | 慢 | 精度要求极高的场景 |
| FP16 | 中 | 中 | 平衡精度与速度 |
| INT8 | 低 | 快 | 实时性要求高的场景 |
建议通过以下命令测试不同量化方式:
bash复制python convert.py ../model/yolov5s_relu.onnx rk3566 fp16 ../model/yolov5s_relu_fp16.rknn
6.3 温度管理与功耗控制
长时间运行NPU时需要注意散热:
- 监控温度:
bash复制cat /sys/class/thermal/thermal_zone*/temp
- 动态调整频率:
bash复制# 查看NPU频率
cat /sys/devices/platform/fde40000.npu/clock_rate
# 设置最大频率(MHz)
echo 800000 > /sys/devices/platform/fde40000.npu/max_rate
- 使用散热措施:
- 被动散热:确保散热片接触良好
- 主动散热:添加风扇,控制转速
7. 实际应用集成
7.1 视频流处理示例
将YOLOv5集成到视频处理流水线:
python复制import cv2
from rknnlite.api import RKNNLite
class YOLOv5Detector:
def __init__(self, model_path):
self.rknn = RKNNLite()
self.rknn.load_rknn(model_path)
self.rknn.init_runtime()
def detect(self, frame):
# 预处理
img = cv2.resize(frame, (640, 640))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 推理
outputs = self.rknn.inference(inputs=[img])
# 后处理
boxes = self.postprocess(outputs)
return boxes
# 使用示例
detector = YOLOv5Detector('yolov5s_relu.rknn')
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret: break
boxes = detector.detect(frame)
for box in boxes:
x1,y1,x2,y2 = box[:4]
cv2.rectangle(frame, (x1,y1), (x2,y2), (0,255,0), 2)
cv2.imshow('Detection', frame)
if cv2.waitKey(1) == 27: break
cap.release()
7.2 多模型协同工作
RK3566支持同时运行多个模型:
python复制# 初始化多个模型
detector = RKNNLite()
detector.load_rknn('yolov5s_relu.rknn')
detector.init_runtime()
classifier = RKNNLite()
classifier.load_rknn('mobilenet.rknn')
classifier.init_runtime()
# 协同推理
def pipeline(img):
# 目标检测
boxes = detector.inference([img])
# 对每个检测结果分类
for box in boxes:
x1,y1,x2,y2 = box
crop = img[y1:y2, x1:x2]
cls = classifier.inference([crop])
return boxes, cls
7.3 模型更新策略
实现不重启服务的模型热更新:
- 使用符号链接管理模型:
bash复制ln -sf yolov5s_relu_v2.rknn current_model.rknn
- 在代码中定期检查更新:
python复制import os
import time
class ModelLoader:
def __init__(self, model_path):
self.model_path = model_path
self.last_mtime = 0
self.load_model()
def check_update(self):
mtime = os.path.getmtime(self.model_path)
if mtime > self.last_mtime:
self.load_model()
def load_model(self):
self.rknn = RKNNLite()
self.rknn.load_rknn(self.model_path)
self.rknn.init_runtime()
self.last_mtime = os.path.getmtime(self.model_path)
# 使用示例
loader = ModelLoader('current_model.rknn')
while True:
loader.check_update()
# 使用loader.rknn进行推理
time.sleep(1)
