了解 Ultralytics YOLO26 中的端到端检测#
如果你正在从之前的模型(例如 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 和 QNN)由于不受支持的算子限制(例如
torch.topk),会自动回退到传统输出。Hailo HEF 工作流是从带有 Hailo 特定脚本的 ONNX 编译而来的,因此请验证你的模型的检测头和 NMS 配置。
端到端检测的工作原理#
YOLO26 在训练期间使用双头架构。两个头共享相同的骨干网络和颈部网络,但以不同的方式产生输出:
| 检测头 | 用途 | 检测输出 | 后处理 |
|---|---|---|---|
| 一对一 (默认) | 端到端推理 | (N, 300, 6) | 仅置信度阈值 |
| 一对多 | 传统 YOLO 输出 | (N, nc + 4, 8400) | 需要 NMS |
上面的形状适用于检测。其他任务通过每个检测的附加数据来扩展一一对应(one-to-one)输出:
| 任务 | 端到端输出 | 额外数据 |
|---|---|---|
| Detection | (N, 300, 6) | — |
| 实例分割 | (N, 300, 6 + nm) + 原型 (N, nm, H, W) | nm 掩码系数(默认 32) |
| Pose | (N, 300, 57) | 17 个关键点 × 3 (x, y, 可见性) |
| OBB | (N, 300, 7) | 旋转角度 |
在训练期间,两个头同时运行——多对一(one-to-many)头提供更丰富的学习信号,而一一对应头则学习产生干净、不重叠的预测。在推理和导出期间,默认只有一一对应头处于活跃状态,每张图像以 [x1, y1, x2, y2, confidence, class_id] 格式产生多达 300 个检测结果。
当你调用 model.fuse() 时,它会折叠 Conv + BatchNorm 层以加快推理速度,并且在端到端模型上,还会移除多对一头——从而减小模型大小和 FLOPs。有关双头架构的更多详细信息,请参阅 YOLO26 模型页面。
我需要更改代码吗?#
使用 Ultralytics Python API 或 CLI#
无需更改。 如果你使用标准的 Ultralytics Python API 或 CLI,一切都会自动运行——预测、验证和导出开箱即用地处理端到端模型。
from ultralytics import YOLO
# Load a YOLO26 model
model = YOLO("yolo26n.pt")
# Predict — no NMS step, no code changes
results = model.predict("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 + 置信度过滤器 | 仅置信度过滤器 |
对于分割、姿态和 OBB 任务,YOLO26 会向每个检测附加特定于任务的数据——请参阅输出形状表。
其中 N 是批量大小,nc 是类别数(例如,COCO 的 80 个)。
对于端到端模型,后处理变得简单得多——例如,在使用 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 切换到它:
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)导出格式兼容性#
大多数导出格式开箱即生地支持端到端推理,包括 ONNX、TensorRT、CoreML、OpenVINO、LiteRT 和 MNN。
以下格式不支持端到端,并且会自动回退到多对一头:NCNN、RKNN、PaddlePaddle、ExecuTorch、IMX、Edge TPU 和 Qualcomm QNN。
对于 Hailo HEF,编译步骤在 ONNX 导出之后的 model.export(format=...) 外部进行。请使用与你的确切检测模型相匹配的 Hailo DFC 日志、.alls 模型脚本和 NMS JSON;如果你的 Hailo 工具链不支持端到端 YOLO26 图,请使用 end2end=False 导出 ONNX 模型并编译传统检测头。
TensorRT 支持端到端,但在 JetPack 6 上的 TensorRT 10.3.0 上使用 quantize=8 导出时,它会被自动禁用。
准确性和速度权衡#
端到端检测在对准确率影响极小的情况下,提供了显著的部署优势:
| 指标 | 端到端(默认) | 多对一 + NMS (end2end=False) |
|---|---|---|
| CPU 推理速度 | 最高提升 43% | 基准 |
| mAP 影响 | 约 0.5 mAP 降低 | 匹配或超过 YOLO11 |
| 后处理 | 仅置信度过滤器 | 完整的 NMS 流水线 |
| 部署复杂度 | 最小 | 需要实现 NMS |
对于大多数实际应用来说,~0.5 的 mAP 差异可以忽略不计,特别是考虑到速度和简单性的提升。如果最高准确率是你的首要任务,你随时可以使用 end2end=False 回退到多对一头。
有关所有模型大小(n、s、m、l、x)的详细基准测试,请参阅 YOLO26 性能指标。
从 YOLOv8 或 YOLO11 迁移#
如果你正在将现有项目升级到 YOLO26,这里有一份简要清单以确保平滑过渡:
- Ultralytics API / CLI 用户: 无需更改——只需将模型名称更新为
yolo26n.pt(或yolo26n-seg.pt、yolo26n-pose.pt、yolo26n-obb.pt) - 自定义后处理代码: 更新以处理新的输出形状——用于检测的
(N, 300, 6),加上用于分割、姿态和 OBB 的特定于任务的数据。同时请注意框格式从xywh到xyxy的更改 - 导出管道: 检查你的目标格式的格式兼容性部分
- TensorRT + INT8: 在 JetPack 6 上,TensorRT 10.3.0 会随
quantize=8自动禁用端到端——请使用不同的 TensorRT 版本来保持端到端 - FP16 导出: 如果你需要 FP16 中的所有输出,请使用
end2end=False进行导出——请参阅为什么 output0 保持为 FP32 - iOS / CoreML: 完全支持端到端。如果你需要 Xcode 预览支持,请将
end2end=False与nms=True一起使用 - 边缘设备 (NCNN, RKNN): 这些格式会自动回退到一对多,因此请在你的设备端流水线中包含 NMS
结论#
端到端检测是 YOLO26 中的默认设置,如果你使用 Ultralytics Python API 或 CLI,则不需要更改代码。只有自定义后处理管道需要更新以读取新的 (N, 300, 6) 输出并放弃 NMS 步骤——除了回退到多对一输出的导出格式(如 NCNN 和 RKNN),它们仍然需要在设备上进行 NMS。有关所有模型大小的详细速度和准确率基准测试,请参阅 YOLO26 模型页面;有关导出选项和格式的完整集合,请参阅导出模式文档。
常见问题解答#
我能同时使用 end2end=True 和 nms=True 吗?#
不是。这些选项是互斥的。如果你在导出时为端到端模型设置了 nms=True,它将自动强制为 nms=False 并发出警告。端到端头已经型内部处理了重复过滤,因此外部 NMS 是不必要的。
然而,end2end=False 结合 nms=True 是一个有效的配置——它将传统的 NMS 烘焙到导出图中。这对于 CoreML 导出非常有用,因为它允许你直接将 Xcode 中的预览功能与检测模型一起使用。
在端到端模型中,max_det 参数控制什么?#
max_det 参数(默认值:300)设置每张图像返回的最大检测数。你可以在推理或导出时对其进行调整:
model.predict("image.jpg", max_det=100) # fewer detections
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 个掩码系数,外加一个原型掩码张量 |
| 姿态 | (1, 300, 57) | 6 个框值 + 17 个关键点 × 3 (x, y, 可见度) |
| 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或者,检查输出形状——端到端检测模型输出 (1, 300, 6),而传统模型输出 (1, nc + 4, 8400)。有关其他任务形状,请参阅输出形状常见问题解答。
实例分割、姿态估计和 OBB 任务是否支持端到端?#
是的。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) |