下载yolov5
标准版
git 链接:ultralytics/yolov5 at v7.0
yolov5s.pt 是一个预训练好的权重文件,需要单独下载。下载链接是:Releases · ultralytics/yolov5
在此处将yolov5s.pt 下载完成,其中包含
yolov5s.pt 包含的内容: ├── 模型结构参数(层数、通道数等) ├── 权重数值(训练好的参数) └── 训练状态(优化器、epoch等) .pt 文件只存储数值,不存储输出方式。同样的 yolov5s.pt: 用标准 YOLOv5 代码加载 → 单输出 [1, 25200, 85] 用 AIROCKIP 版 YOLOv5 代码加载 → 三输出 [1,3,80,80,85], [1,3,40,40,85], [1,3,20,20,85]airockchip 版
Rockchip 的 RKNN Model Zoo 文档明确说明,它的 YOLOv5 示例模型来源于 airockchip/yolov5,并且提供的是优化后的模型,和官方原始模型不同。文档中举例说明,优化版本会把类似 [1,19200,85] 的输出改成类似 [1,255,80,80] 的检测头输出,并把不利于量化的子图删除后放到外部后处理。Rockchip 维护的 YOLOv5 分支基于 YOLOv5 v7.0,并且提供了 --rknpu 参数
GitHub 命令:git clone https://github.com/airockchip/yolov5.git Gitee 命令:git clone https://gitee.com/airockchip/yolov5.git下载好后,我们先配置依赖
进入 YOLOv5 目录: pip install -r requirements.txt pip install onnx onnxsim onnxruntime如果还没有训练自己的模型,可以先下载官方预训练模型,例如:我们先用官方预训练模型测试流程,也就是刚刚下载好的yolov5s.pt。
python export.py --rknpu --weight yolov5s.pt 这个命令会导出适配瑞芯微 NPU 的 ONNX 模型,核心功能: 自动执行的操作 说明 三输出 自动调整 Detect 层,输出三个独立尺度的特征图 去除后处理 不做 sigmoid、解码、NMS,输出原始卷积结果 算子适配 使用 NPU 支持的 ONNX 算子(如将 Sigmoid 替换为 Silu) 固定维度 通常不使用动态轴,固定输入尺寸利于量化第一次导出时遇到的问题
执行:python export.py --rknpu --weight yolov5s.pt 报错:_pickle.UnpicklingError: Weights only load failed 我目前环境使用: Python 3.11.9 torch 2.7.1新版 PyTorch 的 torch.load() 默认更严格。PyTorch 文档中也说明,torch.load() 现在有 weights_only 参数,用来限制反序列化时可以加载的对象类型;同时也提示不要加载不可信来源的模型文件。解决方法是:
修改:models\experimental.py 找到这一行:ckpt = torch.load(attempt_download(w), map_location='cpu') 改成:ckpt = torch.load(attempt_download(w), map_location='cpu', weights_only=False)为什么同一份权重能产生不同输出?
YOLOv5 的检测头(Head)本身就是三个独立尺度的特征图:
Backbone → Neck → Head ├── P3: [1, 255, 80, 80] ← 8倍下采样,检测小目标 ├── P4: [1, 255, 40, 40] ← 16倍下采样,检测中目标 └── P5: [1, 255, 20, 20] ← 32倍下采样,检测大目标 每个 255 通道实际是 3 × 85(3个anchor × 85维信息): 85 = 4(bbox坐标) + 1(置信度) + 80(COCO类别数)核心区别
在于 Detect 层的 forward 方法 标准 YOLOv5 的 Detect.forward: def forward(self, x): z = [] # 收集三个尺度的结果 for i in range(self.nl): x[i] = self.m[i](x[i]) # 卷积 # ... sigmoid、坐标变换 ... z.append(y.view(bs, -1, self.no)) # 展平空间维度 return torch.cat(z, 1) # ← 拼接成 [1, 25200, 85] # 25200 = 3×(80×80 + 40×40 + 20×20) AIROCKIP 版的 Detect.forward: def forward(self, x): z = [] for i in range(self.nl): x[i] = self.m[i](x[i]) # 不做 sigmoid,不做坐标变换,不拼接 # 直接 reshape 成 [batch, 3, h, w, 85] x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2) return x # ← 直接返回三个尺度的列表 # x[0]: [1, 3, 80, 80, 85] # x[1]: [1, 3, 40, 40, 85] # x[2]: [1, 3, 20, 20, 85]准备量化数据集
量化数据集不是训练集,也不需要标签文件,找一些图片即可。
Ubuntu 主要负责事项
主要需要准备RKNN 转换环境
1. git 2. Python 虚拟环境工具 3. rknn-toolkit2 4. rknn_model_zoo先确认 Ubuntu 环境,如果是 Ubuntu 22.04,一般默认是 Python 3.10,可以直接用。RKNN-Toolkit2 官方当前说明支持 Python 3.6 到 Python 3.12,最新版本显示为 v2.3.2。
安装基础工具
sudo apt update sudo apt install -y git python3-pip python3-venv build-essential cmake sudo apt install -y libgl1 libglib2.0-0创建 Python 虚拟环境
建议单独建立一个环境,比如叫rknn_env:
mkdir ~/rknn_project cd ~/rknn_project python3 -m venv rknn_env 在当前目录下,创建一个名为 rknn_env 的独立 Python 环境文件夹 这个文件夹里有一套完全独立的 Python 解释器、pip 包管理工具 之后安装的 RKNN 相关库(如 rknn-toolkit),只会装在这里面 和系统全局 Python 彻底隔离,不会污染其他项目,也不会被其他项目影响 source rknn_env/bin/activate 激活虚拟环境,进入这个独立的 Python 环境 退出虚拟环境,在终端输入 deactivate安装 rknn-toolkit2
目前最新版本是 2.3.2,支持 Ubuntu 22.04 + Python 3.10/3.11
pip install rknn-toolkit2 -i https://pypi.tuna.tsinghua.edu.cn/simple 验证安装成功 python3 -c "from rknn.api import RKNN; print('rknn-toolkit2 安装成功')"下载 rknn_model_zoo
cd ~/rknn_project git clone https://github.com/airockchip/rknn_model_zoo.git cd ~/rknn_project git clone https://gitee.com/airockchip/rknn_model_zoo.git转移文件
把 Windows 上的文件拿到 Ubuntu,
1. yolov5s.onnx 2. val2017 图片目录生成dataset.txt
假设我们的图片路径在
/home/cat/rknn_project/val2017所以在这个目录:
/home/cat/rknn_project下面新建一个python文件夹
from pathlib import Path import random # 量化图片所在目录 IMAGE_DIR = Path("/home/cat/rknn_project/val2017") # 输出的 dataset.txt 路径 OUTPUT_TXT = Path("/home/cat/rknn_project/dataset.txt") # 支持的图片格式 IMAGE_SUFFIXES = {".jpg", ".jpeg", ".png", ".bmp"} # 使用多少张图片做量化 # 建议先用 300 张,后面需要可以改成 500 或 None MAX_NUM = 300 # 固定随机种子,保证每次生成结果一致 RANDOM_SEED = 2026 def main(): if not IMAGE_DIR.exists(): raise FileNotFoundError(f"图片目录不存在: {IMAGE_DIR}") images = [ p for p in IMAGE_DIR.rglob("*") if p.is_file() and p.suffix.lower() in IMAGE_SUFFIXES ] if not images: raise RuntimeError(f"没有在目录中找到图片: {IMAGE_DIR}") print(f"找到图片数量: {len(images)}") random.seed(RANDOM_SEED) random.shuffle(images) if MAX_NUM is not None: images = images[:MAX_NUM] with open(OUTPUT_TXT, "w", encoding="utf-8") as f: for img in images: # 写入绝对路径 f.write(img.resolve().as_posix() + "\n") print(f"dataset.txt 生成完成: {OUTPUT_TXT}") print(f"写入图片数量: {len(images)}") if __name__ == "__main__": main() 运行: python3 make_dataset.py 运行成功后,会生成: /home/cat/rknn_project/dataset.txt修改 convert.py 的 dataset 路径
打开rknn_model_zoo 文件夹下的:
nano ~/rknn_project/rknn_model_zoo/examples/yolov5/python/convert.py找到类似这一行:
DATASET_PATH = '../../../datasets/COCO/coco_subset_20.txt'改成我们刚刚生成的dataset.txt 目录:
DATASET_PATH = '../dataset.txt'ONNX 转为 RKNN并进行量化
官方 YOLOv5 示例里的命令格式就是:
python convert.py <onnx_model> <TARGET_PLATFORM> <dtype> <output_rknn_path>其中 i8 表示做 INT8 量化,fp 表示不量化,默认是 i8。
所以,在我们的路径下目前有这些文件,
目前先激活 RKNN 环境,
source /home/cat/rknn_project/rknn_env/bin/activate然后检查 RKNN-Toolkit2 是否能用:
python -c "from rknn.api import RKNN; print('rknn-toolkit2 OK')"我们的目标板子是RK3588
python convert.py /home/cat/rknn_project/yolov5s.onnx rk3588 i8 /home/cat/rknn_project/yolov5s.rknnrknn_model_zoo
Rockchip 官方的模型仓库:airockchip/rknn_model_zoo
git clone https://gitee.com/airockchip/rknn_model_zoo.git
里面有针对 RK3588 适配好的 YOLOv5 完整示例,包括转换脚本和 C++ 部署代码,比自己从头写省很多事。