ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

rknn_model_zoo 中的 YOLOv7 部署实战:ONNX 转换、量化与 RKNN C/Python 双端推理

rknn_model_zoo 中的 YOLOv7 部署实战:ONNX 转换、量化与 RKNN C/Python 双端推理 示例工程人工智能嵌入式边缘计算计算机视觉模型优化【免费下载链接】rknn_model_zoo项目地址https://gitcode.com/gh_mirrors/rk/rknn_model_zoo点击查看免费下载本指南完整梳理 rknn_model_zoo 仓库examples/yolov7示例的部署全流程从官方 YOLOv7 模型的结构优化与 ONNX 导出到基于 rknn-toolkit 的 RKNN 模型转换含 i8/u8 量化与 fp 非量化再到 Python 与 Android/Linux C 两种 Demo 的编译、部署与运行。读完本文你可以在 RK3566、RK3588、RV1126 等 Rockchip NPU 平台上独立完成 YOLOv7 的目标检测落地并理解锚点解码、NMS 后处理在 RKNN 输出下的实现细节。1. 示例概述与适用平台examples/yolov7是 rknn_model_zoo 中用于在 Rockchip NPU 上部署 YOLOv7 目标检测的官方示例模型来自 airockchip 的 yolov7 开源项目模型结构经过针对 RKNN 的适配优化。示例同时提供 Python 推理脚本与 C 语言 Demo覆盖模型转换、量化、推理、后处理与结果可视化全链路。仓库中的目录结构如下examples/yolov7/ ├── README.md ├── cpp/ │ ├── CMakeLists.txt │ ├── main.cc # C Demo 入口 │ ├── postprocess.cc/.h # 锚点解码 NMS 后处理 │ ├── yolov7.h │ └── rknpu1/ rknpu2/ # 不同 NPU 平台的模型加载实现 ├── model/ │ ├── anchors_yolov7.txt # 3 层输出对应的锚点 │ ├── bus.jpg # 测试图片 │ ├── coco_80_labels_list.txt │ └── download_model.sh ├── model_comparison/ # 官方模型与优化模型的对比图 ├── python/ │ ├── convert.py # ONNX - RKNN 转换脚本 │ └── yolov7.py # Python 推理 Demo └── result.png # 预期输出效果图当前示例支持的 NPU 平台包括RK3562、RK3566、RK3568、RK3576、RK3588、RV1126B、RV1109、RV1126、RK1808、RK3399PRO。其中 RK1808、RV1109、RV1126 属于 RKNPU1 一代 NPU不支持 Android 平台其余平台对应 RKNPU2Android 与 Linux 均支持。2. 预训练模型下载与结构优化说明2.1 下载 ONNX 模型进入examples/yolov7/model目录执行下载脚本即可获得两个 ONNX 模型cd model ./download_model.sh脚本examples/yolov7/model/download_model.sh会下载yolov7-tiny.onnx与yolov7.onnx两个文件前者是轻量版本适合对算力或内存敏感的嵌入式场景。2.2 官方模型与优化模型的差异README 明确说明仓库提供的模型是经过优化的模型与官方原始模型不同。以yolov7-tiny.onnx为例差异体现在输出结构上输出信息对比左图为官方原始模型右图为优化模型图中三个彩色框标注了三个输出的变化位置输出形状变化以[1,3,20,20,85] - [1,255,20,20]为例优化过程将卷积节点之后的子图图中框选部分从模型中移除仅保留卷积的输出[1,255,20,20]这种优化的动机是YOLOv7 原始输出的85维通道中除4维坐标、1维目标置信度和80维类别概率外还包含一些对 RKNN 部署无用的计算子图。将其裁剪后输出从[1,3,20,20,85]按锚点维度排列变为[1,255,20,20]通道维合并为 3×85一方面减小模型体积与推理计算量另一方面让输出可以直接按通道方式解码与仓库提供的后处理实现process_i8/process_u8/process_fp32一一对应。不同分辨率输出层如 20×20、40×40、80×80均按同样方式处理。3. ONNX 转 RKNN转换脚本与参数详解3.1 转换命令格式cd python python convert.py onnx_model TARGET_PLATFORM dtype(optional) output_rknn_path(optional) # 例如 python convert.py ../model/yolov7-tiny.onnx rk3588 # 输出模型默认保存在 ../model/yolov7.rknn参数说明参数是否必选说明onnx_model必选指定 ONNX 模型路径TARGET_PLATFORM必选指定 NPU 平台名如rk3588可选值见下方列表dtype可选i8/u8表示做量化fp表示不做量化默认i8output_rknn_path可选指定 RKNN 模型保存路径默认与 ONNX 同目录文件名为yolov7.rknn3.2 平台与 dtype 的对应关系从转换脚本 examples/yolov7/python/convert.py 的入口参数检查逻辑parse_arg可以看到平台与量化数据类型的对应约束平台可选值rk3562, rk3566, rk3568, rk3576, rk3588, rv1126b, rv1109, rv1126, rk1808对于rk3562, rk3566, rk3568, rk3576, rk3588, rv1126bRKNPU2dtype 可选i8有符号 8bit 量化与fp对于rv1109, rv1126, rk1808RKNPU1dtype 可选u8无符号 8bit 量化与fp。脚本会根据 dtype 设置量化开关i8/u8对应do_quant Truefp对应do_quant False非法 dtype 会直接报错退出。3.3 转换流程的源码级实现convert.py的转换流程分为五步对应 rknn-toolkit 的标准 API 调用序列创建 RKNN 对象rknn RKNN(verboseFalse)配置预处理参数rknn.config(mean_values[[0, 0, 0]], std_values[[255, 255, 255]], target_platformplatform)。注意这里均值全 0、标准差全 255即仅做x/255归一化RGB 各通道独立这与 Python 推理脚本中input_data input_data/255.的预处理方式保持一致加载 ONNX 模型rknn.load_onnx(modelmodel_path)返回非 0 表示加载失败构建 RKNN 模型rknn.build(do_quantizationdo_quant, datasetDATASET_PATH)。量化时使用仓库预置的校准数据集datasets/COCO/coco_subset_20.txt20 张 COCO 子集图片路径定义在脚本头部的DATASET_PATH导出 RKNN 文件rknn.export_rknn(output_path)随后rknn.release()释放资源。每个步骤均有返回值检查失败时打印错误信息并退出便于定位转换问题。4. Python Demo推理与后处理4.1 运行命令cd python # 用 PyTorch 模型或 ONNX 模型推理 python yolov7.py --model_path pt_model/onnx_model --img_show # 用 RKNN 模型推理 python yolov7.py --model_path rknn_model --target TARGET_PLATFORM --img_show--target指定 NPU 平台名如rk3588默认值为rk3566--img_show会弹出窗口显示检测结果--img_save则将结果保存到./result目录。4.2 模型容器与输入输出脚本 examples/yolov7/python/yolov7.py 根据模型后缀自动选择执行容器setup_model.pt/.torchscript使用py_utils/pytorch_executor.py中的Torch_model_container.rknn使用py_utils/rknn_executor.py中的RKNN_model_container需要--target指定平台可配合--device_id指定连接的设备.onnx使用py_utils/onnx_executor.py中的ONNX_model_container。这样同一套后处理代码即可在 PyTorch、ONNX、RKNN 三种模型间直接对比结果。预处理使用COCO_test_helper的letter_box做等比缩放填充输入尺寸固定为IMG_SIZE (640, 640)宽、高可按需改为 1280×736 等填充色为(0,0,0)黑色——注释说明这是为了与 RGA 初始化的(0,0,0)保持一致C Demo 中的填充色则为 114bg_color 114。4.3 锚点文件与后处理流程YOLOv7 是锚点anchor检测器锚点数据从model/anchors_yolov7.txt读取--anchors参数可指定其他路径。文件内容共 18 个浮点数按3输出层×3每层锚点数×2宽、高排列12.0 16.0 19.0 36.0 40.0 28.0 # 80×80 层 36.0 75.0 76.0 55.0 72.0 146.0 # 40×40 层 142.0 110.0 192.0 243.0 459.0 401.0 # 20×20 层后处理核心逻辑post_process的流程为维度重塑将每个输出的1×255×H×W重塑为3×85×H×Wlen(anchors[0])个锚点 × 85 通道锚点解码box_process坐标通道经x*2 - 0.5得到中心偏移宽高通道经(x*2)^2 * anchor得到目标宽高再加上网格偏移并乘以 strideIMG_SIZE/网格尺寸最后把[cx, cy, w, h]转为[x1, y1, x2, y2]阈值过滤filter_boxes默认OBJ_THRESH 0.25取类别最大概率与目标置信度乘积作为最终得分注释中给出 mAP 测试推荐值OBJ_THRESH 0.001、NMS_THRESH 0.65类别内 NMSnms_boxes默认NMS_THRESH 0.45按类别分别抑制重叠框结果输出draw打印类别 (x1 y1 x2 y2) 得分并绘制检测框。脚本还内置了 COCO mAP 评测能力--coco_map_test会按 COCO 标注格式导出预测 JSON需--anno_json指向datasets/COCO/annotations/instances_val2017.json--img_folder指向验证集目录并调用coco_eval_with_json计算 mAP便于量化精度损失评估。5. C Demo 的编译、部署与运行C Demo 的推理主流程在 examples/yolov7/cpp/main.cc加载模型 → 读取图片 → 推理 → 后处理 → 画框 → 写出out.png并用easy_timer分别统计init_yolov7_model、inference_yolov7_model等阶段的耗时。5.1 交叉编译环境Android 与 Linux 平台的编译均需参考仓库的编译环境搭建文档Android 平台docs/Compilation_Environment_Setup_Guide.mdLinux 平台docs/Compilation_Environment_Setup_Guide.md搭建好交叉编译环境后在examples/yolov7/cpp下执行 CMake 构建注意需要将示例名替换为yolov7产物位于install/TARGET_PLATFORM_android_ARCH/rknn_yolov7_demo/Android或install/TARGET_PLATFORM_linux_ARCH/rknn_yolov7_demo/Linux。CMake 构建文件 examples/yolov7/cpp/CMakeLists.txt 展示了平台分支逻辑TARGET_SOC为rv1106/rv1103时定义RV1106_1103宏编译rknpu2/yolov7_rv1106_1103.cc并链接3rdparty/allocator/dmaRV1106 RGA 要求输入输出缓冲区由 DMA 分配TARGET_SOC为rk1808/rv1109/rv1126时定义RKNPU1宏编译rknpu1/yolov7.cc其余 RKNPU2 平台编译rknpu2/yolov7.cc。5.2 Android 平台部署RK1808、RV1109、RV1126 不支持设备通过 USB 连接后adb root adb remount adb push install/TARGET_PLATFORM_android_ARCH/rknn_yolov7_demo/ /data/进入设备运行adb shell cd /data/rknn_yolov7_demo export LD_LIBRARY_PATH./lib ./rknn_yolov7_demo model/yolov7.rknn model/bus.jpg5.3 Linux 平台部署USB 连接设备时adb push install/TARGET_PLATFORM_linux_ARCH/rknn_yolov7_demo/ /userdata/其他开发板可用scp等方式将install/TARGET_PLATFORM_linux_ARCH/rknn_yolov7_demo/下所有文件推送到设备的/userdata目录然后adb shell cd /userdata/rknn_yolov7_demo export LD_LIBRARY_PATH./lib ./rknn_yolov7_demo model/yolov7.rknn model/bus.jpg运行结束后结果保存在out.png可通过adb pull /data/rknn_yolov7_demo/out.pngAndroid或adb pull /userdata/rknn_yolov7_demo/out.pngLinux拉回主机查看。CMake 的install规则会将bus.jpg、coco_80_labels_list.txt及model/*.rknn自动安装到部署目录的model/子目录与运行命令中的路径约定一致。6. 底层原理RKNN 输出如何被后处理消费6.1 模型加载与输出属性查询examples/yolov7/cpp/rknpu2/yolov7.cc 展示了标准 RKNN C API 调用链rknn_init加载模型 →rknn_query(RKNN_QUERY_IN_OUT_NUM)获取输入输出数量 → 分别查询输入/输出张量属性并打印dims / fmt / type / qnt_type / zp / scale。其中关键判断是若输出 0 为RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC且类型不是 FP16则is_quant true后续后处理按量化数据解码。RV1106/1103 的专用实现 examples/yolov7/cpp/rknpu2/yolov7_rv1106_1103.cc 则使用**零拷贝zero-copy**接口rknn_query(RKNN_QUERY_NATIVE_INPUT_ATTR / RKNN_QUERY_NATIVE_NHWC_OUTPUT_ATTR)获取原生属性通过rknn_create_memrknn_set_io_mem直接绑定 DMA 内存输入默认设为RKNN_TENSOR_UINT8RKNN_TENSOR_NHWC1106 NPU 零拷贝模式仅支持 NHWC。6.2 三种输出类型的解码实现examples/yolov7/cpp/postprocess.cc 针对不同平台和量化类型提供了三套解码函数process_fp32浮点输出直接按x*2-0.5、(x*2)^2*anchor解码置信度阈值直接比较浮点数process_i8/process_u8量化输出先用qnt_f32_to_affinei8或qnt_f32_to_affine_u8u8把阈值转换到量化域再比较命中后通过deqnt_affine_to_f32反量化出浮点坐标与得分process_i8_rv1106针对 RV1106 的 NHWC 内存布局h*w*align_c每格 3 锚点 × 85 通道按 hw 连续排列单独实现遍历。解码公式与 Python 版box_process完全一致box_x (x*2-0.5 grid_x) * stride、box_w (w*2)^2 * anchor_w随后转为[x1, y1, x2, y2]。锚点表硬编码在postprocess.cc中anchor[3][6]值与model/anchors_yolov7.txt一一对应const int anchor[3][6] {{12,16,19,36,40,28}, {36,75,76,55,72,146}, {142,110,192,243,459,401}};后处理主函数post_process按输出层遍历RKNPU2 平台取output_attrs[i].dims[2]/dims[3]作为grid_h/grid_wstride model_in_h / grid_hRKNPU1 平台因 NCHW 维度反转为 WHCN取dims[1]与dims[0]。解码出的候选框按得分降序排列后对每个类别分别执行 NMSCalculateOverlap计算 IoU阈值默认NMS_THRESH 0.45最后结合letterbox的x_pad/y_pad/scale将坐标映射回原图置信度阈值默认BOX_THRESH 0.25定义在 examples/yolov7/cpp/postprocess.h最大输出框数OBJ_NUMB_MAX_SIZE 128。类别名由coco_80_labels_list.txt在init_post_process时加载80 类 COCO与 Python 版CLASSES元组一致。7. 预期运行结果以model/bus.jpg为测试图C/Python Demo 会打印检测类别及对应得分形如person (212 241 285 511) 0.886 bus (86 134 540 444) 0.855 person (476 237 561 519) 0.835 person (112 234 218 531) 0.835 person (79 330 124 524) 0.346检测结果可视化如下C Demo 输出out.pngPython Demo 输出./result/*.png注意不同平台、不同版本的 rknn-toolkit 工具链与 NPU 驱动量化推理结果可能存在轻微差异属正常现象若追求更高精度可改用fp类型不做量化转换模型对比验证。8. 常见问题与调优建议量化精度不理想确认convert.py的校准数据集是否覆盖真实使用场景可替换DATASET_PATH指向更贴近业务分布的图片列表或改用fp类型对比精度上限。检测框偏移检查是否使用了仓库提供的优化版 ONNX输出为[1,255,H,W]通道合并格式官方原始模型的输出布局[1,3,H,W,85]与本文后处理解码方式不兼容。RV1106 平台异常RV1106 仅支持 i8 量化且推理输入输出必须使用 DMA 分配的缓冲区见 main.cc 中dma_buf_alloc分支请按 CMake 的TARGET_SOCrv1106/rv1103分支编译。RKNPU1 平台rk1808/rv1109/rv1126量化 dtype 使用u8而非i8转换与推理时平台参数需与模型实际编译平台严格一致。以上流程覆盖了从模型获取、结构优化、量化转换到双端推理的完整闭环可作为在 rknn_model_zoo 中移植其他 YOLO 系列检测模型如 yolov5、yolov8的参考基线。赞分享示例工程人工智能嵌入式边缘计算计算机视觉模型优化【免费下载链接】rknn_model_zoo项目地址https://gitcode.com/gh_mirrors/rk/rknn_model_zoo点击查看免费下载相关推荐qiankun 流式 HTML 入口加载器 qiankunjs/loader 演进全解从流式写入到容器占位门控qiankun 流式 HTML 入口加载器 qiankunjs/loader 演进全解从流式写入到容器占位门控 导读 本文以 qiankunjs/loa示例工程人工智能嵌入式边缘计算计算机视觉模型优化基于 rknn_model_zoo 的 MMS-TTS 端侧语音合成部署指南VITS 模型 ONNX 导出、RKNN 转换与 Android/Linux Demo 实战基于 rknn_model_zoo 的 MMS TTS 端侧语音合成部署指南VITS 模型 ONNX 导出、RKNN 转换与 Android/Linux De示例工程人工智能嵌入式边缘计算计算机视觉模型优化CANN ops-transformer 中的 aclnnNsaCompressAttentionInferNSA 推理阶段 Compress Attention 算子详解与调用指南CANN ops transformer 中的 aclnnNsaCompressAttentionInferNSA 推理阶段 Compress Attenti示例工程人工智能嵌入式边缘计算计算机视觉模型优化上一篇bup社区活动日历参与线上meetup与黑客马拉松下一篇MoneyPrinterTurbo终极指南从零开始3分钟打造爆款短视频的完整教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表