ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

YOLO v5到v11选型指南:目标检测版本演进、训练与部署

2026/9/18 23:03:43 拓冰建站 浏览量
YOLO v5到v11选型指南:目标检测版本演进、训练与部署 YOLO 这个名字现在已经被用得有点泛滥了你在搜索引擎里敲进去前面几条可能不是算法而是某款服务器型号、某个软件版本号甚至某台打印机。真到要干活的时候问题反而变得很朴素我手上这个项目到底该用 v5 还是 v11换新版本能带来多少收益值不值得把已经跑通的流水线推倒重来我自己从 v5 时代就开始在业务里用 YOLO中间经历过 v6、v7 的过渡期也完整跟过 ultralytics 从 v8 到 v11 的迭代踩过的坑从训练到一半显存爆了到导出 TensorRT 之后精度掉三个点都有。这篇东西就是把这些年攒下来的判断逻辑摊开讲v5 到 v11 每一代到底改了什么、损失函数和标签分配是怎么一步步演化的、2026 年这个时间点该怎么选型、以及一套能直接抄作业的训练和部署流程。适合已经跑过一两个检测项目、准备做技术选型的人也适合刚入门想少走弯路的朋友。1. 先把版本谱系捋清楚不然选型全是瞎猜1.1 三个团队在共用 YOLO 这个名字很多人以为 YOLO 是一个连续的、官方维护的版本序列v5 之后是 v6v6 之后是 v7一路往上排。实际情况完全不是这样。YOLO 这个名字从 Joseph Redmon 的 v1 到 v3 之后主线就断过一次后面的版本是不同团队各自维护、各自命名的产物。v4 是 Alexey Bochkovskiy 那边的工作v5 是 ultralytics 这家公司的产品v6 是美团视觉团队发的v7 又回到了 Alexey 那条线v8 再次是 ultralyticsv9 是美团v10 是清华团队v11 又回到 ultralytics。这意味着一个很现实的问题版本号大小和性能强弱之间没有严格的对应关系。v6 在发布时点上的精度是超过 v5 的v7 在特定场景下又能压过 v6但这些比较都是限定在特定数据集、特定硬件、特定训练轮数下做的。你如果拿 v5 和 v11 直接比 mAP那是可以比的因为它们是同一个团队、同一套训练范式下的前后代但拿 v6 和 v11 比变量就太多了。我在实际选型时会先做一个区分ultralytics 系的版本v5、v8、v11以及后续的 v12 等看成一条连续的产品线它们的 API、数据格式、训练配置、部署工具链是一脉相承的迁移成本低其他团队的版本v6、v7、v9、v10看成独立的技术方案它们的价值更多体现在论文里的结构创新你要用就得自己啃代码、自己接部署链路。这个区分对选型的影响非常大。如果你是团队里唯一负责算法的人手上还要兼顾部署和运维那 ultralytics 这条线的工程效率优势会远大于那零点几个点的 mAP 差距。反过来如果你是在做论文复现或者追求极限精度那 v9、v10 的结构设计值得深挖。另外一个容易被忽略的点是命名混乱带来的沟通成本。我在项目评审里听过太多次我们用最新的 YOLO 就行结果落地时发现有人说的是 v8有人以为 v11 就是 YOLOv8 的小版本。所以我现在写方案文档第一句话一定是把版本号、来源团队、权重文件名三件事同时写清楚比如ultralytics YOLO11m权重 yolo11m.pt绝不简写成YOLO 最新版。1.2 v5 到 v11 关键分水岭速览在展开讲每一代之前先给一张我平时用来跟非算法同事沟通的对照表。这张表不是精确的性能排行而是帮你快速定位哪一代是分水岭。版本主要来源核心变化是否分水岭v5ultralyticsCSPDarknet PANet Anchor-based工程化封装做到极致是定义了后来的使用范式v6美团RepVGG 风格重参数化主干Anchor-free 方向部分结构思路被后续吸收v7Alexey 线E-ELAN、辅助训练头、模型缩放策略部分训练技巧影响深远v8ultralyticsC2f 结构、解耦头、DFL、TaskAlignedAssigner、多任务统一 API是最大的一次范式切换v9美团PGI 可编程梯度信息 GELAN否但梯度思路值得看v10清华NMS-free 的一致双分配、秩引导块设计是端到端方向的开端v11ultralyticsC3k2、C2PSA 注意力、头部轻量化、多任务全面增强是v8 之后的稳定收敛点看这张表你会发现一件事v5 和 v8 是两个真正的转折点v11 是 v8 路线上的精修和收敛。这就是为什么现在讨论选型绝大多数场景的答案会落在 v8 和 v11 之间v5 只在特定遗留项目里还有存在价值。2. 逐代拆解每一代到底动了哪里2.1 YOLOv5把工程体验做到极致的一代v5 最大的贡献其实不是网络结构而是它把目标检测的训练流程做成了一个开箱即用的产品。在这之前你要跑一个检测模型得自己写数据加载、自己接增强、自己搭训练循环、自己处理多尺度推理。v5 用一套 YAML 配置 一个 train.py把这些全包了。结构上 v5 是典型的 Anchor-based 三段式CSPDarknet 主干提取特征SPPF 做多尺度池化融合PANet 做自顶向下加自底向上的双向特征聚合最后接三个尺度的检测头。它用的是锚框机制也就是说网络预测的是相对锚框的偏移量而不是直接回归框的宽高。锚框这个东西在老版本里是个绕不开的坎你需要根据自己数据集的目标尺寸分布重新聚类锚框否则召回率会很难看。v5 里内置了 AutoAnchor 功能训练前会自动跑一遍 K-means 聚类来调整锚框尺寸这是很实用的一步。v5 在数据增强上也是堆料式的Mosaic 四图拼接、MixUp、随机缩放裁剪、HSV 色彩抖动一套组合拳下来对小数据集非常友好。我记得当时用一千多张工业缺陷图训 v5s加完这些增强之后 mAP 直接比不加高了七八个点这在数据量不足的场景里几乎是救命的功能。但 v5 也有明显的历史包袱。它的检测头是耦合的分类和回归共享前面的卷积特征这对两个任务的优化目标其实是有冲突的它的标签分配是静态的靠宽高比阈值和中心点距离来匹配正样本对小目标和密集目标不太友好再加上锚框机制本身带来的超参敏感v5 在复杂场景下确实开始吃力了。现在还有人在用 v5我一般会问两个问题你的项目是不是已经稳定运行、不打算重构你的部署链路是不是深度绑定了 v5 的某些输出格式如果两个都是那就别动能跑就是最好的只要有一个是否定的迁移到 v8 或 v11 的收益是实打实的。2.2 v6 和 v7被夹在中间但贡献不小的两代v6 是美团团队在 2022 年放出来的主打的是重参数化主干。它借鉴了 RepVGG 的思路训练时用多分支结构提升表达能力推理时把多分支等价融合成单路卷积这样训练精度高、推理速度还不受影响。这个思路后来被很多轻量化模型吸收。v6 还全面转向了 Anchor-free去掉了锚框那一套超参。v7 是 Alexey 那条线在 2022 年的作品比较有意思的是辅助训练头的设计。简单说就是在中间层额外接一个检测头参与训练让浅层特征也能拿到梯度信号但推理的时候这个辅助头直接丢掉不增加任何计算量。这个技巧本质上是一种深监督对训练收敛很有帮助。v7 还系统性地讨论了模型缩放的问题也就是当你要把模型做大做小时深度、宽度、分辨率三个维度应该按什么比例扩扩错了会导致参数量和计算量不成比例地增长。这两代都没有成为长期主流但它们贡献的结构和训练技巧在后来的模型里到处能看到影子。我的建议是你不需要用 v6、v7 做项目但值得花一两个小时读一下它们的核心设计。看懂了辅助头和重参数化你对后来版本的很多设计会有更直觉的理解而不是当成黑盒。2.3 YOLOv8整个范式的切换点v8 是 ultralytics 在 2023 年放出来的它做的最重要的一件事是把 YOLO 从一个检测模型变成了一个多任务框架。检测、实例分割、姿态估计、图像分类、旋转框检测全部共用同一套 API 和同一个预训练主干你只要换个权重文件名就能切换任务。这个变化对实际项目的影响比任何精度提升都大因为很多时候你做完检测业务方下一句就是能不能把框里的东西抠出来以前这意味着换一套代码库重来现在只要把-seg权重换上。结构上 v8 有三处核心改动每一处都值得说清楚。第一处是C2f 模块替代 C3。C3 是三个卷积并联再拼接C2f 则是在跨层连接的基础上做了更密集的分支合并梯度流更丰富同等参数量下表达能力更强。你可以把它理解成把并联改成了并联再串并联信息通路更多。第二处是解耦头。分类和回归各自走一条独立的卷积分支不再共享特征。这个改动逻辑很好理解分类关心的是这是什么回归关心的是它在哪、多大两者的特征需求本来就不一样强行共享会互相牵制。实测下来解耦头对定位精度的提升是肉眼可见的。第三处也是最有技术含量的一处是TaskAlignedAssigner DFL 的组合。前者负责决定哪些预测框算正样本后者负责让框回归更精细。2.4 TaskAlignedAssigner 和 DFLv8 精度提升的真正来源先讲 TaskAlignedAssigner我一般叫它 TAL。传统的标签分配要么纯靠 IoU 阈值ATSS 那套要么纯靠中心点距离TAL 的思路是把分类得分和定位 IoU 乘起来用一个综合的对齐度指标来决定正样本。具体做法是这样对于一个真实框网络会预测出一堆候选框TAL 会计算每个候选框的分类得分 s 和它与真实框的 IoU 值 u然后算一个对齐度 t s^α × u^β取这个值最高的前 k 个候选作为正样本。这个设计的精妙之处在于它同时兼顾了分类准和定位准两个维度避免了那种分类得分很高但框歪到天上去的预测被当成正样本。为什么要这么做你想想如果标签分配只看 IoU那么一个分类完全学错但恰好位置对的框也会被当成正样本网络就会收到一个矛盾的监督信号你要把它当成这个类别。TAL 用乘法把两个维度耦合起来让监督信号更干净训练更稳定收敛也更快。我在小数据集上对比过同样的配置下 TAL 比静态分配的收敛速度快了大概三成轮次。再讲DFL分布式焦点损失。传统框回归是直接预测一个数值比如框的左边界距离中心点 32.7 个像素。DFL 换了个思路它把每个边界位置离散成一组区间默认 16 个 bin让网络预测一个概率分布然后用期望值来还原实际距离。这个改动听起来绕但好处很实在它把回归问题变成了分类问题的形式避免了直接回归在边界附近的不稳定性。直接回归一个连续值的时候网络对难样本的梯度很容易爆炸而预测分布有天然的数值上界梯度更可控。而且它隐含地提供了不确定性信息分布越尖锐说明网络越确定越平坦说明越犹豫。这在后处理里可以拿来做置信度过滤的辅助信号。2.5 v9 和 v10两条不同的破局路线v9 来自美团核心是PGI可编程梯度信息和 GELAN。PGI 想解决的问题是深层网络训练时浅层特征的信息会在层层传递中被稀释。它的做法是在主干里插一些可编程的分支把浅层的信息直接搬运到需要的地方而不是只靠反向传播慢慢调。GELAN 则是把 ELAN 和 CSP 的思路做了整合让不同深度的特征融合更充分。v9 的思路很有启发性但它的工程生态相对薄弱你要用基本上得自己魔改代码预训练权重和部署工具的完善度都不如 ultralytics 那条线。我一般是把它当参考文献看不当生产工具用。v10 来自清华主打NMS-free。这个点值得单独拎出来说因为它牵扯到端到端检测的根本问题。传统检测模型的输出是一大堆重叠的框必须靠 NMS非极大值抑制来去重。NMS 有两个毛病一是它是个超参敏感的后处理iou 阈值调不好要么框太多要么把挨得近的目标误删二是它很难做成端到端的可微流程部署到某些硬件上会成为性能瓶颈。v10 的做法是在训练时同时使用一对多的分配一个真实框匹配多个预测和一对一的分配一个真实框只匹配一个预测两者共享主干和部分检测头。推理时只用一对一的那个分支这样输出天然就是去重后的结果完全不需要 NMS。这个一致双分配的设计是端到端检测的一个漂亮解法。不过要注意NMS-free 在部署上是双刃剑。好处是流程简洁、延迟稳定坏处是它把去重的压力转移到了网络内部密集场景下的精度可能不如NMS 调得很好的传统方案。我实测过在人群密集的监控场景里传统方案加精细调参的 NMS精度还是能略胜一筹。所以 NMS-free 更适合对延迟稳定性要求高、目标密度中等的场景。2.6 YOLOv11v8 路线上的精修v11 是 ultralytics 在 2024 年放出的它的定位很清楚不推翻 v8 的范式只做结构上的精修和效率优化。主干上最大的改动是C3k2 模块。它其实是 C2f 的一个变体通过参数控制内部卷积核的大小和分支数量在浅层用较小的核、深层用较大的核让参数量和感受野更匹配。另一个是C2PSA它在主干末端引入了注意力机制用的是类似 PSA位置敏感注意力的设计通过多头注意力和空间注意力来强化关键区域的特征。这里我要多说一句注意力的取舍。加注意力确实能提升精度但它对部署不友好因为很多边缘推理框架对注意力算子的支持不完善导出 ONNX 之后可能被拆成一堆小算子实际推理速度比理论值慢很多。v11 的聪明之处在于它把注意力只放在主干最末端也就是分辨率最低的那一层这一层的特征图尺寸最小注意力带来的计算开销可控对整体速度的影响就小。我实测下来 v11m 在 TensorRT 上的耗时和 v8m 基本持平但 mAP 高了大概一到两个点。v11 还有一个容易被忽略的改动是检测头的轻量化部分卷积换成了深度可分离卷积参数少了一些。官方给的数据是同等精度级别下参数比 v8 少两成左右这对显存紧张的场景是有意义的。另外 v11 在多任务上做了全面增强。姿态估计的关键点精度、分割的掩码质量、旋转框的回归稳定性都有提升还新增了一些方向相关的任务支持。如果你的项目是检测加姿态这种组合需求v11 相比 v8 的优势会比单纯的检测任务更明显。2.7 各版本对比速查表我把平时做选型时用的对比表放在这里。注意这张表里的精度是相对值不是绝对值因为具体数字强依赖于你的数据集和训练配置。维度v5v8v9v10v11锚框机制Anchor-basedAnchor-freeAnchor-freeAnchor-freeAnchor-free标签分配静态TALTAL 变体一致双分配TAL是否需要 NMS是是是否是多任务支持仅检测全面部分检测为主全面增强API 成熟度高老很高低中很高部署工具链完善完善需自建需自建完善单阶段模型精度基准高高高最高迁移成本-中高高低从 v8许可证AGPL-3.0AGPL-3.0GPL-3.0AGPL-3.0AGPL-3.0这张表里有个坑要专门提醒许可证。ultralytics 系的权重和代码是 AGPL-3.0这个协议对商业闭源分发是有约束的。如果你的产品要交付给客户且不开放源码需要走商业授权。这一点在做选型时必须提前跟法务确认别等模型都训好了才发现协议有问题。其他团队的版本大多是 GPL 系约束类似。3. 核心机制损失函数和结构演进的内在逻辑3.1 损失函数从 IoU 家族演变到 DFL讲损失函数之前先把检测任务的损失拆成三块分类损失、定位损失、置信度损失。v5 时代这三块是 BCE二值交叉熵做分类、BCE 做置信度、CIoU 做定位。v8 之后置信度损失被合并进分类分支因为 Anchor-free 没有独立的 objectness定位损失换成了 CIoU 加 DFL 的组合。定位损失的历史就是 IoU 家族的进化史。最早的 IoU Loss 直接用交并比问题是两个框完全不相交的时候梯度为零网络学不动。GIoU 引入了最小外接矩形来补上这个洞让不相交的时候也有梯度方向。DIoU 进一步加入了中心点距离项让框收敛得更快。CIoU 再加一个宽高比一致性项让框的形状也能对齐。这几个损失我实际用下来的感受是在正常数据集上IoU 到 CIoU 的差距没有论文里写得那么夸张可能就零点几个点。但在目标尺度差异很大、或者有很多长条形目标的场景里CIoU 的宽高比项确实有用。我做过一个输电线异物检测的项目目标又细又长用 GIoU 的时候框总是学不圆换 CIoU 之后明显改善。DFL 的作用前面讲过了它是把连续回归变成分布预测。这里补充一个实操细节DFL 默认的 bin 数量是 16也就是每个边界位置用 16 个离散值来表示。这个数字不是随便定的它其实有个约束——bin 数量必须是 4 的倍数因为回归头输出通道的分配有这个要求。你要改的话建议在 8 到 32 之间调太小了分辨率不够太大了参数量上去了收益递减。我一般不改默认 16 在绝大多数场景够用。在自定义损失的时候还有个容易忽略的点各项损失的权重配比。ultralytics 默认的分类权重是 0.5、定位权重是 7.5、DFL 权重是 1.5。这个配比是大量实验调出来的你不建议轻易动。我见过有人为了提升定位精度把定位权重调到 20结果分类崩了因为梯度被定位项主导分类分支基本学不到东西。真要调一次动一个幅度别超过 50%。3.2 标签分配决定了模型的上限我经常跟人说一句话检测模型的精度上限很大程度上是标签分配决定的不是网络结构决定的。结构决定了特征提取能力但分配决定了网络到底在学什么。静态分配的思路是规则说了算IoU 超过 0.5 就算正样本宽高比在一定范围内才算中心点必须落在某个区域内。这套规则在人手设计的时代够用但它的阈值是全局的对大小目标一视同仁这就导致小目标经常匹配不到足够的正样本。动态分配的思路是网络自己说了算每一轮训练都根据当前的预测结果重新计算哪些候选算正样本。TAL 是其中的代表用分类得分和 IoU 的乘积来排序。后来还有更复杂的方案比如用最优传输理论来做一对一分配v10 用的一致双分配就属于这一类。这个演进带来的实际收益是什么我给你个具体例子。我做过一个光伏板缺陷检测缺陷尺度从几个像素到几百个像素都有。用 v5 的静态分配小缺陷的召回率一直在 60% 上下打转换到 v8 的 TAL 之后同样数据集、同样增强小缺陷召回率提到了 78%。结构参数其实没变多少变的就是分配策略。所以如果你现在的模型在小目标或者密集目标上表现很差优先考虑换版本或者调分配相关参数而不是去堆网络结构。这是很多人踩过的弯路。3.3 结构演进的底层逻辑梯度流和感受野从 CSP 到 C2f 再到 C3k2表面上看起来是模块名字在变底层其实在优化同一件事梯度流的丰富度。CSP 的核心思路是把特征图分成两半一半走卷积一半直接连过去最后拼起来。这样做的目的是让梯度有短路路径可以走缓解深层网络的梯度消失。C2f 在此基础上把两半变成了更有层次的分支结构让不同分支承担不同深度的特征提取。C3k2 又加入了卷积核尺寸的可配置性。为什么梯度流这么重要你可以把网络想象成一个长长的传话游戏信息从第一层传到第一百层中间任何一层传歪了后面的全歪。短路连接相当于给每几层配一个直接汇报通道让底层的信息可以绕过中间层直达高层。信息通路的数量越多网络能学到的东西越丰富。另一个维度是感受野。检测任务里你需要同时看到局部细节判断这是什么和全局上下文判断它在什么环境里。感受野太小就只能看到局部太大就丢失细节。C3k2 通过让不同深度的层用不同尺寸的卷积核其实是在做感受野的动态分配。v11 的 C2PSA 注意力则是另一个思路不是扩大感受野而是让网络学会看哪里。注意力会计算每个空间位置的重要性权重把计算资源集中在有意义的区域上。对于背景占大头的图像比如航拍、监控这个机制收益明显。3.4 NMS-free 到底值不值得这个问题我被问过很多次。我的回答是先看你部署在什么硬件上。如果你部署在 GPU 上NMS 可以用 CUDA 加速耗时占比通常不到 5%那 NMS-free 带来的收益就很有限反而要承担精度可能下降的风险。如果你部署在 CPU 或者某些 NPU 上NMS 是纯串行操作耗时占比可能到 20% 甚至更高那 NMS-free 的价值就大了。还有一个场景是多路视频流。比如你要同时处理 16 路摄像头这时候每路的后处理开销累加起来很可观而且 NMS 的耗时会随着框的数量波动导致整体帧率不稳定。这种情况下 NMS-free 的稳定性优势很关键因为它把延迟变成了一个固定的前向计算时间。我自己的经验是优先用传统方案加优化过的 NMS因为生态成熟、调参经验多只有在延迟稳定性成为硬指标或者硬件对 NMS 支持极差的时候才切到 NMS-free 方案。别为了尝鲜去用那是给自己找麻烦。4. 面向落地的选型指南4.1 选型的五个判断维度选型不是选最强的是选最合适的。我一般按这五个维度过一遍。维度关键问题影响任务类型只做检测还是要分割/姿态/旋转框决定能否用统一 API精度需求业务能接受的漏检率、误检率是多少决定模型规模延迟约束端到端要在多少毫秒内完成决定模型规模和部署格式硬件平台GPU、CPU、边缘芯片、国产化平台决定导出格式和算子兼容性团队能力有没有人能啃论文改代码决定能否用非 ultralytics 系这五个维度里硬件平台是最容易被低估的一个。我见过太多方案在服务器上跑得好好的一上边缘设备就出问题因为注意力算子或者某些自定义算子不支持导出的时候被工具链拒绝或者虽然导出了但走了 fallback 路径速度慢十倍。所以我的建议是在训练之前就把目标硬件确定下来并且先用一个预训练权重跑通导出和推理的完整链路。别等模型训完了才发现部署不了那时候返工成本极高。4.2 不同场景的推荐组合我把常见的几类场景整理成下面这张对照表都是我实际做过或深度参与过的项目类型。场景推荐版本推荐规模理由服务器端离线批处理v11m 或 l精度优先算力充足实时视频流GPUv8 或 v11s 或 m速度精度平衡生态成熟边缘盒子低功耗v8n 或 v11nn参数量小导出兼容性好移动端 Appv8nn量化工具链成熟老旧遗留系统维护保持 v5s 或 m能跑就别动密集小目标航拍等v11m 或 l大输入尺寸C2PSA 对背景抑制有帮助需要分割掩码v8-seg 或 v11-segs 或 m统一 API切换成本低极端低延迟要求v10sNMS-free 延迟稳定这里我特别想说一下输入尺寸这个参数。很多人只调模型规模忽略输入分辨率其实后者的影响往往更大。把输入从 640 提到 1280小目标召回率的提升可能比换一个大两号的模型还明显代价是计算量涨四倍。如果你的瓶颈是小目标优先考虑提分辨率然后才考虑换模型。但分辨率不是想提就能提的。它受显存约束因为显存占用大致和分辨率的平方成正比。640 到 1280 是四倍batch size 就得相应减小否则直接爆显存。这个权衡在做方案时必须算清楚。4.3 硬件适配的实操细节NVIDIA GPU是最省心的路径。导出 ONNX 再用 TensorRT 转 engine开 FP16 精度无损的情况下速度能提升两到三倍。注意 TensorRT 的 engine 是和显卡型号、驱动版本、TensorRT 版本绑定的换机器必须重新生成这一点在交付的时候要在文档里写清楚否则客户那边跑不起来会来找你。CPU 部署首推 OpenVINO。它对 Intel 的 CPU 和核显优化很好支持 INT8 量化实测在 i7 上 v8n 能跑到 30 FPS 以上够很多场景用了。导出的坑在于动态 shapeOpenVINO 对动态输入的支持不如 ONNX 完善建议导出时指定固定的 batch 和输入尺寸。国产化平台和 ARM 边缘设备常见的选择是 NCNN、RKNN、昇腾的 CANN 工具链。这些工具链对注意力和自定义算子的支持普遍不完善所以我一般会建议在这些平台上用 v8 而不是 v11因为 v8 的结构更传统算子更标准导出成功率更高。如果非要用 v11一定要先在目标平台上跑一遍完整的导入测试。AMD 显卡是很多人关心的点。Linux 下可以用 ROCm 版的 PyTorch 做训练Windows 下训练支持比较有限通常是训练在 NVIDIA 或者云端做推理用 DirectML 或者 ONNX Runtime 跑。这条路径是可行的但踩坑概率明显高于 NVIDIA建议预留调试时间。4.4 许可证和合规这条线不能省前面提过一次这里再强调一下。ultralytics 从 v5 开始的所有版本都是 AGPL-3.0 协议。这个协议的核心约束是如果你把基于它的软件作为网络服务提供或者分发修改后的版本你必须开源你的完整代码。这在企业内部使用是完全没问题的因为不涉及分发。但如果你做的是商业产品交付或者做 SaaS 服务就要仔细评估。ultralytics 提供商业授权费用按项目规模算具体要去官方渠道问。替代路线也有用其他协议更宽松的检测模型或者从零自己实现一套训练框架工作量很大。我的经验是在项目立项阶段就把这件事确认清楚别做到一半才发现要重写那才是真的坑。5. 从零训一个自己的数据集完整流程5.1 环境搭建和版本对齐环境这块我踩过的坑比技术本身还多所以先说结论用虚拟环境锁死版本号别用最新版。Python 建议 3.9 到 3.113.12 之后的某些版本和 PyTorch 的兼容性有问题。PyTorch 建议用 2.0 以上的稳定版和 CUDA 版本对应。ultralytics 直接 pip 装但要注意它会自动拉一堆依赖可能和你的环境冲突所以务必在虚拟环境里做。conda create -n yolo11 python3.10 -y conda activate yolo11 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 pip install ultralytics装完之后验证一下yolo checks这个命令会打印出你的环境信息包括 PyTorch 版本、CUDA 是否可用、GPU 型号。如果 CUDA 显示不可用而你有显卡八成是驱动版本不匹配用nvidia-smi看一下驱动支持的 CUDA 版本然后装对应的 torch。还有一个坑是多版本共存。如果你之前装过 v8 的包再装 v11 可能会覆盖或者冲突。建议每个项目单独一个环境别图省事共用一个。5.2 数据标注和格式转换YOLO 的标注格式很简单每张图对应一个 txt 文件每行一个目标格式是类别索引 中心点x 中心点y 宽度 高度这四个坐标都是归一化到 0 到 1的值是相对于图像宽高的比例。比如一个框的中心在图像中心宽高各占图像一半那就是0 0.5 0.5 0.5 0.5。这里有个新手最容易犯的错把像素坐标直接写进去。我看到过好几次这样的情况训练的时候 loss 一直不降查了半天发现标注文件里写的是0 320 240 100 80这种像素值。所以标注完之后一定要抽查几个文件确认数值都在 0 到 1 之间。标注工具我常用的有几个。labelImg 最经典操作简单输出格式可以选 YOLO 格式适合小规模数据集。CVAT 功能更强支持多人协作、视频标注、自动标注适合中大规模。Roboflow 是线上平台能直接做增强和格式转换但要注意数据上传的合规问题敏感数据别往上传。如果你手上是 COCO 格式的标注需要转成 YOLO 格式可以写个脚本import json import os from PIL import Image def coco2yolo(coco_json, img_dir, out_dir): os.makedirs(out_dir, exist_okTrue) with open(coco_json, r) as f: data json.load(f) cats {c[id]: i for i, c in enumerate(data[categories])} images {img[id]: img for img in data[images]} anns {} for ann in data[annotations]: anns.setdefault(ann[image_id], []).append(ann) for img_id, img_info in images.items(): w, h img_info[width], img_info[height] fname os.path.splitext(img_info[file_name])[0] .txt lines [] for ann in anns.get(img_id, []): x, y, bw, bh ann[bbox] cx (x bw / 2) / w cy (y bh / 2) / h lines.append(f{cats[ann[category_id]]} {cx:.6f} {cy:.6f} {bw/w:.6f} {bh/h:.6f}) with open(os.path.join(out_dir, fname), w) as f: f.write(\n.join(lines)) coco2yolo(instances.json, images, labels)注意 COCO 的 bbox 格式是[左上角x, 左上角y, 宽, 高]是像素值转换的时候要做归一化。这个脚本我用了好多次直接改改路径就能跑。5.3 数据集的目录结构和配置文件标准结构是这样的dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yaml注意images 和 labels 的目录结构必须完全镜像图片路径是images/train/a.jpg标注就必须是labels/train/a.txt。ultralytics 在加载的时候会做路径替换替换规则是找路径里的最后一个images字符串换成labels然后扩展名换成 txt。如果你的目录名里有别的 images 字样可能会替换错位置这是个隐蔽的坑。data.yaml 是最关键的配置文件path: /abs/path/to/dataset train: images/train val: images/val names: 0: person 1: helmet 2: vest几个细节path建议写绝对路径避免相对路径带来的混乱。names的索引必须从 0 开始连续不能跳号。如果你的类别名里有中文或者特殊字符建议改成英文因为我遇到过某些环境下 YAML 解析中文出问题的情况。5.4 训练参数怎么定我用 v11 做例子一条基础训练命令yolo detect train \ modelyolo11m.pt \ datadataset/data.yaml \ epochs200 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ cos_lrTrue \ warmup_epochs3 \ patience50 \ device0 \ projectruns/train \ nameexp01我把几个关键参数的解释和我的经验值列一下。epochs这个要和数据集规模一起看。数据集大几万张的时候 100 到 300 轮就够数据集小几千张的时候需要更多轮但要注意过拟合。我一般先跑 100 轮看曲线如果验证 loss 还在降就继续加。batch受显存约束。经验值是在保证不 OOM 的前提下尽量大因为大 batch 的梯度更稳BatchNorm 的统计也更准。但如果 batch 太大泛化会变差一般不建议超过 64。lr0 和 lrf初始学习率和最终学习率系数。lrf0.01表示最终学习率是初始值的 1%。学习率太大会震荡不收敛太小会收敛慢。我的经验是从头训用 0.01微调预训练模型用 0.001 到 0.005。cos_lr用余弦退火的学习率调度。相比阶梯式下降余弦更平滑通常在后期能拿到更好的精度。我基本都开着。patience早停耐心值。验证指标连续这么多轮没提升就停。设太小会提前停设太大浪费时间。50 是个比较稳的值。warmup_epochs预热轮数。前几轮用很小的学习率慢慢升上去避免一开始就把预训练权重破坏掉。用预训练权重时建议开从零训可以设 0。还有一个参数容易被忽略是close_mosaic。Mosaic 增强在训练后期是有害的因为它的图像拼接会让目标尺寸分布失真。ultralytics 默认在最后 10 轮关闭 Mosaic这个设置我一般不动。如果你发现训到后期指标突然跳变可以看看是不是这个引起的。5.5 训练监控和结果解读训练启动之后结果会保存在runs/train/exp01/下。最重要的几个文件results.csv每个 epoch 的所有指标results.png指标曲线图confusion_matrix.png混淆矩阵weights/best.pt验证集上最好的权重weights/last.pt最后一个 epoch 的权重看曲线的时候我一般关注这几件事。box_loss 和 cls_loss 是不是单调下降如果震荡很厉害说明学习率偏大。验证集的 mAP 是不是还在涨如果很久不涨了说明该停了。训练和验证的 gap 大不大如果训练指标远高于验证说明过拟合了要加增强或者减模型。有一次我训一个缺陷检测模型训练 mAP 到 0.95 了验证才 0.6。查了半天发现是数据泄漏同一个产品的多张图片被分到了训练集和验证集。所以划分数据集的时候一定要按产品、按时间段或者按场景来分别随机分否则同一个目标的多张近似图片会跨集导致指标虚高。5.6 导出和部署的完整链路训练完之后导出# 通用 ONNX yolo export modelruns/train/exp01/weights/best.pt formatonnx opset12 simplifyTrue # TensorRT需要 GPU yolo export modelbest.pt formatengine halfTrue device0 # OpenVINO yolo export modelbest.pt formatopenvino halfTrue # NCNN yolo export modelbest.pt formatncnn几个坑点必须说。opset 版本默认可能是 17 或者更高但很多推理框架只支持到 11 或 12。我一般显式指定 12兼容性最好。如果目标平台很老可能要降到 11。dynamic 参数默认导出是固定的 shape。如果你需要动态 batch 或者动态分辨率要加dynamicTrue。但注意动态 shape 在 TensorRT 上会降低优化空间速度可能不如固定 shape。我一般导出两个版本一个固定一个动态按场景选用。simplify这个参数会用 onnx-simplifier 优化计算图去掉冗余算子通常能提升推理速度。但偶尔会引入 bug如果你发现导出后精度掉了先试试关掉它。half 精度FP16 导出能提速但要注意溢出问题。分类分支在 FP16 下一般没问题但如果你的模型有特别大或者特别小的数值可能会溢出成 NaN。判断方法是导出后跑几张测试图对比 FP32 和 FP16 的输出如果差异超过 1% 就别用 FP16。精度对齐验证这是我强烈建议做的一步。导出之后用同一批测试图分别跑 PyTorch 原模型和导出模型对比输出的框坐标和置信度。差异应该在小数点后两位内。如果差异大说明转换过程有问题要逐步排查 opset、simplify、精度设置。6. 踩坑记录与排查速查6.1 训练阶段问题速查表现象可能原因排查方向loss 一直是 nan学习率太大、数据有脏样本、FP16 溢出降 lr、开 AMP 检查、抽查标注loss 不降标注格式错、类别索引错、数据路径错可视化验证一批数据显存 OOMbatch 太大、输入尺寸太大、模型太大降 batch、开梯度累积训练慢数据加载瓶颈、没用 GPU、num_workers 太小检查 GPU 利用率调 workers验证 mAP 虚高数据泄漏、类别不均衡重新划分数据集、看混淆矩阵小目标效果差输入分辨率低、分配策略不适应提 imgsz、检查正样本数这里重点说一下loss 不降这个最常见的现象。我的排查顺序是固定的先可视化几张训练图带标注确认标注框位置对不对再看 data.yaml 的 names 和标注文件里的类别索引能不能对上然后确认图片路径和标注路径的镜像关系有没有错。这三个查完九成的问题都能定位。可视化这个动作极其重要我见过太多人跳过这一步直接训练然后花几天时间调参最后发现是标注错了。ultralytics 提供了可视化脚本或者你自己用 OpenCV 画一下也就十几行代码的事。关于梯度累积补充一下用法。如果你的显存只够跑 batch4但你想模拟 batch16 的效果可以设nbs64配合小 batch框架会自动做梯度累积。注意这个参数和 batch 是配合使用的具体行为在不同版本里略有差异建议看当前版本的文档确认。6.2 部署阶段问题速查表现象可能原因解决思路导出报错不支持某算子用了注意力或自定义算子换 v8、降低 opset、手动替换算子推理结果全空预处理不一致归一化、通道顺序对齐 letterbox 和归一化参数框位置偏移输入尺寸处理不一致检查 letterbox 的填充和还原逻辑TensorRT 速度没提升batch 太小、没用 FP16、被 fallback增大 batch、开 half、看 verbose 日志换机器跑不了 engineengine 和硬件绑定每台机器重新生成多线程推理崩模型实例没做线程隔离每个线程独立实例或加锁预处理不一致是部署阶段第一大坑没有之一。训练时框架会做 letterbox保持宽高比的缩放加填充推理时你自己写的代码如果直接 resize坐标就全错了。letterbox 的逻辑是先算出缩放比例把图缩放到目标尺寸内剩下的部分用灰色填充然后在还原坐标的时候减去填充量再除以缩放比例。这个逻辑不难但细节多建议直接抄官方源码里的实现别自己造。还有一个坑是通道顺序和归一化。PyTorch 训练时用的是 RGB、0 到 1 归一化。如果你用 OpenCV 读图默认是 BGR、0 到 255。忘了转换的话模型的输出会完全乱掉表现为检测出一堆莫名其妙的东西。这个错误特别隐蔽因为程序不报错就是结果不对。6.3 几个只有踩过才知道的心得第一个心得是先跑通全链路再做优化。我现在的习惯是拿到新项目先用官方预训练权重跑一遍推理确认环境没问题再用少量数据几百张训 10 轮确认训练链路没问题再导出到目标平台确认部署链路没问题。这三步走完才开始正式训练和调优。这个流程看起来很慢但能避免训了三天发现部署不了这种灾难。第二个心得是版本升级要留回退路径。从 v8 升到 v11 的时候别直接把老代码删了。新老版本并行跑一段时间对比指标确认新版本确实更好再切换。数据格式虽然兼容但某些参数名和行为是变了的比如某些增强的默认值、某些损失项的系数。这些差异在文档里可能没写清楚只能靠实测对比发现。第三个心得是关注 hard example 而不是平均值。mAP 是一个平均指标它会掩盖掉那些少数但重要的失败案例。我每次训完都会把验证集里置信度低、或者预测错的样本挑出来看往往能发现数据标注的系统性问题。有一次我发现模型总是把戴深色安全帽的人漏掉查数据才发现这类样本在整个数据集里只有十几张。补标了一批之后指标直接上去了。第四个心得是推理耗时要在目标硬件上测别信理论值。论文里的 FPS 是在特定 GPU 上、特定 batch、特定精度下测的和你的实际场景差得远。我在一个边缘设备上实测过理论 FLOPs 差不多的两个模型实际推理速度差了三倍原因是其中一个模型的算子被工具链拆得稀碎走了很多 fallback。所以 FLOPs 只能用来做粗略筛选最终决策必须靠实机实测。第五个心得是数据集的质量比算法的先进程度更能决定成败。我做过一个对比同样的 v8m标注精细的数据集比标注粗糙的数据集 mAP 高了十个百分点以上而换成 v11l 只能再提升一个点。所以如果你的项目效果不好先别急着换模型先回头看看数据。最后分享一个我自己的小工具习惯。我会在项目目录下放一个check.py功能很单一随机抽 20 张训练图把标注框画上去再跑一遍模型推理把预测框画上去两个结果并排显示。每次训完模型我都先跑这个脚本看一眼。它能在一分钟内告诉你模型到底学到了什么、漏了什么、多检了什么。这个习惯帮我省下的时间比任何调参技巧都多。