理解 Ultralytics YOLO26 中的端到端 detect
简介
如果您从YOLOv8或YOLO11等早期模型升级到YOLO26,您会注意到的最大变化之一是移除了非极大值抑制(NMS)。传统的YOLO模型会产生数千个重叠的预测,需要单独的NMS后处理步骤来筛选出最终的检测结果。这会增加延迟,使导出图变得复杂,并且在不同的硬件平台上表现不一致。
YOLO26采用了不同的方法。它直接从模型输出最终检测结果 — 无需外部过滤。这被称为端到端目标检测,并且在所有YOLO26模型中默认启用。结果是更简单的部署流程、更低的延迟,以及在CPU上高达43%的推理速度提升。
本指南将引导您了解发生了哪些变化、您是否需要更新代码、哪些导出格式支持端到端推理,以及如何从旧版YOLO模型平稳迁移。
要深入了解这一架构转变背后的动机,请参阅Ultralytics关于YOLO26为何移除NMS的博客文章。
快速摘要
- 使用Ultralytics API或CLI? 无需更改 — 只需将模型名称替换为
yolo26n.pt. - 使用自定义推理代码(ONNX Runtime、TensorRT等)? 更新您的后处理 — 检测输出现在是
(N, 300, 6)在xyxy格式,无需NMS。其他任务会附加额外数据(掩码系数、关键点或角度)。 - 导出? 大多数格式原生支持端到端输出。然而,少数格式(NCNN、RKNN、PaddlePaddle、ExecuTorch、IMX和Edge TPU)由于不支持的操作符限制,会自动回退到传统输出(例如,
torch.topk)。
端到端 detect 的工作原理
YOLO26在训练期间使用双头架构。两个头部共享相同的骨干网络和颈部,但以不同的方式产生输出:
| 头部 | 目的 | 检测输出 | 后处理 |
|---|---|---|---|
| 一对一 (默认) | 端到端推理 | (N, 300, 6) | 仅置信度阈值 |
| 一对多 | 传统 YOLO 输出 | (N, nc + 4, 8400) | 需要 NMS |
上述形状适用于 detect。其他任务通过为每个 detect 扩展一对一输出,增加额外数据:
| 任务 | 端到端输出 | 额外数据 |
|---|---|---|
| 检测 | (N, 300, 6) | — |
| 分割 | (N, 300, 6 + nm) + proto (N, nm, H, W) | nm 掩码系数 (默认 32) |
| 姿势估计 | (N, 300, 57) | 17 关键点 × 3 (x, y, 可见性) |
| OBB | (N, 300, 7) | 旋转角度 |
在训练期间,两个头部同时运行——一对多头部提供更丰富的学习信号,而一对一头部则学习生成清晰、不重叠的预测。在 推理 和 导出,只有 一对一头部 默认处于活动状态,以以下格式每张图像生成最多 300 个 detect: [x1, y1, x2, y2, confidence, class_id].
当您调用 model.fuse()时,它会折叠 Conv + BatchNorm 层以实现更快的推理,并且,对于端到端模型,还会移除一对多头部——从而减小模型大小和 FLOPs。有关双头架构的更多详细信息,请参阅 YOLO26 模型页面.
我需要更改我的代码吗?
使用 Ultralytics python API 或 CLI
无需更改。 如果您使用标准的 Ultralytics python API 或 CLI,一切都将自动运行——预测、验证和导出都开箱即用地支持端到端模型。
使用 Ultralytics API 无需代码更改
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 Runtime 或 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 + 置信度过滤 | 仅置信度过滤 |
对于segmentation、姿势估计和旋转框检测任务,YOLO26会将任务特定数据附加到每个检测结果中 — 请参阅上面的输出形状表。
其中 N 是 批次大小 和 nc 是类别数量 (例如,对于80个类别 COCO)。
对于端到端模型,后处理变得简单得多 — 例如,当使用ONNX Runtime时:
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输出
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和Edge TPU。
当不支持端到端时会发生什么
当您导出为这些格式之一时,Ultralytics会自动切换到一对多头部并记录警告 — 无需手动干预。这意味着对于这些格式,您的推理管道中将需要NMS,就像使用YOLOv8或YOLO11一样。
TensorRT + INT8
TensorRT 支持端到端,但它被 自动禁用 当使用 int8=True 在 TensorRT ≤10.3.0 上。
准确性和速度的权衡
端到端 detect 提供了显著的部署优势,同时对准确性的影响最小:
| 指标 | 端到端(默认) | 一对多 + NMS (end2end=False) |
|---|---|---|
| CPU 推理速度 | 快达43% | 基线 |
| mAP 影响 | mAP 约降低 0.5 | 与 YOLO11 相当或超越 |
| 后处理 | 仅置信度过滤 | 完整 NMS 流水线 |
| 部署复杂性 | 最小 | 需要 NMS 实现 |
对于大多数实际应用而言,约 0.5 的 mAP 差异可以忽略不计,尤其是在考虑到速度和简便性提升的情况下。如果最大准确性是您的首要任务,您始终可以使用一对多头部回退到 end2end=False.
请参阅 YOLO26 性能指标,以获取所有模型尺寸(n、s、m、l、x)的详细基准测试结果。
从YOLOv8或YOLO11迁移
如果您正在将现有项目升级到 YOLO26,这里有一个快速清单,以确保平稳过渡:
- Ultralytics API / CLI 用户: 无需更改 — 只需将模型名称更新为
yolo26n.pt(或yolo26n-seg.pt,yolo26n-pose.pt,yolo26n-obb.pt) - 自定义后处理代码: 更新以处理新的输出形状 —
(N, 300, 6)用于 detect,以及针对特定任务的数据 分割, 姿势估计和 OBB。另请注意边界框格式从xywh到xyxy - 导出流水线:请查阅上方针对您目标格式的格式兼容性部分
- TensorRT + INT8:请验证您的 TensorRT 版本是否高于 10.3.0 以获得端到端支持
- FP16 导出: 如果您需要所有输出均为 FP16 格式,请使用以下方式导出:
end2end=False— 参见 为何 output0 保持 FP32 - iOS / CoreML: 端到端(End-to-end)功能已完全支持。如果您需要 Xcode 预览支持,请使用
end2end=False使用nms=True - 边缘设备 (NCNN, RKNN): 这些格式会自动回退到一对多模式,因此请在您的设备端管线中包含 NMS
常见问题
我可以同时使用end2end=True和nms=True吗?
不。这些选项是互斥的。如果您在 nms=True 端到端模型上设置 导出,它将自动被强制为 nms=False 并发出警告。端到端头部已在内部处理重复过滤,因此外部 NMS 是不必要的。
然而, end2end=False 结合 nms=True 是一个有效的配置 — 它将传统 NMS 嵌入到导出图中。这对于 CoreML 导出很有用,因为它允许您直接在 Xcode 中使用 detect 模型进行预览功能。
max_det 参数在端到端模型中控制什么?
字段 max_det 参数(默认值:300)设置了一对一头部每张图像可输出的最大 detect 数量。您可以在推理或导出时进行调整:
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 个清晰的 detect,因此超出此限制的 detect 质量可能会较低。如果您每张图像需要超过 300 个 detect,请考虑使用更高的 max_det 值进行重新训练。
我导出的ONNX模型输出(1, 300, 6) — 这正确吗?
是的,这就是 detect 的预期端到端输出格式: 批次大小 为 1,最多 300 个 detect,每个 detect 包含 6 个值 [x1, y1, x2, y2, confidence, class_id]只需按置信度阈值进行过滤即可——NMS 。
。只需按置信度阈值过滤即可完成 — 无需 NMS。
| 任务 | 对于其他任务,输出形状有所不同: | 描述 |
|---|---|---|
| 检测 | (1, 300, 6) | [x1, y1, x2, y2, conf, class_id] |
| 分割 | (1, 300, 38) + (1, 32, 160, 160) | 输出形状 |
| 姿势估计 | (1, 300, 57) | 6 个边界框值 + 32 个掩码系数,以及一个原型掩码 tensor |
| OBB | (1, 300, 7) | 6个边界框值 + 1个旋转角度 |
如何检查我的导出模型是否是端到端的?
您可以通过Ultralytics Python API或直接检查导出的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
或者,检查输出形状 — 端到端detect模型输出 (1, 300, 6),而传统模型输出 (1, nc + 4, 8400)。对于其他任务形状,请参阅 输出形状常见问题.
端到端支持分割、姿势估计和旋转框检测任务吗?
是的。所有YOLO26任务变体 — 检测, 分割, 姿势估计和 旋转框检测 (OBB) — 默认支持端到端推理。该 end2end=False 回退机制也适用于所有任务。
每个任务都通过任务特定数据扩展了基础detect输出:
| 任务 | 模型 | 端到端输出 |
|---|---|---|
| 检测 | yolo26n.pt | (N, 300, 6) |
| 分割 | yolo26n-seg.pt | (N, 300, 38) + proto (N, 32, 160, 160) |
| 姿势估计 | yolo26n-pose.pt | (N, 300, 57) |
| OBB | yolo26n-obb.pt | (N, 300, 7) |