Comprender la detección integral en Ultralytics YOLO26#
Los modelos de tipo de detección de YOLO26 —detección, segmentación, pose y OBB— vienen sin NMS por defecto: emiten las detecciones finales directamente desde el modelo, sin un paso posterior de Non-Maximum Suppression (NMS). Modelos anteriores como YOLOv8 y YOLO11 producen miles de predicciones superpuestas que un paso de NMS independiente debe filtrar, lo que añade latencia, complica los grafos de exportación y puede comportarse de forma incoherente en distintas plataformas de hardware.
Esto se conoce como detección de objetos de extremo a extremo y se activa por defecto. El resultado es un proceso de despliegue más sencillo y una menor latencia: YOLO26n se ejecuta hasta un 43 % más rápido que YOLO11n en inferencia ONNX en CPU (Intel Xeon CPU a 2,00 GHz).
Esta guía te explica qué ha cambiado, si necesitas actualizar tu código, qué formatos de exportación admiten inferencia integral y cómo migrar sin problemas desde modelos YOLO antiguos.
Para profundizar en la motivación detrás de este cambio arquitectónico, consulta la entrada del blog de Ultralytics sobre por qué YOLO26 elimina NMS.
- ¿Usas la API o la CLI de Ultralytics? No necesitas hacer ningún cambio; solo tienes que cambiar el nombre de tu modelo por
yolo26n.pt. - ¿Usas código de inferencia personalizado (ONNX Runtime, TensorRT, etc.)? Actualiza tu postprocesamiento: la salida de detección es ahora
(N, 300, 6)en formatoxyxy, sin necesidad de NMS. Otras tareas añaden datos adicionales (coeficientes de máscara, puntos clave o ángulo). - ¿Vas a exportar? La mayoría de los formatos conservan la salida de extremo a extremo de forma nativa; algunos vuelven a la salida tradicional y la cuantización puede deshabilitarla; consulta Compatibilidad de formatos de exportación.
Cómo funciona la detección integral#
YOLO26 utiliza una arquitectura de doble cabezal durante el entrenamiento. Ambos cabezales comparten el mismo esqueleto (backbone) y cuello (neck), pero producen salidas de formas diferentes:
| Cabezal | Propósito | Salida de detección | Postprocesamiento |
|---|---|---|---|
| One-to-One (por defecto) | Inferencia integral | (N, 300, 6) | Solo umbral de confianza |
| One-to-Many | Salida YOLO tradicional | (N, nc + 4, 8400) | Requiere NMS |
Las formas anteriores corresponden a la detección, donde N es el tamaño de lote, nc es el número de clases (por ejemplo, 80 para COCO) y el recuento de 8400 anclajes es el valor en imgsz=640. Otras tareas amplían la salida uno a uno con datos adicionales por detección:
| Tarea | Salida integral | Datos adicionales |
|---|---|---|
| Detection | (N, 300, 6) | — |
| Instance Segmentation | (N, 300, 6 + nm) + proto (N, nm, H, W) | coeficientes de máscara de nm (predeterminado 32) |
| Pose | (N, 300, 57) | 17 puntos clave × 3 (x, y, visibilidad) |
| OBB | (N, 300, 7) | Ángulo de rotación |
Durante el entrenamiento, ambos cabezales se ejecutan simultáneamente: el cabezal de uno a muchos proporciona una señal de aprendizaje más rica, mientras que el cabezal de uno a uno aprende a producir predicciones limpias y sin superposiciones. Durante la inferencia y la exportación, solo el cabezal de uno a uno está activo de forma predeterminada, produciendo hasta 300 detecciones por imagen en el formato [x1, y1, x2, y2, confidence, class_id].
Cuando llamas a model.fuse(), se combinan las capas Conv + BatchNorm para acelerar la inferencia y, en los modelos de extremo a extremo, también se elimina el cabezal de uno a muchos, lo que reduce el tamaño del modelo y las FLOPs. Para obtener más detalles sobre la arquitectura de doble cabezal, consulta la página del modelo YOLO26.
¿Necesito cambiar mi código?#
Usando la API de Python o la CLI de Ultralytics#
No se necesitan cambios. Si utilizas la API de Python de Ultralytics o la CLI estándar, todo funciona automáticamente: la predicción, la validación y la exportación gestionan los modelos de extremo a extremo de forma nativa.
from ultralytics import YOLO
# Load a YOLO26 model
model = YOLO("yolo26n.pt")
# Predict — no NMS step, no code changes
results = model.predict("image.jpg")Usando código de inferencia personalizado#
Sí, el formato de salida es diferente. Si escribiste una lógica de postprocesamiento personalizada para YOLOv8 o YOLO11 (por ejemplo, al ejecutar inferencias con ONNX Runtime o TensorRT), tendrás que actualizarla para que admita la nueva forma de salida:
| YOLOv8 / YOLO11 | YOLO26 (integral) | |
|---|---|---|
| Salida de detección | (N, nc + 4, 8400) | (N, 300, 6) |
| Formato de caja | xywh (centro x, centro y, ancho, alto) | xyxy (superior izquierdo x, superior izquierdo y, inferior derecho x, inferior derecho y) |
| Disposición | Coordenadas de caja + puntuaciones de clase por ancla | [x1, y1, x2, y2, conf, class_id] |
| NMS requerido | Sí | No |
| Postprocesamiento | NMS + filtro de confianza | Solo filtro de confianza |
Para las tareas de segmentación, pose y OBB, YOLO26 adjunta datos específicos de la tarea a cada detección; consulta la tabla de formas de salida.
Con los modelos de extremo a extremo, el postprocesamiento se vuelve mucho más sencillo; por ejemplo, al utilizar 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] > 0.25] # confidence filter, no NMSCambiar al cabezal One-to-Many#
Si necesitas el formato de salida YOLO tradicional (por ejemplo, para reutilizar código de postprocesamiento basado en NMS existente), puedes cambiar al cabezal de uno a muchos cuando esté disponible configurando 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)Compatibilidad del formato de exportación#
La mayoría de los formatos de exportación admiten la inferencia de extremo a extremo de forma nativa, incluidos ONNX, TensorRT, CoreML, OpenVINO, LiteRT y MNN.
Los siguientes formatos no admiten el extremo a extremo y recurren automáticamente al cabezal de uno a muchos: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU y Qualcomm QNN.
Para Hailo, el exportador selecciona la ruta de salida de la cabeza cargada en lugar de un argumento, por lo que se rechaza end2end si se proporciona: un modelo de detección YOLO26 predeterminado mantiene sus salidas uno a uno sin NMS, mientras que un punto de control cuya cabeza ya es end2end=False compila la ruta tradicional con NMS de HailoRT.
TensorRT y LiteRT admiten el extremo a extremo, pero la rama se deshabilita automáticamente en versiones de TensorRT anteriores a la 8.5.0, en TensorRT 10.3.0 con quantize=8 en JetPack 6 y en LiteRT con quantize=8 o quantize="w8a16". En cada caso, se registra una advertencia y se exporta la cabeza de uno a varios.
Compromisos entre precisión y velocidad#
La detección de extremo a extremo ofrece importantes ventajas de despliegue con un impacto mínimo en la precisión:
| Métrica | Integral (por defecto) | Uno a muchos + NMS (end2end=False) |
|---|---|---|
| mAPval de COCO | 0,6-0,8 menos | Base |
| Postprocesamiento | Solo filtro de confianza | Pipeline NMS completo |
| Complejidad de despliegue | Mínima | Requiere implementación de NMS |
En las cinco escalas de detección, la cabeza de uno a uno cuesta de 0,6 a 0,8 de mAP en COCO —de 40,9 a 40,1 para YOLO26n y de 57,5 a 56,9 para YOLO26x— a cambio de eliminar por completo la pasada de NMS. Si la máxima precisión es tu prioridad, vuelve a la cabeza de uno a varios con end2end=False.
Consulta las métricas de rendimiento de YOLO26 para ver pruebas comparativas detalladas en todos los tamaños de modelo (n, s, m, l, x).
Migración desde YOLOv8 o YOLO11#
Si estás actualizando un proyecto existente a YOLO26:
- Usuarios de la API / CLI de Ultralytics: No se necesitan cambios; solo actualiza el nombre del modelo a
yolo26n.pt(oyolo26n-seg.pt,yolo26n-pose.pt,yolo26n-obb.pt) - Código de postprocesamiento personalizado: Actualízalo para gestionar las nuevas formas de salida:
(N, 300, 6)para detección, además de datos específicos de la tarea para segmentación, pose y OBB. Ten en cuenta también el cambio de formato de caja dexywhaxyxy - Tuberías de exportación: Consulta la sección de compatibilidad de formatos para tu formato de destino
- TensorRT anterior a la 8.5.0: el extremo a extremo se deshabilita en todas las precisiones; actualiza TensorRT a la versión 8.5.0 o posterior para conservarlo
- Exportaciones cuantizadas: TensorRT 10.3.0 con
quantize=8en JetPack 6 y LiteRT conquantize=8oquantize="w8a16"deshabilitan automáticamente el extremo a extremo; exporta a una precisión mayor para conservarlo - Exportaciones en FP16: Si necesitas todas las salidas en FP16, exporta con
end2end=False; consulta por qué output0 se queda en FP32 - iOS / CoreML: El extremo a extremo es totalmente compatible. Si necesitas soporte para Xcode Preview, utiliza
end2end=Falseconnms=True - Dispositivos Edge (NCNN, RKNN): Estos formatos vuelven automáticamente al modo one-to-many, así que incluye NMS en tu pipeline en el dispositivo
Conclusión#
La detección de extremo a extremo es el valor predeterminado en YOLO26 y no requiere cambios de código si utilizas la API de Python de Ultralytics o la CLI. Solo las tuberías de postprocesamiento personalizadas necesitan actualizarse para leer la nueva salida de (N, 300, 6) y omitir el paso de NMS, excepto para los formatos de exportación que recurren a la salida de uno a muchos (como NCNN y RKNN), los cuales siguen requiriendo NMS en el dispositivo. Para obtener pruebas comparativas detalladas de velocidad y precisión en todos los tamaños de modelo, consulta la página del modelo YOLO26, y para ver el conjunto completo de opciones y formatos de exportación, consulta la documentación del modo de exportación.
FAQ#
No. Estas opciones son mutuamente excluyentes. Si configuras
nms=Trueen un modelo de extremo a extremo durante la exportación, se forzará automáticamente anms=Falsecon una advertencia. El cabezal de extremo a extremo ya gestiona el filtrado de duplicados internamente, por lo que el NMS externo es innecesario.Sin embargo,
end2end=Falsecombinado connms=Truees una configuración válida, ya que integra el NMS tradicional en el grafo de exportación. Esto puede ser útil para las exportaciones de CoreML porque te permite usar la función Preview en Xcode directamente con el modelo de detección.El parámetro
max_det(predeterminado: 300) establece el número máximo de detecciones devueltas por imagen. Puedes ajustarlo en el momento de la inferencia o de la exportación:model.predict("image.jpg", max_det=100) # fewer detections model.export(format="onnx", max_det=500) # more detections for dense scenesEl valor se integra en el grafo exportado como el top-k de la cabeza, por lo que
max_det=500amplía el tensor de salida hasta(1, 500, 6), limitado por el recuento de anclajes.Sí, ese es el formato de salida de extremo a extremo esperado para la detección: un tamaño de lote de 1, hasta 300 detecciones, cada una con 6 valores
[x1, y1, x2, y2, confidence, class_id]. Simplemente filtra por el umbral de confianza; no se necesita NMS.Para otras tareas, la forma de salida es diferente:
Tarea Forma de salida Descripción Detección (1, 300, 6)[x1, y1, x2, y2, conf, class_id]Segmentación (1, 300, 38)+(1, 32, 160, 160)6 valores de caja + 32 coeficientes de máscara, más un tensor de máscara prototipo Pose (1, 300, 57)6 valores de caja + 17 puntos clave × 3 (x, y, visibilidad) OBB (1, 300, 7)6 valores de caja + 1 ángulo de rotación Puedes comprobarlo desde la API de Python de Ultralytics o desde los metadatos del modelo ONNX exportado:
Comprobar si un modelo es de extremo a extremofrom 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 enabledLas dos comprobaciones responden a preguntas diferentes: los metadatos de ONNX registran la cabeza que se exportó, mientras que
predictor.model.end2endinforma de que la salida del backend ya está posprocesada y no necesita ningún NMS externo. No coinciden en el caso de un modelo exportado conend2end=False, nms=True, que utiliza la cabeza de uno a varios pero incorpora el NMS en el grafo y también emite(1, 300, 6), por lo que ni el indicador ni la forma de salida por sí solos identifican la cabeza. Para ver las formas de otras tareas, consulta las preguntas frecuentes sobre formas de salida.Sí. Las variantes de tareas de estilo de detección de YOLO26 (detección, segmentación de instancias, estimación de pose y detección de objetos orientados (OBB)) admiten la inferencia de extremo a extremo de forma predeterminada. El respaldo de
end2end=Falsetambién está disponible en estas tareas.Cada tarea amplía la salida de detección base con datos específicos de la tarea; las formas de salida de
yolo26n.pt,yolo26n-seg.pt,yolo26n-pose.ptyyolo26n-obb.ptse enumeran en Cómo funciona la detección de extremo a extremo.