ARTICLE DETAIL

资讯详情

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

DAMO-YOLO实战:从训练调参到TensorRT部署全流程

DAMO-YOLO实战:从训练调参到TensorRT部署全流程 1. 为什么DAMO-YOLO值得单独拿出来聊目标检测这个圈子过去五六年基本是YOLO系列的天下。从YOLOv3开始每隔一段时间就有新版本刷榜大家一边追新一边吐槽精度上去了速度掉下来速度保住了小目标又漏检。工业界真正落地的时候往往不是选那个榜单第一的模型而是选那个在自家数据上“够准、够快、够好部署”的模型。阿里达摩院开源的DAMO-YOLO就是在这个背景下进入视野的。它没有走“堆参数换精度”的老路而是从网络结构搜索、重参数化、训练策略三个方向同时下手在COCO上做到了同精度下更快、同速度下更准。我第一次跑通它的推理脚本时最直观的感受是这玩意儿在T4上跑640分辨率吞吐量确实比同级别的YOLO变体要舒服而且导出ONNX之后部署链路很干净。这篇文章不打算复述论文而是从一个实际使用者的角度把DAMO-YOLO的核心设计、环境搭建、训练调参、部署落地、踩坑记录完整讲一遍。适合两类人看一类是想找一个能直接上生产的检测模型另一类是好奇它到底“超越”在哪里、值不值得从YOLOv5/v8迁移过来。全文基于我自己的实操记录和常见工程实践补充参数和步骤都可以直接抄。2. DAMO-YOLO整体设计思路拆解2.1 它到底“超越”在哪个维度很多人看到“超越一众YOLO”第一反应是精度又刷高了。实际上DAMO-YOLO的卖点更偏向精度-速度-部署成本这个三角的平衡。官方给出的对比里DAMO-YOLO-T在COCO上约42% AP推理速度比同精度YOLOv5-s快不少DAMO-YOLO-S在约46% AP时速度依然压着同级别对手。这个“同精度更快”比“同速度更准”在工程上更有价值因为产线往往卡的是延迟和吞吐。它做到这一点的核心手段有三个MAE-NAS骨干搜索、RepGFPN颈部结构、ZeroHead检测头。这三个词听起来唬人拆开看其实都是很务实的工程选择。2.2 MAE-NAS不靠人工堆叠靠搜索找骨干传统YOLO的骨干Backbone基本是人工设计的比如CSPDarknet。人工设计的问题是你很难穷举所有通道组合和层间连接方式。DAMO-YOLO用MAE-NAS一种基于最大熵原理的神经架构搜索方法去搜骨干搜索空间里包含卷积类型、通道数、层数、连接方式。搜出来的结构在同等FLOPs下特征提取能力更强。这里有个关键点NAS搜出来的结构往往“不规则”不像人工设计那样整齐。但DAMO-YOLO把搜出来的结构做了工程化整理保证它能在常见推理引擎上跑得动。这一点很重要我见过不少NAS模型论文精度漂亮但导出ONNX一堆算子不支持根本没法用。2.3 RepGFPN把特征融合做“重”再“轻”回来FPNPAN是YOLO系列的标配负责把不同尺度的特征融合起来。DAMO-YOLO用的是RepGFPN核心思想是训练时用多分支、多尺度的重结构推理时通过重参数化合并成单分支。训练阶段多分支能提升特征表达能力推理阶段合并后不增加延迟。这个思路和RepVGG一脉相承。实际用下来RepGFPN对小目标检测的提升比较明显因为多尺度融合更充分。但要注意重参数化对训练显存有一定要求batch size太小的时候收益会打折。2.4 ZeroHead把检测头做到极简检测头Head是最后输出分类和框回归的地方。DAMO-YOLO的ZeroHead设计理念是“解耦但轻量”分类分支和回归分支分开但每个分支的卷积层数压到很低。配合前面强力的骨干和颈部检测头不需要太复杂就能出好结果。这个设计带来的直接好处是推理时延低。检测头往往是推理瓶颈之一尤其是高分辨率输入时。ZeroHead把这块的成本压下来了。2.5 为什么这套组合值得关注把这三个模块放一起看DAMO-YOLO的思路很清晰骨干负责强特征颈部负责好融合头部负责快输出。每一块都在“够用”的前提下追求效率而不是无脑堆。这种设计哲学对工业落地非常友好因为产线要的不是论文里的极限指标而是稳定、可预测、好部署。3. 环境搭建与快速跑通实操3.1 硬件与基础环境选择我实测用的是一张T416G显存和一张1080Ti11G显存。T4适合推理和中等batch训练1080Ti训练时batch size要压小一点。系统用Ubuntu 20.04CUDA 11.3cuDNN 8.2这套组合在T4上比较稳。Python环境建议3.8或3.9太新的版本有些依赖包会出问题。我习惯用conda建独立环境避免污染系统Python。conda create -n damoyolo python3.8 conda activate damoyoloPyTorch版本选1.10到1.12之间比较稳对应CUDA 11.3。官方仓库对PyTorch版本有一定要求太新或太旧都可能遇到算子不兼容。pip install torch1.11.0cu113 torchvision0.12.0cu113 -f https://download.pytorch.org/whl/torch_stable.html3.2 拉取代码与安装依赖从官方仓库拉代码注意分支选择。我一般用主分支但如果你要复现论文指标建议切到对应release tag。git clone https://github.com/tinyvision/DAMO-YOLO.git cd DAMO-YOLO pip install -r requirements.txt依赖里比较关键的是pycocotools、onnx、onnxsim、tensorrt如果要做TRT部署。pycocotools在Windows上编译经常出问题建议在Linux下搞。安装完后跑一下自带的demo确认环境没问题python tools/demo.py image -f configs/damoyolo_tinynasL20_T.py --path assets/000000000139.jpg --conf 0.5 --infer_size 640 640如果能看到检测结果图输出说明基础环境通了。3.3 数据集准备COCO格式与自定义数据DAMO-YOLO默认用COCO格式。如果你有自己的数据需要转成COCO的json标注。我常用labelme或CVAT标完再转转换脚本网上很多但要注意类别id从1开始还是从0开始这个坑我踩过导致训练时loss一直不降。目录结构建议这样组织datasets/ mydata/ annotations/ instances_train.json instances_val.json train/ xxx.jpg val/ xxx.jpg然后在config里改dataset相关路径。注意num_classes要和你的类别数一致改错了会报维度不匹配。3.4 配置文件关键参数解读DAMO-YOLO的config是Python文件不是yaml。以damoyolo_tinynasL20_T.py为例几个关键参数img_size训练输入尺寸默认640。显存不够可以降到512但小目标会受影响。batch_sizeT4上T版本可以到32S版本建议16。epochs默认300实际微调100左右就够。lr初始学习率默认0.01微调时建议降到0.001。num_classes必须和数据集一致。注意改完config后最好先跑1个epoch看看loss曲线确认没有nan或爆炸再正式训。4. 训练调参与核心环节实现4.1 从预训练权重开始微调除非你有几十万张标注数据否则不要从零训。官方提供了T/S/M/L各版本的预训练权重下载后放到pretrained/目录在config里指定pretrained_model路径。微调时我一般冻结骨干前几层只训颈部和头部训几十个epoch后再解冻全部。这样收敛快也不容易过拟合小数据集。# 在config里可以设置冻结层 model dict( backbonedict( frozen_stages2, # 冻结前2个stage ), )4.2 损失函数与正负样本分配DAMO-YOLO用的损失包括分类损失Quality Focal Loss、回归损失GIoU Loss和DFLDistribution Focal Loss。正负样本分配用的是SimOTA的变体。这套组合在YOLOX里已经被验证过DAMO-YOLO做了适配。实际训练时如果发现正样本太少导致召回低可以调center_radius和topk参数。但这两个参数比较敏感建议一次只调一个观察验证集AP变化。4.3 数据增强策略默认开启了Mosaic、MixUp、HSV增强、随机翻转。Mosaic对小目标提升明显但训练后期建议关闭让模型适应真实分布。我一般在前80% epoch开Mosaic后20%关掉。# 关闭Mosaic的epoch阈值 mosaic_epoch 240 # 总300epoch时240之后关闭实操心得如果你的数据集里小目标特别多Mosaic可以一直开着如果都是大目标早点关掉反而更好。4.4 训练过程监控与日志解读训练日志里重点看几个指标loss_cls、loss_iou、loss_dfl、lr、验证集AP。正常情况loss_cls应该稳步下降如果震荡剧烈可能是学习率太大或batch size太小。我习惯用TensorBoard看曲线tensorboard --logdirwork_dirs/如果验证集AP在某个epoch后不再上升甚至下降说明过拟合了可以早停或加正则。4.5 多卡训练与显存优化如果你有多张卡可以用torch.distributed启动python -m torch.distributed.launch --nproc_per_node2 tools/train.py -f configs/xxx.py单卡显存不够时可以开混合精度AMPDAMO-YOLO默认支持。开了AMP后显存能省30%左右速度也有提升。但要注意AMP有时会导致loss nan遇到这种情况把loss_scale调小或关掉AMP。5. 模型导出与部署落地5.1 导出ONNX及常见坑训练完的模型要部署第一步是导出ONNXpython tools/converter.py -f configs/xxx.py -c weights.pth --batch_size 1 --img_size 640 640导出时常见的坑动态轴设置如果要做变分辨率推理需要设置dynamic_axes否则ONNX固定输入尺寸。算子不支持某些自定义算子导出后ONNX不认需要用onnxsim简化。输出节点名导出后确认输出节点名后面TRT或推理引擎要用。python -m onnxsim damoyolo.onnx damoyolo_sim.onnx5.2 TensorRT加速实测在T4上我把DAMO-YOLO-T导出TRT FP16640分辨率batch1时单帧推理约3ms左右batch8时吞吐能到200FPS。这个数据在同精度模型里相当能打。TRT转换步骤trtexec --onnxdamoyolo_sim.onnx --saveEnginedamoyolo.engine --fp16 --workspace4096注意TRT版本要和CUDA、cuDNN匹配版本不对会报各种奇怪的错。我一般用TRT 8.x配CUDA 11.3。5.3 多路视频流推理的算力估算有人问T4 1080p25帧用TRT跑640分辨率能支持多少路。粗算一下单帧3ms理论单卡能跑300FPS。1080p25帧每路需要25FPS所以理论上限是12路左右。但实际要考虑解码、预处理、后处理开销一般打对折6路左右比较稳。如果开batch推理效率还能再高一些。场景单帧延迟理论路数实际建议路数T4 FP16 batch1~3ms126-8T4 FP16 batch8~2ms/帧158-101080Ti FP16 batch1~5ms84-55.4 边缘设备部署注意事项如果要在边缘设备如Jetson系列上跑建议用T版本输入降到416或320。导出时用FP16甚至INT8量化。INT8量化需要校准集校准集要从你的实际数据里采样不能用COCO随便凑否则精度掉得厉害。6. 常见问题与排查技巧实录6.1 训练不收敛或loss nan这是最常见的问题。排查顺序检查学习率是否太大先降到0.001试试。检查数据标注是否有问题比如框超出图像边界、类别id错误。检查是否有空标注图片空标注会导致某些loss计算出nan。关掉AMP试试排除混合精度问题。6.2 验证集AP远低于训练集典型过拟合。解决办法加数据增强、加正则weight decay、减小模型规模、早停。如果数据集本身很小几千张建议直接用预训练权重做微调不要解冻全部层。6.3 导出ONNX后推理结果不对先确认预处理是否一致。DAMO-YOLO训练时的归一化参数是mean[0,0,0], std[1,1,1]但有些部署代码默认用ImageNet的mean/std这就导致输入分布不对。另外确认letterbox的填充值训练时用的是114部署时也要用114。6.4 TRT推理速度不如预期检查是否用了FP16是否开了cudaGraphworkspace是否够大。另外TRT首次推理有构建开销要warmup几次再测。如果batch1速度上不去试试batch4或8吞吐会明显提升。6.5 小目标漏检严重DAMO-YOLO本身对小目标做了优化但如果你的数据里小目标占比极高可以提高输入分辨率640→800、在config里调整anchor或正样本分配参数、增加小目标的数据增强如小目标复制粘贴。问题现象可能原因排查方向loss nan学习率过大/AMP问题/标注异常降lr、关AMP、查标注AP不升过拟合/数据量不足加增强、早停、冻结层ONNX结果错预处理不一致对齐mean/std/letterboxTRT慢未开FP16/未warmup开FP16、warmup、调batch小目标漏检分辨率低/正样本少提分辨率、调分配参数6.6 一些独家避坑技巧config改完先跑1个epoch别一上来就训300epoch先确认能跑通、loss正常。权重保存频率别太高每10个epoch存一次就够存太勤磁盘很快满。验证集要独立别从训练集里随便抽几张当验证集分布不一致会导致AP虚高。导出前先eval确认PyTorch推理结果正常再导出否则出了问题不好定位是训练问题还是导出问题。7. 它适合哪些场景不适合哪些场景DAMO-YOLO适合对延迟敏感、需要快速部署、数据量中等的场景比如工业质检、安防监控、自动驾驶感知的辅助模块。它的部署链路成熟ONNX和TRT支持好这是很多学术模型比不了的。不太适合的场景需要开放词汇检测它不支持、需要实例分割它只做检测、数据量极小且没有预训练权重的领域微调效果有限。如果你要做开放词汇检测得看Grounding DINO那类模型要做分割得看YOLOv8-seg或Mask R-CNN。我个人在实际项目里的体会是DAMO-YOLO最大的价值不是某个指标刷了多高而是它把“搜出来的结构”真正做成了能落地的工程件。很多NAS模型死在部署这一步DAMO-YOLO没死这就够了。后续如果要做模型压缩可以在这个基础上继续剪枝或量化空间还很大。
返回列表