跳转至内容

了解Ultralytics 中的端到端检测

简介

如果您是从较早的型号(例如 YOLOv8YOLO11升级到 YOLO26,你会注意到最大的变化之一就是去除了非最大抑制(NMS)。传统的YOLO 生成数千个重叠的预测结果,需要单独的NMS 才能筛选出最终的检测结果。这会增加延迟,使导出图变得复杂,并且在不同的硬件平台上可能表现不一致。

YOLO26 采用了不同的方法。它直接从模型中输出最终的检测结果,无需外部过滤。这被称为端到端目标检测,且在所有 YOLO26 模型中默认启用。由此带来的好处是部署流程更简单、延迟更低,且在 CPU 上的推理速度最高可提升 43%

本指南将带您了解具体有哪些变更、是否需要更新代码、哪些导出格式支持端到端推理,以及如何从旧版YOLO 顺利迁移。

若想更深入地了解此次架构调整背后的动因,请参阅Ultralytics 关于 YOLO26 为何移除NMS的文章

简要概述

  • 您正在使用Ultralytics 还是CLI? 无需进行任何更改——只需将您的型号名称替换为 yolo26n.pt.
  • 是否使用了自定义推理代码(ONNX 、TensorRT 等)? 更新您的后处理——检测结果现已 (N, 300, 6)xyxy 格式,NMS 。其他任务NMS 追加额外数据(掩模系数、关键点或角度)。
  • 要导出吗? TPU格式原生支持端到端输出。然而,由于某些操作符约束不被支持(例如, torch.topk)。

端到端检测的工作原理

YOLO26在训练过程中采用双头架构。这两个头部共享相同的骨干网络和颈部网络,但输出方式不同:

头部目的检测结果后处理
一对一(默认)端到端推理(N, 300, 6)仅置信阈值
一对多传统YOLO(N, nc + 4, 8400)需要NMS

上面的形状用于检测。其他任务则在“一对一”输出基础上,针对每次检测添加额外数据:

任务端到端输出附加数据
检测(N, 300, 6)
分割(N, 300, 6 + nm) + 原型 (N, nm, H, W)nm 蒙版系数(默认值为 32)
姿势估计(N, 300, 57)17 个关键点 × 3(x、y、可见性)
OBB(N, 300, 7)旋转角度

在训练过程中,两个头部同时运行——一对多头部提供更丰富的学习信号,而一对一头部则学习生成干净、不重叠的预测。在 推理导出,只有 一对一辅导 该功能默认处于启用状态,每张图像最多可生成 300 个检测结果,格式为 [x1, y1, x2, y2, confidence, class_id].

当您致电时 model.fuse(),它会折叠 Conv + BatchNorm 层以加快推理速度,并在端到端模型中移除一对多头,从而缩减模型大小并降低浮点运算量。有关双头架构的更多详细信息,请参阅 YOLO26 模型页面.

我需要修改代码吗?

使用Ultralytics Python 或CLI

无需进行任何更改。如果您使用标准的Ultralytics Python CLI,一切均可自动运行——预测验证和 导出功能开箱即用,可全程处理端到端模型。

使用Ultralytics 无需修改代码

from ultralytics import YOLO

# Load a YOLO26 model
model = YOLO("yolo26n.pt")

# Predict — no NMS step, no code changes
results = model.predict("image.jpg")
yolo predict model=yolo26n.pt source=image.jpg

使用自定义推理代码

是的,输出格式不同。如果你为 YOLOv8YOLO11 编写了自定义后处理逻辑(例如,在使用ONNX TensorRT进行推理时),您需要对其进行更新以适配新的输出形状:

YOLOv8 YOLO11YOLO26(端到端)
检测输出(N, nc + 4, 8400)(N, 300, 6)
框格式xywh (中心 x, 中心 y, 宽度, 高度)xyxy (左上角 x, 左上角 y, 右下角 x, 右下角 y)
版式各锚点的箱线图坐标及班级分数[x1, y1, x2, y2, conf, class_id]
NMS
后处理NMS 置信度滤波器仅置信度过滤器

关于分割姿势估计以及 旋转框检测 任务中,YOLO26 会在每次检测结果后附加特定任务的数据——请参见上方的输出形状表

在哪里 N批次大小nc 是班级数量(例如,80 表示 COCO)。

借助端到端模型,后处理变得简单得多——例如,在使用ONNX 时:

import onnxruntime as ort

# Load and run the exported end-to-end model
session = ort.InferenceSession("yolo26n.onnx")
output = session.run(None, {session.get_inputs()[0].name: input_tensor})

# End-to-end output: (batch, 300, 6) → [x1, y1, x2, y2, confidence, class_id]
detections = output[0][0]  # first image in batch
detections = detections[detections[:, 4] > conf_threshold]  # confidence filter — that's it!

切换到“一对多”模式

如果您需要传统的YOLO 格式(例如,为了复用现有的NMS 的后处理代码),您可以随时通过设置 end2end=False:

使用一对多接口实现NMS传统NMS输出

from ultralytics import YOLO

model = YOLO("yolo26n.pt")

# Prediction with NMS (traditional behavior)
results = model.predict("image.jpg", end2end=False)

# Validation with NMS
metrics = model.val(data="coco.yaml", end2end=False)

# Export without end-to-end
model.export(format="onnx", end2end=False)
yolo predict model=yolo26n.pt source=image.jpg end2end=False
yolo val model=yolo26n.pt data=coco.yaml end2end=False
yolo export model=yolo26n.pt format=onnx end2end=False

导出格式的兼容性

大多数导出格式开箱即用即可支持端到端推理,包括 ONNXTensorRTCoreML, OpenVINO, TFLiteTF.jsMNN

以下格式支持端到端模式,并将自动回退到一对多头模式: NCNNRKNNPaddlePaddleExecuTorchIMX 以及EdgeTPU

如果不支持端到端加密会怎样

当您导出为这些格式之一时Ultralytics 切换到“一对多”模式并记录一条警告——无需手动干预。这意味着,对于这些格式,您需要在推理NMS 就像使用 YOLOv8YOLO11的情况一样。

TensorRT INT8

TensorRT 支持端到端,但它是 自动禁用 在使用 int8=True 在TensorRT .3.0 上。

准确性与速度的权衡

端到端检测在几乎不影响准确性的情况下,带来了显著的部署优势:

指标端到端(默认)一对多 +NMSend2end=False)
CPU 速度速度提升高达43%基线
mAPmAP 约0.5mAP达到或超过YOLO11
后处理仅置信度过滤器完整的NMS
部署复杂性极简需要NMS )

对于大多数实际应用而言,约0.5 mAP 这种差异微乎其微,尤其是考虑到它带来的速度和简便性优势。如果最高精度是您的首要考虑,您随时可以使用 end2end=False.

请参阅YOLO26 性能指标,了解所有模型尺寸(n、s、m、l、x)的详细基准测试结果。

从YOLOv8 YOLO11迁移

如果您正在将现有项目升级到 YOLO26,以下是一份简要检查清单,可确保升级过程顺利进行:

  • Ultralytics /CLI : 无需修改——只需将模型名称更新为 yolo26n.pt (或 yolo26n-seg.pt, yolo26n-pose.pt, yolo26n-obb.pt)
  • 自定义后处理代码: 更新以支持新的输出形状 — (N, 300, 6) 用于检测,以及针对特定任务的数据 分割, 姿势估计OBB. 另请注意,框的格式已从 xywhxyxy
  • 导出管道:请参阅上文的“格式兼容性”部分,了解目标格式的相关信息
  • TensorRT INT8:请确认您的TensorRT 大于 10.3.0,以获得端到端支持
  • FP16导出: 如果您需要所有输出均为FP16格式,请使用以下方式导出: end2end=False — 参见 为什么 output0 保持为 FP32
  • iOS CoreML: 全面支持端到端开发。如果您需要 Xcode 预览功能的支持,请使用 end2end=False 使用 nms=True
  • 边缘设备(NCNN、RKNN):这些格式会自动回退到一对多模式,因此NMS 设备端管道NMS 包含NMS

常见问题

我可以同时使用 end2end=True 和 nms=True 吗?

不。这些选项是互斥的。如果你设置 nms=True 在端到端模型上 导出,它将自动被强制为 nms=False 附带一个提醒。端到端头端已在内部处理了重复数据过滤,因此NMS 外部NMS 。

然而, end2end=False 结合 nms=True 这是一个有效的配置——它将传统的NMS 整合NMS 导出NMS 。这对于 CoreML 导出,因为这样可以直接在 Xcode 中使用检测模型的预览功能。

在端到端模型中,max_det 参数控制什么?

字段 max_det 参数(默认值:300)用于设置一对一头部在每张图像中最多可输出的检测结果数量。您可以在推理或导出时调整该参数:

model.predict("image.jpg", max_det=100)  # fewer detections, slightly faster
model.export(format="onnx", max_det=500)  # more detections for dense scenes

请注意,默认的 YOLO26 检查点是使用 max_det=300. 虽然您可以增加此数值,但一对一检测头在训练过程中已针对生成最多 300 个清晰检测结果进行了优化,因此超过该限额的检测结果质量可能会降低。如果您需要每张图像生成超过 300 个检测结果,请考虑使用更高的 max_det 值。

我导出的ONNX 输出为 (1, 300, 6) —— 这样对吗?

是的,这就是检测功能的预期端到端输出格式: 批次大小 1 个,最多 300 次检测,每次包含 6 个数值 [x1, y1, x2, y2, confidence, class_id]只需按置信度阈值进行过滤即可——NMS 。

对于其他任务,输出形状则有所不同:

任务输出形状描述
检测(1, 300, 6)[x1, y1, x2, y2, conf, class_id]
分割(1, 300, 38) + (1, 32, 160, 160)6个盒子权重 + 32个掩码系数,外加一个原型掩码tensor
姿势估计(1, 300, 57)6个边界框值 + 17个关键点 × 3(x、y、可见性)
OBB(1, 300, 7)6个箱体值 + 1个旋转角度

如何检查我导出的模型是否是端到端的?

您可以通过Ultralytics Python 进行检查,也可以直接查看导出的ONNX :

检查模型是否为端到端模型

from ultralytics import YOLO

model = YOLO("yolo26n.onnx")
model.predict(verbose=False)  # run predict to setup predictor first
print(model.predictor.model.end2end)  # True if end-to-end is enabled
import onnxruntime as ort

session = ort.InferenceSession("yolo26n.onnx")
metadata = session.get_modelmeta().custom_metadata_map
print(metadata.get("end2end"))  # 'True' if end-to-end is enabled

或者,检查输出维度——端到端检测模型的输出 (1, 300, 6),而传统模型则输出 (1, nc + 4, 8400). 有关其他任务形状,请参阅 输出形状常见问题解答.

在分割、姿势估计和旋转框检测 是否支持端到端处理?

是的。所有 YOLO26 任务变体—— 检测, 分割, 姿势估计旋转框检测 (OBB) — 默认支持端到端推理。该 end2end=False 所有任务也均支持备用方案。

每个任务都会在基础检测结果的基础上,补充特定于该任务的数据:

任务模型端到端输出
检测yolo26n.pt(N, 300, 6)
分割yolo26n-seg.pt(N, 300, 38) + 原型 (N, 32, 160, 160)
姿势估计yolo26n-pose.pt(N, 300, 57)
OBByolo26n-obb.pt(N, 300, 7)


📅 创建于 0 天前 ✏️ 更新于 0 天前
raimbekovm

评论