Ir al contenido

Comprendiendo la detección de extremo a extremo en Ultralytics YOLO26

Introducción

Si está actualizando a YOLO26 desde un modelo anterior como YOLOv8 o YOLO11, uno de los cambios más significativos que notará es la eliminación de la Supresión No Máxima (NMS). Los modelos YOLO tradicionales producen miles de predicciones superpuestas que requieren un paso de postprocesamiento NMS separado para filtrar y obtener las detecciones finales. Esto añade latencia, complica los gráficos de exportación y puede comportarse de manera inconsistente en diferentes plataformas de hardware.

YOLO26 adopta un enfoque diferente. Emite las detecciones finales directamente desde el modelo, sin necesidad de filtrado externo. Esto se conoce como detección de objetos de extremo a extremo, y está habilitado por defecto en todos los modelos YOLO26. El resultado es una tubería de despliegue más sencilla, menor latencia y hasta un 43% más de velocidad de inferencia en CPU.

Esta guía le explica qué ha cambiado, si necesita actualizar su código, qué formatos de exportación admiten la inferencia de extremo a extremo y cómo migrar sin problemas desde modelos YOLO más antiguos.

Para una visión más profunda de la motivación detrás de este cambio arquitectónico, consulte la publicación del blog de Ultralytics sobre por qué YOLO26 elimina NMS.

Resumen rápido

  • ¿Utiliza la API de Ultralytics o la CLI? No se necesitan cambios, solo cambie el nombre de su modelo a yolo26n.pt.
  • ¿Utiliza código de inferencia personalizado (ONNX Runtime, TensorRT, etc.)? Actualice su postprocesamiento: la salida de detección es ahora (N, 300, 6) en xyxy formato, no se requiere NMS. Otras tareas añaden datos adicionales (coeficientes de máscara, puntos clave o ángulo).
  • ¿Exportando? La mayoría de los formatos admiten la salida de extremo a extremo de forma nativa. Sin embargo, algunos formatos (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX y Edge TPU) recurren automáticamente a la salida tradicional debido a restricciones de operadores no compatibles (por ejemplo, torch.topk).

Cómo funciona la detección de extremo a extremo

YOLO26 utiliza una arquitectura de doble cabezal durante el entrenamiento. Ambos cabezales comparten el mismo backbone y cuello, pero producen salidas de diferentes maneras:

HeadPropósitoSalida de DetecciónPosprocesamiento
Uno a Uno (predeterminado)Inferencia de extremo a extremo(N, 300, 6)Solo umbral de confianza
Uno a MuchosSalida tradicional de YOLO(N, nc + 4, 8400)Requiere NMS

Las formas anteriores son para detección. Otras tareas extienden la salida uno a uno con datos adicionales por detección:

TareaSalida de Extremo a ExtremoDatos Adicionales
Detección(N, 300, 6)
Segmentación(N, 300, 6 + nm) + proto (N, nm, H, W)nm coeficientes de máscara (predeterminado 32)
Pose(N, 300, 57)17 puntos clave × 3 (x, y, visibilidad)
OBB(N, 300, 7)Ángulo de rotación

Durante el entrenamiento, ambas cabezas se ejecutan simultáneamente — la cabeza uno a muchos proporciona una señal de aprendizaje más rica, mientras que la cabeza uno a uno aprende a producir predicciones limpias y no superpuestas. Durante inferencia y export, solo la cabeza uno a uno está activa por defecto, produciendo hasta 300 detecciones por imagen en el formato [x1, y1, x2, y2, confidence, class_id].

Cuando se invoca model.fuse(), pliega las capas Conv + BatchNorm para una inferencia más rápida y, en modelos de extremo a extremo, también elimina la cabeza uno a muchos — reduciendo el tamaño del modelo y los FLOPs. Para más detalles sobre la arquitectura de doble cabeza, consulte la página del modelo YOLO26.

¿Necesito cambiar mi código?

Uso de la API de python de Ultralytics o la CLI

No se necesitan cambios. Si utiliza la API estándar de Ultralytics Python API o la CLI, todo funciona automáticamente — la predicción, la validación y la exportación manejan los modelos de extremo a extremo de forma predeterminada.

No se requieren cambios en el código con la API de 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

Uso de código de inferencia personalizado

Sí, el formato de salida es diferente. Si escribió lógica de postprocesamiento personalizada para YOLOv8 o YOLO11 (por ejemplo, al ejecutar la inferencia con ONNX Runtime o TensorRT), deberá actualizarla para manejar la nueva forma de salida:

YOLOv8 / YOLO11YOLO26 (de extremo a extremo)
Salida de detección(N, nc + 4, 8400)(N, 300, 6)
Formato de cajaxywh (centro x, centro y, ancho, alto)xyxy (x superior izquierda, y superior izquierda, x inferior derecha, y inferior derecha)
DisposiciónCoordenadas de caja + puntuaciones de clase por ancla[x1, y1, x2, y2, conf, class_id]
NMS requeridaNo
PostprocesamientoNMS + filtro de confianzaSolo filtro de confianza

Para tareas de segmentation, pose y obb, YOLO26 añade datos específicos de la tarea a cada detección; consulte la tabla de formas de salida anterior.

Donde N es el tamaño de lote y nc es el número de clases (p. ej., 80 para COCO).

Con los modelos de extremo a extremo, el postprocesamiento se simplifica considerablemente; por ejemplo, al usar 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!

Cambio al cabezal de uno a muchos

Si necesita el formato de salida YOLO tradicional (por ejemplo, para reutilizar código de postprocesamiento existente basado en NMS), puede cambiar al cabezal de uno a muchos en cualquier momento configurando end2end=False:

Uso del cabezal de uno a muchos para la salida tradicional basada en 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

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, incluyendo ONNX, TensorRT, CoreML, OpenVINO, TFLite, TF.js y MNN.

Los siguientes formatos no admiten el procesamiento de extremo a extremo y recurren automáticamente al cabezal de uno a muchos: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX y Edge TPU.

¿Qué sucede cuando el procesamiento de extremo a extremo no es compatible?

Al exportar a uno de estos formatos, Ultralytics cambia automáticamente al cabezal de uno a muchos y registra una advertencia, sin necesidad de intervención manual. Esto significa que necesitará NMS en su pipeline de inferencia para estos formatos, al igual que con YOLOv8 o YOLO11.

TensorRT + INT8

TensorRT admite de extremo a extremo, pero es desactivado automáticamente al exportar con int8=True en TensorRT ≤10.3.0.

Compensaciones entre precisión y velocidad

La detección de extremo a extremo ofrece beneficios significativos en el despliegue con un impacto mínimo en la precisión:

MétricaDe extremo a extremo (predeterminado)De uno a muchos + NMS (end2end=False)
Velocidad de inferencia de CPUHasta un 43% más rápidoLínea de base
Impacto en mAP~0.5 mAP inferiorIguala o supera a YOLO11
PosprocesamientoSolo filtro de confianzaPipeline NMS completo
Complejidad del despliegueMínimoRequiere implementación de NMS

Para la mayoría de las aplicaciones del mundo real, la diferencia de ~0.5 mAP es insignificante, especialmente al considerar las ganancias en velocidad y simplicidad. Si la precisión máxima es su principal prioridad, siempre puede recurrir al cabezal de uno a muchos utilizando end2end=False.

Consulte las métricas de rendimiento de YOLO26 para obtener benchmarks detallados en todos los tamaños de modelo (n, s, m, l, x).

Migración desde YOLOv8 o YOLO11

Si está actualizando un proyecto existente a YOLO26, aquí tiene una lista de verificación rápida para asegurar una transición fluida:

  • Usuarios de la API / CLI de Ultralytics: No se necesitan cambios — solo actualice el nombre del modelo a yolo26n.pt (o yolo26n-seg.pt, yolo26n-pose.pt, yolo26n-obb.pt)
  • Código de postprocesamiento personalizado: Actualice para manejar 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. También tenga en cuenta el cambio de formato de caja de xywh a datos xyxy
  • Pipelines de exportación: Consulte la sección de compatibilidad de formato anterior para su formato de destino
  • TensorRT + INT8: Verifique que su versión de TensorRT sea >10.3.0 para un soporte de extremo a extremo
  • Exportaciones FP16: Si necesita todas las salidas en FP16, exporte con end2end=False — vea por qué output0 permanece en FP32
  • iOS / CoreML: El soporte de extremo a extremo es total. Si necesita soporte de vista previa de Xcode, utilice end2end=False con nms=True
  • Dispositivos de borde (NCNN, RKNN): Estos formatos recurren automáticamente a uno-a-muchos, así que incluya NMS en su pipeline en el dispositivo

Preguntas frecuentes

¿Puedo usar end2end=True y nms=True juntos?

No. Estas opciones son mutuamente excluyentes. Si configura nms=True en un modelo de extremo a extremo durante export, se forzará automáticamente a nms=False con una advertencia. El cabezal de extremo a extremo ya maneja el filtrado de duplicados internamente, por lo que el NMS externo es innecesario.

Sin embargo, end2end=False combinado con nms=True es una configuración válida — integra el NMS tradicional en el grafo de exportación. Esto puede ser útil para las CoreML exportaciones porque le permite usar la función de Vista Previa en Xcode directamente con el modelo de detección.

¿Qué controla el parámetro max_det en los modelos de extremo a extremo?

El max_det parámetro (predeterminado: 300) establece el número máximo de detecciones que el cabezal uno-a-uno puede generar por imagen. Puede ajustarlo en el momento de la inferencia o la exportación:

model.predict("image.jpg", max_det=100)  # fewer detections, slightly faster
model.export(format="onnx", max_det=500)  # more detections for dense scenes

Tenga en cuenta que los puntos de control predeterminados de YOLO26 se entrenaron con max_det=300. Si bien puede aumentar este valor, el cabezal uno-a-uno fue optimizado durante el entrenamiento para producir hasta 300 detecciones limpias, por lo que las detecciones más allá de ese límite pueden ser de menor calidad. Si necesita más de 300 detecciones por imagen, considere reentrenar con un valor de max_det más alto.

Mi modelo ONNX exportado produce (1, 300, 6) — ¿es correcto?

Sí, ese es el formato de salida de extremo a extremo esperado para la detección: tamaño de lote de 1, hasta 300 detecciones, cada una con 6 valores [x1, y1, x2, y2, confidence, class_id]. Simplemente filtre por umbral de confianza y listo — no se necesita NMS.

Para otras tareas, la forma de salida difiere:

TareaForma de SalidaDescripció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

¿Cómo verifico si mi modelo exportado es de extremo a extremo?

Puede verificarlo utilizando la API de python de Ultralytics o inspeccionando directamente los metadatos del modelo ONNX exportado:

Verificar si un modelo es de extremo a extremo

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

Alternativamente, verifique la forma de salida — los modelos de detección de extremo a extremo producen (1, 300, 6), mientras que los modelos tradicionales producen (1, nc + 4, 8400). Para otras formas de tarea, consulte las FAQ sobre formas de salida.

¿Se admite el enfoque de extremo a extremo para tareas de segmentación, pose y obb?

Sí. Todas las variantes de tareas de YOLO26 — detección, segmentación, estimación de pose, y detección de objetos orientados (obb) — admiten la inferencia de extremo a extremo por defecto. El end2end=False mecanismo de respaldo también está disponible para todas las tareas.

Cada tarea extiende la salida de detección base con datos específicos de la tarea:

TareaModeloSalida de Extremo a Extremo
Detecciónyolo26n.pt(N, 300, 6)
Segmentaciónyolo26n-seg.pt(N, 300, 38) + proto (N, 32, 160, 160)
Poseyolo26n-pose.pt(N, 300, 57)
OBByolo26n-obb.pt(N, 300, 7)


📅 Creado hace 13 días ✏️ Actualizado hace 11 días
glenn-jocherraimbekovm

Comentarios