
最近一直在折腾香橙派5 Pro起因其实很简单手头有一批YOLOv5模型要部署到边缘设备上需要实时处理摄像头画面。树莓派5虽然也能跑但CPU推理YOLOv5s只能到两三帧根本没法用。换到香橙派5 Pro之后情况完全不一样。这块板子用的是瑞芯微的RK3588S芯片自带6 TOPS算力的NPU配合YOLOv5做实时目标检测非常舒服。这篇东西是我从头到尾完整跑通一遍的实战记录包括环境搭建、模型转换、板端部署、踩坑复盘适合手里有RK3588系列板子、想把YOLOv5或者类似YOLO系列模型真正部署起来跑实时推理的朋友参考。整个流程走下来我的结论先说在前面RK3588的NPU跑YOLOv5sint8量化之后在640x640输入下能稳定跑到30到40帧这个性能对绝大多数边缘检测场景都够了。但这条路并不是装上rknn-toolkit跑一下就能通中间有不少细节坑尤其是ONNX导出和量化这两步很多人就是卡死在这里。这篇我会把每一个环节的具体操作和为什么这么做的逻辑都讲清楚。1. 整体方案为什么选RK3588 NPU跑YOLOv51.1 一块板子上的算力究竟在哪里香橙派5 Pro用的是瑞芯微RK3588S。这里有个容易混淆的点很多人说RK3588其实3588和3588S是同一颗NPU设计S版本在接口上做了一些裁剪但NPU部分完全一样都是三核设计总算力6 TOPS。这个6 TOPS是什么概念对于YOLOv5s这种规模的模型int8推理的算力需求大约在0.5到1 TOPS之间所以理论上RK3588的NPU跑YOLOv5s是绰绰有余的。需要注意的是这颗NPU只原生支持int4、int8、int16和fp16精度不支持fp32直接推理。这意味着我们训练好的PyTorch模型不能直接丢进去跑必须要经过格式转换和量化。很多第一次接触RK3588 NPU的朋友会在这里迷惑为什么不是把所有模型直接加载进去因为你手里的.pt文件是基于CUDA训练的指令集和NPU完全不一样必须转换成瑞芯微的私有的RKNN格式类似于NVIDIA的TensorRT引擎文件才能被NPU识别和执行。那么为什么不推荐用CPU或者GPU去跑YOLOv5CPU比如RK3588S的A76核心跑ONNX版本的YOLOv5s640x640输入单帧推理时间大概是300到500毫秒也就是2到3帧。GPUMali-G610理论上可以用OpenCL加速但YOLOv5对OpenCL的支持并不好很多算子跑不起来实际效果甚至不如CPU。NPU是专门为卷积神经网络设计的矩阵运算有硬件加速单元YOLOv5这种以卷积为主的目标检测模型正好是它的主场。所以如果你要在RK3588系板子上做实时目标检测NPU是唯一靠谱的路线。1.2 部署全链路从PyTorch到板端推理的四个跃迁我第一次部署的时候以为就是“把.pt转成.rknn然后load进去跑”结果根本不是这么简单。完整链路其实长这样第一步训练得到PyTorch权重.pt。这个可以在任何机器上完成和板子没关系。第二步用YOLOv5官方的export.py脚本把.pt导出为ONNX格式。这一步要特别注意opset版本和simplify处理因为RKNN工具链对ONNX算子的兼容性并不是100%一些很新的算子或者复杂结构会导致转换失败。第三步在宿主机一般是x86的Ubuntu机器上用rknn-toolkit2工具把ONNX模型转成RKNN格式。这一步通常还要做int8量化需要准备一个标注或未标注的图像数据集。第四步把生成的.rknn文件拷贝到香橙派5 Pro上安装板端runtimerknn-toolkit-lite2写推理脚本运行。整个链条里第一、二步是常规的深度学习工作流网上教程一大把第三、四步是瑞芯微体系的特有流程也是坑最多的地方。1.3 这套方案适合什么场景和人群如果你要做的是以下这类事情这个方案非常适合在边缘设备上做实时安全帽检测、人员闯入报警、车辆识别等安防类应用。想要在本地跑YOLOv5但要控制功耗和成本不想上带独显的工控机。研究RK3588 NPU的异构计算能力想评估它跑各类轻量模型的性能边界。如果你只想在板子上轻轻松松跑个Demo那可能直接用YOLOv5官方在CPU上推理就够了不需要这么复杂的部署流程。但如果你想真正上项目、追求帧率和低延迟NPU部署是绕不开的。前置知识方面你需要会基础的Linux命令、Python脚本对卷积神经网络和YOLO家族的输出结构有概念。不需要精通C因为Python API完全够用但如果你要做极致性能优化C API是加分项。2. 环境准备宿主机加板端缺一不可2.1 香橙派5 Pro的硬件配置与系统选择先说硬件。香橙派5 Pro官方参数是RK3588S处理器、8GB或16GB LPDDR4x内存、支持NVMe SSD和TF卡启动。我的建议是既然要做AI推理一定要用NVMe SSD来装系统不要用TF卡。原因有二一是TF卡的随机读写性能太差系统启动和Python依赖安装会奇慢无比二是NPU推理时如果有大量日志或图像缓冲写入TF卡会成为瓶颈。散热方面这个我必须强调RK3588S满载时发热非常可观跑NPU推理芯片温度轻松上70℃如果用的是原装小散热片分分钟过热降频推理速度直接掉一半。我自己的做法是加了一个主动散热风扇散热片选大一点的纯铝或铜底实测温度可以稳定在60℃以下。系统我推荐刷官方Ubuntu 22.04镜像或者Armbian。香橙派官方和Armbian社区对RK3588的支持都很成熟内核里已经包含了NPU驱动。刷完系统之后先确认NPU驱动是否正常。sudo cat /proc/rknpu/version如果输出类似RKNPU driver: v0.9.8这样的信息说明NPU驱动正常。这个命令在后续排查问题时会经常用到。2.2 宿主机用Docker优雅安装rknn-toolkit2模型转换这一步需要在x86宿主机上完成因为rknn-toolkit2虽然有Linux wheel包但依赖Numpy、OpenCV、Pillow等一堆库版本要求也很严直接pip install很容易把环境搞崩。我的建议是直接用瑞芯微官方提供的Docker镜像一条命令省去所有烦恼。瑞芯微在rknn-toolkit2的GitHub仓库里发布了多个版本的Docker镜像比如rknn-toolkit2:1.6.0这样的tag。拉取并进入容器的方式很简单docker pull rknn-toolkit2:1.6.0 docker run -it --name rknn_env \ -v $(pwd):/workspace \ rknn-toolkit2:1.6.0 /bin/bash注意要把你的模型目录挂载到容器里的/workspace这样宿主机和容器之间可以共享文件。进入容器后验证rknn-toolkit2是否正常导入python -c from rknn.api import RKNN; print(OK)如果能正常打印OK宿主机环境就搞定了。整个过程比手动创建conda环境要快得多也不会污染宿主机本身的Python环境。2.3 板端Runtime环境与Python依赖板端的部署不需要rknn-toolkit2这个重量级工具只需要一个轻量的runtime包叫rknn-toolkit-lite2。这个包在板子上安装之后会附带librknnrt.so的Python绑定Python脚本里from rknnlite.api import RKNN用的就是这个。安装方式有两种我推荐直接复制。如果板子和宿主机在同一局域网可以直接在板端pip安装pip install rknn-toolkit-lite2如果不想折腾网络也可以把whl文件拷贝到板子上离线安装。安装完之后测试导入python -c from rknnlite.api import RKNN; print(OK)另外板端还需要OpenCV和NumPy这些直接apt或pip安装就行。这里有一个小坑板端的Python环境最好是系统自带的Python 3.10不要用conda或者虚拟环境因为rknn-toolkit-lite2对Python版本有要求系统环境最省事。3. YOLOv5模型导出最容易被忽视但定生死的一步3.1 用自己的数据还是官方权重如果你只是想先跑通流程直接用YOLOv5官方仓库里的yolov5s.pt权重就可以。但如果你是部署自己训练好的模型一定要确认训练时用的YOLOv5版本。我强烈建议在YOLOv5 v6.0以上版本训练模型因为v6.0之后YOLOv5的输出结构是1x255x80x80、1x255x40x40、1x255x20x20三个特征图部署时做后处理解码就行。如果是v5.0以前的老版本输出可能带有一个额外的全连接层后处理逻辑完全不同RKNN工具链支持也不够好。另外导出前建议把模型的检测头结构保持默认不要自行修改输出层的拼接逻辑。RKNN的预编译工具链对YOLOv5的标准结构支持最好一旦你改了输出头的拼接方式后面做后处理时就会非常痛苦。3.2 导出ONNX的完整操作克隆YOLOv5仓库安装依赖后用官方export.py导出ONNX。git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt python export.py \ --weights yolov5s.pt \ --include onnx \ --opset 12 \ --simplify--opset 12这个参数很关键。RKNN工具链对ONNX算子支持最全的是opset 11到12不要为了“新”而选择opset 14甚至17。新版本ONNX引入的某些算子会让RKNN转换时报错需要你手动修改模型结构才能解决完全没有必要。--simplify选项会调用onnx-simplifier压缩模型结构把一些冗余的算子合并这对RKNN转换成功率有直接帮助。导出成功后会生成yolov5s.onnx可以用Netron打开查看。正常的YOLOv5 v6.0以上结构应该有一个输入节点1x3x640x640三个输出节点。如果输出节点数量不对检查一下模型版本和export脚本里的参数。3.3 预处理细节letterbox和归一化不能忘YOLOv5的预处理分为两步letterbox缩放图片到640x640然后除以255归一化。这个预处理在你自己的推理脚本和量化数据集的准备中都要保持一致否则模型推理出来的结果会离谱。letterbox是什么意思简单说就是把原图的长边缩放到640短边等比缩放后用灰色填充到640。这个细节非常容易出错尤其是后续板端推理时如果遗漏了letterbox或者填充比例不对检测框的位置会整体偏移。RKNN的Python API在板端推理时不会自动做letterbox需要我们自己在代码里实现。后面部署部分我会给出完整代码。3.4 一个重要的认知NPU输出的是特征图不是检测结果新手最容易犯的错误是以为模型输出直接就是(x1, y1, x2, y2, score, class)的检测框列表。实际上YOLOv5 ONNX模型的输出是三个原始特征图分别对应80x80、40x40、20x20的网格每个网格点有255个通道85x3这里的85是x, y, w, h, objectness以及80个类别的概率。要在NPU拿到特征图之后自己程序里做解码和NMS。这其实也是RKNN工具链下部署的一大特点后处理部分完全由开发者自己完成。好在YOLOv5官方后处理逻辑不算复杂而且rknn_model_zoo里提供了可以直接参考的Python实现抄过来改改就能用。4. RKNN模型转换核心环节与量化博弈4.1 编写模型转换脚本进入rknn-toolkit2的Docker容器在源码目录下新建一个convert.py写入以下转换脚本from rknn.api import RKNN def main(): rknn RKNN(verboseTrue) # 1. 配置模型输入与量化参数 rknn.config( mean_values[[0, 0, 0]], std_values[[255, 255, 255]], target_platformrk3588 ) # 2. 加载ONNX模型 ret rknn.load_onnx(modelyolov5s.onnx) assert ret 0, load_onnx failed # 3. 构建RKNN模型 ret rknn.build(do_quantizationTrue, datasetdataset.txt) assert ret 0, build failed # 4. 导出RKNN模型 ret rknn.export_rknn(yolov5s.rknn) assert ret 0, export failed # 5. 释放资源 rknn.release() if __name__ __main__: main()这个脚本看着简单但里面的参数都有讲究。mean_values和std_values是图像归一化参数。YOLOv5训练的默认预处理就是像素值除以255所以mean填0std填255就是x/255的效果。这个必须和YOLOv5训练时的归一化保持一致如果填错模型推理的置信度会全线崩塌。target_platform指定目标平台为rk3588。如果你用的是rk3588s也填rk3588工具链会生成适配RK3588系列NPU的模型。填错了平台模型即使构建成功在板端加载时也可能报“model is not compatible”的错误。4.2 量化数据集怎么准备do_quantizationTrue表示做int8量化。量化过程其实就是一个校准过程工具链会拿你提供的图片数据集统计每个特征层的数值分布范围然后根据这个范围把浮点数映射到int8的整数区间。如果数据集没有代表性比如全是纯色图或者和你的实际场景差异巨大量化的数值范围就会失真最终推理精度会惨不忍睹。所以dataset.txt的每一行应该是图片的绝对路径或相对路径这些图片最好能覆盖实际场景中的各种情况。图片数量不需要太多我一般用200到300张。图片尺寸无所谓工具链会自动缩放但最好是接近实际输入尺寸。dataset.txt的内容示意/data/coco_sample/000001.jpg /data/coco_sample/000002.jpg /data/coco_sample/000003.jpg ...这里有一个坑我踩过一次不要复制粘贴一个包含上千张图片的巨型数据集来做量化。量化校准只需要有代表性的几百张就足够了图片太多会显著增加build的时间而且对精度提升没有帮助。另外量化时如果发现模型在板端检测效果不好可以尝试将build里的do_quantization改为False生成一个fp16的RKNN模型。fp16模型在RK3588 NPU上也是支持的精度完胜int8代价是推理速度会慢一些但相比CPU仍然是质的飞跃。4.3 转换失败怎么办转换过程中最常见的错误是E RKNN: Cannot find a valid layout for the given input或者某个算子不支持。遇到这类问题第一优先级是检查ONNX的版本和简化程度。重新跑一遍export.py确保用了simplify。如果还不行可以用onnx-simplifier独立跑一遍python -m onnxsim yolov5s.onnx yolov5s_sim.onnx然后用yolov5s_sim.onnx重新转换。如果仍然报错就需要查一下具体是哪个算子不支持。rknn-toolkit2的verbose输出会给出Layer信息根据报错信息到GitHub的Issues里搜绝大多数情况都能找到解法。还有一个小技巧rknn.config里有一个custom_allocator参数在某些报错场景下可以开启或关闭做测试。4.4 转换完怎么验证精度RKNN构建好之后可以在宿主机上先用板端相同的runtime做模拟推理验证输出是否正常。rknn-toolkit2提供了accuracy_analysis功能rknn.load_rknn(yolov5s.rknn) rknn.init_runtime() rknn.accuracy_analysis(inputs[test.jpg], output_dir./analysis)这个功能会把ONNX模型的输出和RKNN模型的输出做一个逐层对比输出每个层的余弦相似度。如果某些层的相似度特别低说明量化掉精度严重需要检查mean/std或数据集。5. 板端部署让YOLOv5真正跑起来5.1 Python API推理脚本完整可运行假设现在yolov5s.rknn已经在香橙派5 Pro上把后处理代码也准备好。这里我给出一个可以直接跑的Python推理脚本框架。import cv2 import numpy as np from rknnlite.api import RKNN CLASSES [person, bicycle, car, ...] # 自己的类别列表 def letterbox(img, new_shape(640, 640), color(114, 114, 114)): shape img.shape[:2] r min(new_shape[0] / shape[0], new_shape[1] / shape[1]) new_unpad (int(round(shape[1] * r)), int(round(shape[0] * r))) dw (new_shape[1] - new_unpad[0]) / 2 dh (new_shape[0] - new_unpad[1]) / 2 top, bottom int(round(dh - 0.1)), int(round(dh 0.1)) left, right int(round(dw - 0.1)), int(round(dw 0.1)) img cv2.resize(img, new_unpad, interpolationcv2.INTER_LINEAR) img cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, valuecolor) return img def main(): rknn RKNN() rknn.load_rknn(yolov5s.rknn) rknn.init_runtime() img cv2.imread(test.jpg) img_letterbox letterbox(img) img_input img_letterbox.astype(np.float32) / 255.0 img_input np.expand_dims(img_input, axis0) # 形状: 1x640x640x3NPU输入NHWC outputs rknn.inference(inputs[img_input]) # 对三个输出层分别做解码再合并、NMS # 具体解码逻辑可以参考YOLOv5官方后处理或rknn_model_zoo rknn.release() if __name__ __main__: main()这里有一个很容易被忽略的点rknn.inference输入的张量shape是1x640x640x3也就是NHWC布局不是PyTorch里的NCHW。YOLOv5训练时是CHW但RKNN工具链在转换时通常已经帮你插入了transpose节点所以输入到NPU的tensor布局是NHWC。这个转换是自动的但你要保证自己喂进去的numpy数组确实按照NHWC排列不然推理结果完全错误。5.2 输出解码和NMS的处理YOLOv5的每个特征图输出形状是1x255x80x80注意RKNN的输出仍然是NCHW。你需要把每个特征图reshape成3x85x80x80然后做一个通道维度的转置变成3x80x80x85再reshape为(3 * 80 * 80, 85)。这个转置操作如果封装不好在纯Python里跑会非常慢。我的建议是使用NumPy的transpose操作一次搞定out outputs[i].reshape(1, 3, 85, grid_size, grid_size) out out.transpose((0, 1, 3, 4, 2)) # 变为 1, 3, grid, grid, 85 out out.reshape(-1, 85)然后按照YOLOv5标准解码方式用sigmoid处理objectness和class prob加上anchor和stride还原出检测框坐标。NMS可以直接用cv2.dnn.NMSBoxes速度还不错甚至可以用PyTorch版的torchvision.ops.nms如果板子上装了PyTorch。5.3 摄像头实时推理与性能模式要做实时摄像头推理思路很简单开一个线程读取摄像头帧主线程做NPU推理和后处理。这里要特别注意不要用cv2.VideoCapture.read()阻塞推理线程因为摄像头帧率通常是30fps但NPU推理可能要30到50毫秒read的阻塞会让整个流水线卡顿。我推荐用这种方式class VideoStream: def __init__(self, src0): self.cap cv2.VideoCapture(src) self.ret False self.frame None self.stopped False self.thread threading.Thread(targetself.update, args()) self.thread.daemon True self.thread.start() def update(self): while not self.stopped: self.ret, self.frame self.cap.read() def read(self): return self.ret, self.frame推理主循环里每次从VideoStream取帧做letterbox、归一化、inference、后处理、显示。这样可以保证摄像头采集和推理是两个独立线程互相不阻塞。另外RK3588的NPU默认是普通模式可以开启性能模式来提升推理速度echo performance /sys/class/misc/rknpu/device_power这个操作会把NPU的频率拉满功耗会上升但帧率能提升10%到20%。如果设备是电池供电不建议长期开启实测温度会明显升高。6. 性能实测各种模型在RK3588 NPU上的表现6.1 测试结果一览我自己在香橙派5 Pro上跑了几个常见配置测试条件是系统Ubuntu 22.04Python 3.10rknn-toolkit-lite2 1.6.0输入尺寸640x640单batch。模型精度推理耗时毫秒帧率FPS备注YOLOv5sint8约25ms约40最佳性价比YOLOv5sfp16约45ms约22精度高速度慢YOLOv5mint8约45ms约22精度更好速度下降明显YOLOv5nint8约15ms约65轻量场景首选这个耗时包含了NPU推理时间不包含前置的图像缩放和letterbox也不包含后处理NMS。如果完整体验全流程YOLOv5s int8的端到端耗时大约在35到40毫秒依然能跑到25到30帧。6.2 影响性能的几大因素第一个因素是输入分辨率。640x640是官方推荐的输入如果你能接受降低小目标检测精度可以尝试用512x512甚至416x416输入推理耗时能减少40%。但要注意YOLOv5模型训练时的输入尺寸和部署时最好一致否则会掉精度。如果你在训练时用的是640部署时改成416小目标的检测效果会明显下降。第二个因素是后处理效率。我见过很多人在板端部署后处理写得很随意每个框都遍历大量无效网格导致后处理耗时超过NPU推理耗时纯纯的浪费。建议后处理时用向量化NumPy操作或者直接借用YOLOv5官方在推理时使用的非极大值抑制代码。第三个因素是内存分配。rknn.init_runtime有一个async_mode参数默认是False。如果设为Truerknn.inference会变成异步调用你可以把上一帧的后处理和这一帧的推理重叠起来流畅度会更好。代价是代码复杂度上升建议等基础流程跑通后再优化。6.3 对比CPU推理到底快了多少作为对照组我在香橙派5 Pro上用onnxruntimeCPU执行跑了同一个YOLOv5s ONNX模型640x640输入单帧耗时大约是350毫秒也就是不到3帧。NPU int8推理25毫秒速度是CPU的14倍。这个对比足够说明问题在RK3588平台上做YOLOv5推理NPU不是“锦上添花”而是真正的核心加速方案。如果不用NPU这块板子的AI性能基本荡然无存。7. 常见问题速查坑我都帮你踩过了7.1 转换阶段的报错错误信息原因解决方案E load_onnx failedONNX模型格式问题用onnx-simplifier重新简化检查opset版本E quantize failed量化数据集异常检查dataset.txt路径和图片完整性E The type of input tensor is not support输入形状不对确认模型的输入是动态还是静态最好导出时为静态shape1x3x640x640E Please set target_platform没有配置target_platformrknn.config中设置target_platformrk35887.2 推理结果不对画面全黑、全灰、或者检测框完全错乱这个问题的排查优先级最高的是输入预处理。先确认letterbox后图像是否是640x640。然后确认归一化是否正确YOLOv5是把像素值除以255你在板端推理时也要这样做不能直接喂0到255的uint8数组。其次确认输入tensor的shapeRKNN API要求是1x640x640x3如果你按1x3x640x640喂进去模型输出的结果肯定是乱的。检测框位置偏移通常是letterbox的填充尺寸没有正确记录导致后处理把坐标还原到原图尺寸时出错。我在代码里专门返回了(top, bottom, left, right)这些填充参数后处理解码后的坐标要减掉这些偏移量再除以缩放比例才能映射到原图。置信度很低几乎检测不到目标首先检查mean/std是否设错然后用fp16模型交叉验证如果fp16正常而int8不正常说明量化掉精度需要重建数据集重新量化。7.3 板端加载RKNN失败最常见的原因有两个一是模型转换时target_platform写错比如填了rk3566加载到rk3588上当然报错。二是rknn-toolkit-lite2和rknn-toolkit2的版本不匹配。转换时用的工具包版本和板端runtime版本要保持大版本一致比如都是1.6.0。瑞芯微在这个方面兼容性做得一般跨大版本加载模型有时候会直接挂掉。所以我的建议是宿主机Docker镜像版本和板端pip安装的rknn-toolkit-lite2版本一定在同一个版本号下。不要混用。7.4 性能达不到预期如果你的NPU推理耗时比预期高很多先检查是否开启了性能模式。然后在代码里打印一下推理耗时分布看看是rknn.inference慢还是图像预处理慢还是后处理慢。常见的情况是图像预处理尤其letterbox里的cv2.copyMakeBorder太耗时因为它在每次推理前都要执行。你可以把letterbox的尺寸计算提前缓存起来或者直接用固定尺寸缩放省掉copyMakeBorder。实测能省5毫秒左右。还有一点RKNN的inference API默认会做一次线程调度如果你追求极致性能可以把rknn.inference的data_format参数设成nhwc减少一次内存重排。8. 几个能让你省半天时间的实战心得最后分享几个我反复踩过坑后总结出来的经验。第一永远先把rknn_model_zoo里对应的YOLOv5 demo先跑通再去换自己的模型和代码。rknn_model_zoo是瑞芯微官方的模型仓库里面yolov5目录下包含了完整的Python部署代码和数据准备脚本后处理逻辑写得比我上面贴的示例完整得多。先跑通官方demo确认板子环境没问题再逐步替换成自己的.pt和.rknn这样排查问题会容易很多。第二每完成一个阶段就做一次备份。我自己习惯在香橙派5 Pro上装好系统、配置好全部依赖之后用dd命令或者官方工具做一个完整的系统镜像备份。这个习惯在后续反复刷机调试时救了我好几次。RK3588的系统不像树莓派那么耐折腾一旦某个依赖装错重装系统的成本很高。备份镜像可以让你随时回到一个干净可用的状态。第三如果你准备做连续视频流推理一定要做推理结果的时间戳与帧号对齐。RK3588的NPU推理是异步的如果你在读取摄像头帧后立刻把帧交给推理线程推理完成的帧可能已经落后于当前显示画面好几帧。在目标检测需要叠加到实时视频流的场景里这个延迟肉眼可见。解决方案是每帧推理前给帧打上序号后处理结束后按序号更新显示别直接用最新帧。第四把注意力花在后处理优化上往往比折腾NPU本身更有效。瑞芯微NPU的推理时间已经是硬性指标很难再压榨出大幅提升。但后处理里的NMS、坐标映射如果你写得好几毫秒的差距轻轻松松这在追求帧率稳定性时非常关键。我的经验是先用Python版本跑通全流程之后再决定要不要用C扩展重写后处理。对于边缘部署的正式项目后处理用C是值得考虑的性能提升非常可观。这条部署路线并不复杂但涉及的知识点确实多。希望这篇实战记录能帮你少走一些弯路在香橙派5 Pro或者任何RK3588板子上顺利把YOLOv5跑起来。