了解Ultralytics 中的端到端检测
简介
如果您是从较早的型号(例如 YOLOv8 或 YOLO11升级到 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
使用自定义推理代码
是的,输出格式不同。如果你为 YOLOv8 或 YOLO11 编写了自定义后处理逻辑(例如,在使用ONNX 或 TensorRT进行推理时),您需要对其进行更新以适配新的输出形状:
| YOLOv8 YOLO11 | YOLO26(端到端) | |
|---|---|---|
| 检测输出 | (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
导出格式的兼容性
大多数导出格式开箱即用即可支持端到端推理,包括 ONNX、 TensorRT、 CoreML, OpenVINO, TFLite、TF.js 和MNN。
以下格式不支持端到端模式,并将自动回退到一对多头模式: NCNN、RKNN、 PaddlePaddle、ExecuTorch、IMX 以及EdgeTPU。
如果不支持端到端加密会怎样
当您导出为这些格式之一时Ultralytics 切换到“一对多”模式并记录一条警告——无需手动干预。这意味着,对于这些格式,您需要在推理NMS 就像使用 YOLOv8 或 YOLO11的情况一样。
TensorRT INT8
TensorRT 支持端到端,但它是 自动禁用 在使用 int8=True 在TensorRT .3.0 上。
准确性与速度的权衡
端到端检测在几乎不影响准确性的情况下,带来了显著的部署优势:
| 指标 | 端到端(默认) | 一对多 +NMSend2end=False) |
|---|---|---|
| CPU 速度 | 速度提升高达43% | 基线 |
| mAP | mAP 约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. 另请注意,框的格式已从xywh到xyxy - 导出管道:请参阅上文的“格式兼容性”部分,了解目标格式的相关信息
- 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) |
| OBB | yolo26n-obb.pt | (N, 300, 7) |