了解 Ultralytics YOLO26 的端到端检测#
YOLO26 同时训练 one-to-many 头和 one-to-one 头。默认情况下,预测和验证使用 one-to-many 头,并执行非极大值抑制(NMS)。这样可以在使用相同训练权重的同时提高准确率。将 nms=False 设为使用速度更快、无需 NMS 的 one-to-one 头。
一个参数即可控制预测、验证、跟踪、导出和基准测试所使用的路径:
nms | 预测和验证 | 导出 |
|---|---|---|
None(默认) | One-to-many 头;Ultralytics 执行 NMS | 原始 one-to-many 输出;由调用方执行 NMS |
True | 与 None 相同 | 支持时使用内嵌 NMS 的 one-to-many 头 |
False | 不进行 IoU 抑制的 one-to-one 头 | 支持时输出无需 NMS 的 one-to-one 结果 |
None 表示模型中没有嵌入可选的后处理。它不会移除将模型输出转换为预测结果或验证指标的常规处理。分类、语义分割、深度估计以及没有可选检测头的模型,仍会采用各自任务的原生行为。
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
results = model.predict("image.jpg") # one-to-many + NMS
metrics = model.val(data="coco.yaml") # one-to-many + NMS
results = model.predict("image.jpg", nms=False) # 选择使用无 NMS 推理
results = model.predict("image.jpg", nms=None) # 切回 one-to-many + NMS
model.export(format="onnx") # 原始 one-to-many 输出
model.export(format="onnx", nms=True) # 嵌入 NMS
model.export(format="onnx", nms=False) # 无需 NMS 的 one-to-one 输出端到端检测的工作原理#
两个检测头共享骨干网络和颈部网络,并在训练期间共同优化。one-to-many 头为每个目标提供多个候选预测;NMS 会移除重叠的检测结果。one-to-one 头则学习为每个目标生成单个预测。选择推理路径不会禁用双头监督。训练期间的验证会使用所选推理头,因此检查点选择和提前停止依据的预测结果与部署时相同。
| 深度头 | 外部处理前的检测输出 | 处理 |
|---|---|---|
| One-to-many(默认) | (N, nc + 4, 8400) | 置信度筛选和 NMS |
| One-to-one | (N, 300, 6) | 置信度筛选;不进行 IoU 抑制 |
这里,N 表示批次大小,nc 表示类别数,而 8400 是 imgsz=640 时的候选数量。One-to-one 检测行包含 [x1, y1, x2, y2, confidence, class_id]。其他检测任务还包含额外输出:
| 任务 | 端到端输出 | 额外数据 |
|---|---|---|
| 检测 | (N, 300, 6) | — |
| 实例分割 | (N, 300, 6 + nm) 和 (N, nm, H, W) | 掩码系数和原型 |
| 姿态 | (N, 300, 57) | 17 个关键点 × 3 个值 |
| OBB | (N, 300, 7) | 旋转角度 |
融合会移除未使用的推理分支,并折叠 Conv 和 BatchNorm 层。如果你需要切换检测头,请保留原始训练检查点:分支一旦移除,就无法通过融合还原。仅保留单对一检测头的模型仍可使用该路径。
导出输出#
YOLOv8、YOLO11 和 YOLO26 检测模型默认导出原始的一对多预测。使用 nms=False 导出 YOLO26,可获得无需 NMS 的检测结果。
nms=None | nms=False | |
|---|---|---|
| 检测输出 | (N, nc + 4, 8400) | (N, 300, 6) |
| 边界框格式 | xywh | xyxy |
| 分数 | 每个候选框对应每个类别的一个分数 | 每个检测结果对应一个置信度和类别 ID |
| 外部处理 | 置信度筛选和 NMS | 置信度筛选 |
nms=True 也会生成经过处理的检测结果,但使用一对多检测头并嵌入传统 NMS。如果你希望部署运行时直接接收检测结果,而无需自行实现抑制操作,这种方式就很有用。
导出模型的计算图决定了模型的输出。加载模型时传入 nms 不会重建计算图;要选择输出路径,请使用所需的 nms 值导出源检查点。Ultralytics 会使用模型制品的元数据,避免重复应用 NMS。
导出格式兼容性#
ONNX、TensorRT、CoreML、OpenVINO 等多种格式都支持无 NMS 导出。如果格式的算子无法支持端到端输出,NCNN、RKNN、PaddlePaddle、ExecuTorch、IMX、Edge TPU 和 Qualcomm QNN 会回退到一对多路径。格式警告会说明回退原因。
- 内嵌 NMS:
nms=True受各格式的任务、精度和动态形状限制。不支持内嵌 NMS 的格式会导出原生输出,以便进行外部处理。 - CoreML: 内嵌 NMS 支持静态形状下的检测、分割和姿态任务。对于需要使用 Xcode Preview 的 NMS 流程的检测模型,请使用
nms=True。 - MNN: 内嵌 NMS 使用
dynamic=False时支持检测和姿态任务。 - IMX: 检测、实例分割和姿态任务需要内嵌 NMS,系统会自动选择该选项。
- Hailo: YOLO26 默认使用原始张量和主机端 NMS;
nms=False会选择其一对一路径。YOLOv8/YOLO11 检测使用 HailoRT NMS。 - 量化: TensorRT 8.5.0 之前的版本、JetPack 6 上的 TensorRT 10.3.0 INT8,以及 LiteRT INT8 或
w8a16会回退到一对多输出。
硬件要求请参阅各个集成指南。如需完整的 FP16 输出张量,请使用 nms=None;即使模型经过量化,端到端类别索引也可能使输出张量保持 FP32。
精度与速度的权衡#
已发布的 YOLO26 COCO 结果显示,在五种模型尺寸上,一对多检测头可将检测 mAP 提高 0.6–0.8 个点:例如,YOLO26n 为 40.9,而非 40.1;YOLO26x 为 57.5,而非 56.9。一对一检测头省去了 NMS 步骤,更有利于降低延迟。这些结果为默认设置提供了依据,但不能保证在每个数据集上都能提升。
已发布的无 NMS 速度测量结果使用 nms=False。比较精度和延迟时,请确保检测头选择、图像尺寸、精度和硬件相同。
常见问题#
它会限制预测和验证返回的检测结果数量。对于端到端和内嵌 NMS 导出,该限制属于计算图的一部分,因此要更改限制就需要重新导出;CoreML 检测的内嵌 NMS 是例外,没有检测数量上限。如果图像提供的锚点少于
max_det,端到端输出中的候选框数量可能会更少。是的,如果使用
nms=False或nms=True,并采用默认检测数量限制,就会得到这种结果。仅凭形状无法判断导出的是哪个检测头。默认的原始 COCO 检测导出通常会在imgsz=640处具有(1, 84, 8400)形状。是的。对于检测、实例分割、姿态和 OBB,同一个
nms参数都会选择可用的检测头。它不会取代掩码重建、关键点解码、旋转框处理、分类概率、语义类别图或深度解码。