ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLOv8+RK3588端侧部署全流程:环境搭建、数据准备与模型训练

YOLOv8+RK3588端侧部署全流程:环境搭建、数据准备与模型训练 1. 整体方案选型为什么是 YOLOv8 RK3588 RKNN1.1 为什么选择YOLOv8作为检测模型先说结论YOLOv8不是每一项目最先进的选择但它是从“算法验证”到“端侧落地”之间路径最顺、坑最少的选择之一。YOLO系列走到今天已经从最早的v1迭代到v8甚至v9、v10、v11。单看精度YOLOv8并不总占优某些场景下YOLOv5的成熟生态甚至更好用部分新版本的单模型精度也能压v8一头。但做嵌入式部署的人最怕什么怕的是模型训得漂漂亮亮转换工具链却死活不认或者导出过程出现一堆不兼容问题。YOLOv8背后的Ultralytics团队把这方面处理得相对干净从训练到导出ONNX再到对接RKNN工具链每一步都有大量可参考案例。工程化的意义在于“确定性”而不只是“极限性能”这一条在嵌入式场景里比什么都重要。再从算法结构上看YOLOv8相比老版本有几个明显的改动它转成了anchor-free检测方式不再需要预设anchor框主干部分引入了C2f模块信息流动更充分检测头换成了解耦头结构分类和回归分支分开收敛更快。这些改动带来的好处是训练调参的门槛降低了、收敛稳定性更好同时也让导出的模型结构相对规整对后续RKNN导出阶段的算子映射更加友好。实测下来同样的数据集v8s的mAP往往能和v5m打成平手但模型体积和推理速度反而更占优。还有一个很实际的原因Ultralytics这个训练框架对新手友好到几乎“无脑”。一条命令就能训练、验证、导出能少写大量中间代码。这一点在前期快速验证方案可行性时尤其加分。1.2 RK3588和RKNN工具链的能力边界RK3588是瑞芯微的旗舰级SoC集成了一颗6 TOPS算力的NPU。这个数字在今天的端侧AI芯片里不算夸张但它的优势在于整个平台的外围能力——8核CPU、高性能GPU、丰富的外设接口适合做完整的智能硬件产品而不只是跑一个模型。如果你只是需要跑YOLOv8做目标检测这颗NPU跑v8s的量化模型大致能做到几十毫秒级别足够应对大部分实时视频流分析的场景。要把模型跑到这块NPU上绕不开瑞芯微的工具链RKNN。目前主流的部署链路是PyTorch训练产出.pt权重先导出为ONNX中间格式再用RKNN-Toolkit2将ONNX转换成RKNN格式最后在板端通过RKNN Runtime API调用推理。这个链路里ONNX是承上启下的关键节点也是模型转换出问题最集中的环节。这里想特别提醒一个经常被忽视的点训练阶段的很多操作会影响后面RKNN转换的顺利程度。比如上采样算子、NMS后处理是否集成在模型里、某些自定义层的写法是否导出友好。如果训练时完全不考虑部署等到模型训完再做转换很可能被某个算子卡住返工成本极高。所以做嵌入式AI项目训练之前就要把部署链路想清楚这是项目成败的分水岭。1.3 训练环境选型Ubuntu 20.04 CPU版是否可行这次项目环境选择的是Ubuntu 20.04。原因不复杂Ubuntu 20.04是当前RKNN-Toolkit2、ROS等工具链兼容性最稳妥的版本网上能搜到的踩坑记录也最丰富。虽然Ubuntu 22.04甚至24.04都已发布多年但很多嵌入式工具链的预编译包仍以20.04为主没必要在环境上追求新版本给自己平添麻烦。至于CPU版本能不能训练YOLOv8答案是能跑但要有心理预期。如果你的数据量只有几百张、训练几轮只为验证流程CPU完全够用。但如果数据量上千张、模型选择的是v8m或v8l、epochs设置到一两百CPU版本的训练时间会膨胀到不可接受的地步。我自己实测过一张RTX 3060训练v8s约0.3-0.5小时/100轮的数据量CPU可能要慢20倍以上。所以环境搭建部分我会把CPU和GPU两种方式都讲一遍你根据自己的硬件情况取舍。核心目标是先把流程走通把数据准备和训练逻辑搞清楚模型训练本身反而可以后续再找GPU环境大规模跑。2. 环境搭建Ubuntu 20.04 下把 YOLOv8 训练环境跑通2.1 创建独立的Python虚拟环境很多人装环境习惯直接在系统Python里pip install一把梭后期包版本冲突时悔得肠子都青了。做AI训练项目虚拟环境是基本功强烈建议从一开始就养成习惯。Python版本建议选择3.8到3.10之间。Ultralytics对Python版本的要求并不苛刻但PyTorch在某些新Python版本上的预编译包可能滞后选3.8/3.9/3.10最稳妥。我自己倾向于用3.8因为RKNN-Toolkit2在3.8上的兼容性记录最好后续部署环节不用切换环境。# 使用conda创建虚拟环境 conda create -n yolov8 python3.8 conda activate yolov8 # 如果没装conda也可以用python自带的venv python3 -m venv yolov8_env source yolov8_env/bin/activateconda和venv选哪个如果只是训练venv够了。但你的后续工作流里如果涉及其他工具链conda的环境管理更灵活依赖冲突的处理成本低很多。RKNN-Toolkit2安装时依赖一堆库conda环境能少不少麻烦。装完Python环境后顺手把pip源换成国内镜像。这个操作能省你大量等待时间pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple2.2 安装PyTorch与Ultralytics训练框架PyTorch的安装分为CPU版和GPU版命令有区别别搞混。CPU版安装最简单PyTorch官方源直接装# CPU版本 pip install torch torchvisionGPU版要注意CUDA版本的匹配。安装前先确认你的显卡驱动支持的CUDA版本用nvidia-smi命令可以查看。比如显示CUDA Version: 12.1那安装CUDA 11.8或12.1的PyTorch都没问题但别选太高。# GPU版本以CUDA 11.8为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118安装完一定要验证一下GPU是否真的可用。这一步很多人跳过后面训练时报错才发现装的是CPU版浪费大量时间。import torch print(torch.__version__) print(torch.cuda.is_available()) # True才说明GPU可用 print(torch.cuda.get_device_name(0))Ultralytics安装更简单一行命令pip install ultralytics这个命令会顺带把opencv-python、numpy、matplotlib等常用依赖装上省去你一个个手动装的麻烦。装完后用一下命令验证yolo predict modelyolov8n.pt sourcebus.jpg如果能看到检测结果输出说明环境OK。2.3 环境验证的坑提前踩给你看环境搭建阶段最容易出问题的在三处第一GPU版PyTorch装完torch.cuda.is_available()还是False。这是最常见的坑大概率是CUDA驱动和PyTorch的CUDA版本不匹配。先看nvidia-smi里的驱动版本再看PyTorch官方文档对应的CUDA版本要求。别随手装最新版PyTorch稳定版最靠谱。第二pip install ultralytics后命令行找不到yolo。这一般是Python的Scripts目录没加到PATH里。检查一下虚拟环境的bin目录是不是在PATH中或者直接用python -m ultralytics调用。第三显存不足报错。如果电脑只有4GB显存直接用默认参数训练yolov8s可能直接OOM。先用yolov8n跑通或者调低batch size别一上来就追求大模型。提示环境搭建追求的是“确定性”不是“最新”。所有组件的版本在项目开始时固定下来后面出问题才好排查。3. 准备自有数据集从标注到YOLOv8格式3.1 训练数据采集与标注的关键细节很多人拿到项目第一件事就是闷头标注。我的建议是先确定检测目标、场景和相机位置再开始采数据。举个例子如果要做工厂车间的安全帽检测相机的安装高度、角度、光线条件会直接决定模型最终表现。训练数据和实际部署场景差异过大模型的精度再高也是废的。数据采集时尽量覆盖不同光照、不同距离、不同角度、不同遮挡情况。宁可先少来点把多样性做够再根据验证集的badcase补数据。一上来采几千张高度雷同的图片标注费时费力对模型泛化能力却没有帮助。标注工具我用过LabelImg和Labelme最终还是更倾向Labelme。原因很简单Labelme默认输出JSON格式信息完整二次处理灵活而且它导出COCO格式也方便后面如果要做实例分割还能复用。LabelImg的老版本对Python 3.10支持不太友好配置环境挺折腾。标注的操作流程不复杂打开图片沿目标边缘画框或画多边形给每个目标打上对应类别标签保存后生成同名JSON文件标注过程中我的经验是边界框略紧不略松宁可小一点不要框进去大量背景。背景信息框得多了模型容易学偏。另外类别的命名尽量全英文小写不要带空格方便后面处理。3.2 标注格式转换成YOLOv8需要的格式Labelme生成的JSON格式不能直接用于YOLOv8训练需要转换成YOLO格式的TXT文件。YOLO格式的标注是这样的class_id center_x center_y width height注意这四个坐标值都是相对于图片宽高的归一化值范围在0到1之间。每行对应一个目标框。转换脚本不复杂核心逻辑如下import json import os def labelme_to_yolo(json_path, save_dir, class_names): with open(json_path, r, encodingutf-8) as f: data json.load(f) img_w data[imageWidth] img_h data[imageHeight] txt_name os.path.splitext(os.path.basename(json_path))[0] .txt txt_path os.path.join(save_dir, txt_name) with open(txt_path, w) as f: for shape in data[shapes]: label shape[label] if label not in class_names: continue class_id class_names.index(label) points shape[points] x_min min(p[0] for p in points) y_min min(p[1] for p in points) x_max max(p[0] for p in points) y_max max(p[1] for p in points) center_x (x_min x_max) / 2 / img_w center_y (y_min y_max) / 2 / img_h width (x_max - x_min) / img_w height (y_max - y_min) / img_h f.write(f{class_id} {center_x:.6f} {center_y:.6f} {width:.6f} {height:.6f}\n)这里要注意Labelme画的是多边形坐标点不一定正好是正方形框的四个角需要自己计算外接矩形。上面的代码已经做了这个处理。3.3 数据集目录结构与YAML配置文件YOLOv8训练时要求的数据集目录结构是这样的dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yaml图片和标签文件名必须一一对应图片在images/train/下的文件名是001.jpg对应的标注文件就必须是labels/train/001.txt。目录名错了、文件名对不上训练时会直接报错或者静默跳过查起来很头疼。train和val的划分比例常见做法是8:2或者9:1。划分的时候要注意同一场景的相似图片尽量放在同一个集合里避免数据泄露导致验证结果虚高。我自己还会保留一部分test集不参与训练和验证等整个流程跑完再做最终评估。这个习惯能帮你发现模型是否真的泛化而不是只对验证集好。data.yaml文件是告诉YOLOv8去哪儿找数据、有几个类别、类别名字是什么train: /path/to/dataset/images/train val: /path/to/dataset/images/val test: /path/to/dataset/images/test nc: 2 names: [helmet, person]注意train和val的路径只写到images目录不要写到labels。Ultralytics会自动根据images路径推导labels路径规则是把images替换为labelstrain/val子目录保持不变。很多人在这里写错导致训练时提示找不到labels文件。3.4 数据质量检查与可视化验证标注完成、目录搭好之后不要急着训练。先做一次可视化检查把标注框画到图片上看一遍能发现很多肉眼不易察觉的问题。Ultralytics提供了一条命令做数据检查yolo train datadata.yaml modelyolov8s.yaml epochs0跑完之后会在runs/detect/train/目录下生成Btrain_batch*.jpg图片上面画了增强后的图片和标注框。检查一下有没有漏标、错标、框偏移严重的情况及时修正不要直接开训。这一步花费的时间很少但能避免你浪费数小时去训练一个数据有问题的模型。4. 训练模型跑通YOLOv8s训练流程4.1 预训练模型选择与训练参数设置数据准备好了模型架构和参数怎么定YOLOv8按尺寸分n、s、m、l、x五个档每档的精度和速度不同。嵌入式部署场景我的建议是从YOLOv8s开始。n太小精度损失可能不可接受m以上的模型在RK3588上虽然也能跑但推理帧率会明显下降做实时应用压力大。先用s跑通整个流程后续再根据端侧实测帧率决定是否上m或者降级到n。训练前要确定的参数有这几个epochs迭代轮数。小数据集几百张图建议从100轮起步参考早停机制判断是否收敛。batch批量大小。取决于显存8GB显存跑v8s建议8-16CPU版建议4甚至更低。imgsz输入图片分辨率。训练和后续部署保持一致很重要。我用的是640这也是YOLOv8的默认值。如果你要追求速度后面量化部署时可以把输入分辨率降到416甚至320但训练阶段先保持640留出调优空间。device0表示使用第一块GPUcpu表示纯CPU训练。训练命令很简单yolo train datadata.yaml modelyolov8s.pt epochs100 batch8 imgsz640 device0这里用yolov8s.pt作为预训练权重。注意不是yolov8s.yaml前者会加载COCO上的预训练权重做迁移学习收敛速度和最终精度都远好于从零训练。只有你的任务和COCO差异极大、或者你明确要做随机初始化时才用yaml配置。4.2 训练过程中的核心监控指标训练启动后终端会实时打印loss值和mAP指标。新手可能一看到loss不降就慌这里给一个参考经验box_loss是边界框回归损失通常会在前20轮快速下降之后缓慢收敛cls_loss是分类损失和你的类别数、数据质量关系大不会掉到0稳定在一个小值就可以。关注val/box_loss和val/cls_loss的变化趋势比死盯训练loss更有意义。验证loss持续下降说明模型在真正学习泛化特征如果训练loss还在降、验证loss开始回升就是过拟合的信号可以提前停。训练完成后在runs/detect/train/目录下会生成results.png画了所有loss曲线和mAP曲线。还有一个混淆矩阵和PR曲线这些图在后续做模型评估和优化时都是重要的参考依据。想更精细地监控训练过程可以装TensorBoardpip install tensorboard yolo train ... projectmy_project nameexp1 tensorboard --logdir my_project浏览器打开localhost:6006就能看实时曲线比盯着终端输出强多了。4.3 训练结果评估与权重文件管理训练正常结束时runs/detect/train/weights/目录下会生成两个文件best.pt和last.pt。best.pt是验证集指标最优的权重last.pt是最后一轮的权重。两者差别可能很大。训练后期如果出现过拟合last.pt可能比best.pt差很多。导出和部署时默认用best.pt别搞错。评估模型效果直接看验证集上的mAP0.5和mAP0.5:0.95。前者是IoU阈值0.5下的平均精度后者是0.5到0.95多个阈值下的平均精度。mAP0.5在实际工程中更有参考价值它比较贴近“能不能检测到这个目标”的直观感受。mAP0.5:0.95更严格适合对定位精度要求高的场景。评估命令yolo val modelruns/detect/train/weights/best.pt datadata.yaml输出会告诉你每个类别的precision、recall和mAP逐类看一遍能发现哪些类别是短板。如果一个类别的检测效果明显差于其他类别大概率是数据量不足或者场景覆盖不够补充对应场景的数据往往比调整模型参数更有效。4.4 训练阶段的坑与避坑经验训练过程中有几个高频问题提前说下省得你踩了再搜。第一个是训练时loss异常变大或不收敛。先检查数据标注是不是有误很多情况是某个标注框坐标超出图片边界、或者类别ID和names列表不对应导致的。用前面提到的可视化检查方法查一下。第二个是过拟合严重。训练loss收敛得很好验证loss却高得离谱。解决思路依次是增加数据量、加大数据增强、缩小模型尺寸、加早停机制。不要一上来就调学习率先把数据层面的问题排查干净。第三个是batch size和learning rate的联动关系。batch太小学习率要相应调低。如果你用的是默认学习率0.01但batch只有4大概率震荡不收敛。小数据集上我习惯手动改为0.001启动稳定很多。第四个是训练速度过慢。CPU训练几百张图、100轮可能要跑一整天这个很正常。如果只是想验证流程可以把epochs临时调低到5轮确认一切正常后再拉长。不要一上来就设置300轮然后干等有问题早点暴露。注意训练阶段的目标是拿到一个“能交付给部署环节”的模型而不是盲目追求刷新精度。模型再准转不到RKNN、跑不动实时推理都是白搭。5. 为端侧部署提前做的准备与常见问题速查5.1 训练时就要为RKNN转换保留的“后路”部署的完整链路是best.pt导出为ONNX再用RKNN-Toolkit2转成RKNN格式最后在板端用RKNN Runtime推理。训练阶段的某些选择直接影响后面这两步是否顺利。第一个要注意的是模型的检测输出。YOLOv8原始模型输出三个尺度的特征图后处理包括decode、NMS都不包含在模型内部需要我们自己写。训练后导出ONNX时默认导出结果就包含了这三个输出张量后续在RKNN上推理时需要分别处理。也有一种做法是把后处理直接写进模型里导出时带上NMS模块但RKNN工具链对NMS算子的支持不太好实际部署时我建议不要这么做老老实实在板端写后处理可控性更高。第二个要注意的是算子的兼容性。YOLOv8的模型结构里有一些特殊算子导出ONNX后需要确认RKNN-Toolkit2是否支持。目前较新版本的RKNN-Toolkit2对YOLOv8的算子覆盖比较完整导出时遇到不支持的算子的概率不大但如果你在模型里加了自定义模块或注意力机制就要格外小心。我的建议是正式训练前先用一批极少量的数据训练个mini模型走一遍导出和转换链路确认没问题再大规模训练。这叫“提前做技术验证”比训完了发现转换不了再返工效率高太多。第三是输入分辨率。训练分辨率、导出ONNX时的输入分辨率、RKNN转换时的输入分辨率三者必须统一。如果训练用640、导出用416虽然也能跑但模型精度会打折扣因为输入尺寸变化导致特征图尺寸变化预训练学习到的特征分布可能不完全匹配。我踩过这个坑后来所有环节固定在640省心省力。5.2 常见问题速查表环境搭建、数据处理、模型训练这三个阶段的问题我做了一个速查表基本覆盖了我在项目中遇到的高频问题。阶段问题现象可能原因解决方案环境torch.cuda.is_available()为FalseCUDA版本与PyTorch不匹配检查nvidia-smi的CUDA版本重装匹配的PyTorch环境命令行找不到yolo命令Python Scripts目录不在PATH激活虚拟环境后重新安装或手动加PATH环境训练时显存不足(OOM)batch过大或模型过大调小batch或使用yolov8n小模型数据训练时提示找不到labels目录结构不对或路径写错按images/labels对应结构检查目录和data.yaml路径数据训练loss很大且不降标注坐标越界或类别ID错误可视化检查标注数据修正后再训练数据验证集效果好但实际效果差数据集划分存在数据泄露重新划分保证同场景图片在同一集合训练训练loss降但val_loss升过拟合增加数据/增强提前早停降低模型复杂度训练loss震荡不收敛学习率过大或batch过小降低学习率至0.001尝试训练训练速度极慢使用了CPU或GPU性能不足降低epochs验证流程后续换GPU训练这个表的核心思想就一句话先定位是环境问题、数据问题还是模型问题再对症下药。很多新手遇到问题就疯狂调参结果越调越乱。我的习惯是每次只改动一个变量确认问题解决后再动下一个这个方法在AI项目里尤其重要。5.3 本阶段完成后的下一步方向环境搭建好了、数据准备好了、模型训练跑通了这个阶段的核心闭环就算完成。接下来要面对的是模型从PyTorch格式到RKNN格式再到板端推理的全链路打通。这一步会接触ONNX导出、量化精度损失、板端API调用、推理性能调优等新问题每一步都有不少专门的门道。我个人在整个流程中最大的体会是嵌入式AI项目的时间分配写模型和调模型的代码其实只占一小部分大量时间都花在环境和工具链的兼容性排查上。所以这个系列的第一期我把环境、数据、训练这些“地基”部分的细节尽量讲透。地基打牢了后面的部署阶段才能少一些莫名其妙的坑。如果你也是第一次走YOLOv8到RK3588的链路建议严格按照这个顺序来不要跳步。环境用虚拟环境做好隔离数据准备阶段宁可多花一两天做检查和可视化训练阶段先用小参数量跑通流程再慢慢加码。把基本功做扎实整个项目推进的速度反而不会慢。
返回列表