1. 前言:当高性能边缘算力遇见新一代 YOLO26
在边缘计算与智能物联网(AIoT)领域,瑞芯微 RK3588 凭借其内置的 6 TOPS NPU、强大的多路视频处理能力以及极高的性价比,已经成为工业检测、智能安防等场景的骨干硬件。
随着 Ultralytics 发布新一代轻量化端到端检测器 YOLO26,目标检测在边缘端的落地迎来了新的变革。YOLO26 最大的特点在于其原生端到端(NMS-Free)的设计:模型直接输出固定数量(如300个)的候选框,省去了传统 YOLO 部署中极其消耗 CPU 的非极大值抑制(NMS)后处理步骤。
本文将手把手带你完成 YOLO26 在 RK3588 上的完整部署流程,涵盖 PyTorch 模型导出、RKNN 格式转换(FP16 高精度构建)、以及基于 rknnlite 的 Python 物理板卡推理。同时,本文还会重点分享在边缘端进行多分辨率图像预处理的映射算法(直接缩放与经典 Letterbox 填充),以及预防 NPU CMA 内存碎片化的优化技巧。
2. 核心对比:RKNN NPU 加密部署 vs 传统 Ultralytics CPU 推理
许多开发者在拿到 RK3588 后的第一反应是直接使用 pip install ultralytics 并跑在 CPU 上,或者使用 ONNX Runtime 的 CPU 模式。下表客观对比了这两种部署路径在实际工程中的表现:
| 评估维度 | 传统 Ultralytics CPU / ONNX CPU 部署 | 基于 RKNN 转换 + NPU (rknnlite) 部署 |
| 算力载体 | 仅依赖 ARM Cortex-A76/A55 CPU 核心 | 完整释放 6 TOPS NPU 硬件加速器 |
| 帧率(FPS) | 较低(通常个位数,CPU 容易过载) | 极高(可实现多路实时流畅推理) |
| 功耗与发热 | CPU 长期满载(100%),发热严重,容易因温度过高导致降频 | NPU 功耗极低(功耗通常仅为 CPU 满载时的几分之一),系统运行稳定 |
| 后处理开销 | 需在 CPU 端进行耗时的边界框筛选与 NMS 运算 | 结合 YOLO26 的 NMS-Free 特性,推理结果即为最终框,后处理只需简单过滤置信度,CPU 零负担 |
| 多线程支持 | 受限于 Python GIL 锁,多路并发时 CPU 性能劣化严重 | 可通过 RKNN 多实例绑定不同的 NPU 核心(RK3588 拥有 3 个独立的 NPU Core),轻松实现硬件级多路并发 |
| 长期运行稳定性 | 容易因 PyTorch/ONNX-runtime 的 Python 层垃圾回收滞后导致内存泄露 | 本教程提供了 CMA 连续物理内存的主动管理与释放方案,可确保系统 7x24 小时稳定运行 |
通过将 YOLO26 转换为 RKNN 格式并运行在 NPU 上,不仅能够将推理延迟降低几个数量级,还能腾出宝贵的 CPU 资源用于业务逻辑、推流或 GUI 交互。
当然,通过Ultralytics也能直接使用3588的npu进行推理,同时效率高于纯cpu推理,但是面临一个工程化的致命问题——无法指定模型加载的npu。
RK3588拥有6T的算力,但是6T算力是均分在三个npu上,每个npu仅有2Tops,而使用Ultralytics的YOLO推理底层虽然也使用到了rknnlite相关接口,但是并不能直接指定npu的使用。默认仅会使用第一个npu,导致无法同时加载多个模型、浪费另外两个npu,所以效率是远低于同时使用三个npu进行模型加载与推理。
三、全链条实战步骤与代码实现
整个部署流程可分为三个阶段:
[PC/开发机] 导出端到端 ONNX 格式;
[PC/开发机] 使用 RKNN-Toolkit2 将 ONNX 转换为 RKNN 模型;
[RK3588板卡] 使用 RKNN-Lite 驱动 NPU 进行高效推理。
1. 步骤一:PyTorch 权重导出为 ONNX (pt2onnx.py)
在你的深度学习训练环境(PC/服务器)中运行此脚本。为了保证算子兼容性,我们利用 ultralytics 库自带的 export 函数,同时设定指定的 opset 并启用简化功能。
# pt2onnx.py from ultralytics import YOLO # 1. 加载训练好的 YOLO26 权重模型 model = YOLO('weights/com/yolo26s_com.pt') # 2. 导出为 ONNX 格式 # simplify=True 用于自动简化 ONNX 计算图,合并多余算子 # opset=16 确保算子版本符合 RKNN 编译器的最佳解析标准 model.export(format='onnx', simplify=True, opset=16) print("ONNX 导出成功!")