Link to this sectionComprender la detección integral en Ultralytics YOLO26#
Link to this sectionIntroducción#
Si vas a actualizar a YOLO26 desde un modelo anterior como YOLOv8 o YOLO11, uno de los cambios más importantes que notarás es la eliminación de la Supresión No Máxima (NMS, por sus siglas en inglés). Los modelos YOLO tradicionales producen miles de predicciones superpuestas que necesitan un paso de postprocesamiento NMS separado para filtrar hasta llegar a las detecciones finales. Esto añade latencia, complica los grafos de exportación y puede comportarse de forma inconsistente en diferentes plataformas de hardware.
YOLO26 adopta un enfoque diferente. Genera las detecciones finales directamente desde el modelo, sin necesidad de filtrado externo. Esto se conoce como detección de objetos integral (end-to-end) y está habilitado por defecto en todos los modelos YOLO26. El resultado es un pipeline de despliegue más sencillo, menor latencia y una inferencia hasta un 43% más rápida en CPUs.
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 y cómo eso cambia el despliegue.
- ¿Utilizas la API o la CLI de Ultralytics? No necesitas realizar cambios; simplemente cambia el nombre de tu modelo a
yolo26n.pt. - ¿Utilizas 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 extra (coeficientes de máscara, puntos clave o ángulo). - ¿Estás exportando? La mayoría de los formatos admiten la salida integral de forma nativa. Sin embargo, algunos formatos (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU y QNN) vuelven automáticamente a la salida tradicional debido a restricciones de operadores no soportados (por ejemplo,
torch.topk). Los flujos de trabajo de Hailo HEF se compilan desde ONNX con scripts específicos de Hailo, así que verifica la configuración del cabezal de detección y de NMS para tu modelo.
Link to this sectionCómo funciona la detección integral#
YOLO26 utiliza una arquitectura de doble cabezal durante el entrenamiento. Ambos cabezales comparten el mismo backbone y cuello, 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 son para detección. Otras tareas amplían la salida one-to-one con datos adicionales por cada detección:
| Tarea | Salida integral | Datos adicionales |
|---|---|---|
| Detección | (N, 300, 6) | — |
| Segmentación de instancias | (N, 300, 6 + nm) + proto (N, nm, H, W) | nm coeficientes de máscara (por defecto 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 funcionan simultáneamente: el cabezal one-to-many proporciona una señal de aprendizaje más rica, mientras que el cabezal one-to-one aprende a producir predicciones limpias y sin superposiciones. Durante la inferencia y la exportación, solo el cabezal one-to-one está activo por defecto, produciendo hasta 300 detecciones por imagen en el formato [x1, y1, x2, y2, confidence, class_id].
Cuando llamas a model.fuse(), se pliegan las capas Conv + BatchNorm para una inferencia más rápida y, en los modelos integrales, también se elimina el cabezal one-to-many, reduciendo el tamaño del modelo y los FLOPs. Para obtener más detalles sobre la arquitectura de doble cabezal, consulta la página del modelo YOLO26.
Link to this section¿Necesito cambiar mi código?#
Link to this sectionUsando la API de Python o la CLI de Ultralytics#
No se necesitan cambios. Si utilizas la API de Python de Ultralytics estándar o la CLI, todo funciona automáticamente: la predicción, la validación y la exportación gestionan los modelos integrales de forma inmediata.
from ultralytics import YOLO
# Load a YOLO26 model
model = YOLO("yolo26n.pt")
# Predict — no NMS step, no code changes
results = model.predict("image.jpg")Link to this sectionUsando 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 la inferencia con ONNX Runtime o TensorRT), necesitarás actualizarla para gestionar la nueva forma de salida:
| YOLOv8 / YOLO11 | YOLO26 (integral) | |
|---|---|---|
| Salida de detección | (N, nc + 4, 8400) | (N, 300, 6) |
| Formato de caja | xywh (x central, y central, ancho, alto) | xyxy (x superior izquierda, y superior izquierda, x inferior derecha, y inferior derecha) |
| 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 tareas de segmentación, pose y OBB, YOLO26 añade datos específicos de la tarea a cada detección; consulta la tabla de formas de salida anterior.
Donde N es el tamaño de lote y nc es el número de clases (por ejemplo, 80 para COCO).
Con los modelos integrales, el postprocesamiento se vuelve mucho más sencillo; 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!Link to this sectionCambiar al cabezal One-to-Many#
Si necesitas el formato de salida YOLO tradicional (por ejemplo, para reutilizar código de postprocesamiento existente basado en NMS), puedes cambiar al cabezal one-to-many en cualquier momento 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)Link to this sectionCompatibilidad del formato de exportación#
La mayoría de los formatos de exportación admiten inferencia integral de forma inmediata, incluyendo ONNX, TensorRT, CoreML, OpenVINO, TFLite, TF.js y MNN.
Los siguientes formatos no admiten el modo integral y vuelven automáticamente al cabezal one-to-many: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU y Qualcomm QNN.
Para Hailo HEF, el paso de compilación ocurre fuera de model.export(format=...) tras una exportación a ONNX. Utiliza los registros de Hailo DFC, el script de modelo .alls y el JSON de NMS que coincidan exactamente con tu modelo de detección; si tu cadena de herramientas de Hailo no admite un grafo integral de YOLO26, exporta el modelo ONNX con end2end=False y compila el cabezal de detección tradicional.
TensorRT admite el modo integral, pero se desactiva automáticamente al exportar con int8=True en TensorRT 10.3.0 en JetPack 6.
Link to this sectionCompromisos entre precisión y velocidad#
La detección integral proporciona beneficios significativos en el despliegue con un impacto mínimo en la precisión:
| Métrica | Integral (por defecto) | One-to-Many + NMS (end2end=False) |
|---|---|---|
| Velocidad de inferencia en CPU | Hasta un 43% más rápida | Base |
| Impacto en mAP | ~0.5 mAP menos | Iguala o supera a YOLO11 |
| Postprocesamiento | Solo filtro de confianza | Pipeline NMS completo |
| Complejidad de despliegue | Mínima | Requiere implementación de NMS |
Para la mayoría de las aplicaciones del mundo real, la diferencia de ~0.5 mAP es insignificante, especialmente si consideramos las ganancias en velocidad y simplicidad. Si tu prioridad principal es la máxima precisión, siempre puedes volver al cabezal one-to-many usando end2end=False.
Consulta las métricas de rendimiento de YOLO26 para ver benchmarks detallados en todos los tamaños de modelo (n, s, m, l, x).
Link to this sectionMigración desde YOLOv8 o YOLO11#
Si vas a actualizar un proyecto existente a YOLO26, aquí tienes una lista de verificación rápida para asegurar una transición sin problemas:
- Usuarios de la API / CLI de Ultralytics: No se requieren cambios; simplemente 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 manejar las nuevas formas de salida:
(N, 300, 6)para detección, además de los datos específicos de la tarea para segmentación, pose y OBB. Ten en cuenta también el cambio de formato de caja dexywhaxyxy - Pipelines de exportación: Revisa la sección compatibilidad de formato anterior para tu formato objetivo
- TensorRT + INT8: En JetPack 6, TensorRT 10.3.0 desactiva automáticamente el modo integral con
int8=True; utiliza una versión diferente de TensorRT para mantener el modo integral - Exportaciones FP16: Si necesitas todas las salidas en FP16, exporta con
end2end=False; consulta por qué output0 permanece en FP32 - iOS / CoreML: El modo integral es totalmente compatible. Si necesitas compatibilidad con la vista previa de Xcode, usa
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
Link to this sectionFAQ#
Link to this section¿Puedo usar end2end=True y nms=True juntos?#
No. Estas opciones son mutuamente excluyentes. Si configuras nms=True en un modelo integral durante la exportación, se forzará automáticamente a nms=False con una advertencia. El cabezal integral ya gestiona internamente el filtrado de duplicados, por lo que el NMS externo es innecesario.
Sin embargo, end2end=False combinado con nms=True es una configuración válida; esto incorpora el NMS tradicional en el grafo de exportación. Esto puede ser útil para exportaciones a CoreML porque permite usar la función de vista previa en Xcode directamente con el modelo de detección.
Link to this section¿Qué controla el parámetro max_det en los modelos de extremo a extremo?#
El parámetro max_det (predeterminado: 300) establece el número máximo de detecciones que el head one-to-one puede generar por imagen. Puedes ajustarlo durante la inferencia o al exportar:
model.predict("image.jpg", max_det=100) # fewer detections, slightly faster
model.export(format="onnx", max_det=500) # more detections for dense scenesTen en cuenta que los checkpoints predeterminados de YOLO26 se entrenaron con max_det=300. Aunque puedes aumentar este valor, el head one-to-one se optimizó durante el entrenamiento para producir hasta 300 detecciones limpias, por lo que las detecciones que superen ese límite podrían tener una calidad inferior. Si necesitas más de 300 detecciones por imagen, considera volver a entrenar con un valor de max_det más alto.
Link to this sectionMi modelo ONNX exportado genera (1, 300, 6) —¿es correcto?#
Sí, es el formato de salida esperado de extremo a extremo para detección: tamaño del lote de 1, hasta 300 detecciones, cada una con 6 valores [x1, y1, x2, y2, confidence, class_id]. Simplemente filtra por umbral de confianza y listo: no necesitas 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 |
Link to this section¿Cómo compruebo si mi modelo exportado es de extremo a extremo?#
Puedes comprobarlo usando la API de Python de Ultralytics o inspeccionando directamente los metadatos del modelo ONNX exportado:
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 enabledAlternativamente, comprueba la forma de la salida: los modelos de detección de extremo a extremo generan (1, 300, 6), mientras que los modelos tradicionales generan (1, nc + 4, 8400). Para las formas de otras tareas, consulta las preguntas frecuentes sobre formas de salida.
Link to this section¿Es compatible el extremo a extremo con tareas de segmentación de instancias, pose y OBB?#
Sí. Las variantes de tareas estilo detección de YOLO26 (detección, segmentación de instancias, estimación de pose y detección de objetos orientados (OBB)) admiten inferencia de extremo a extremo de forma predeterminada. El fallback end2end=False también está disponible para estas tareas.
Cada tarea extiende la salida base de detección con datos específicos de la tarea:
| Tarea | Modelo | Salida integral |
|---|---|---|
| Detección | yolo26n.pt | (N, 300, 6) |
| Segmentación de instancias | yolo26n-seg.pt | (N, 300, 38) + proto (N, 32, 160, 160) |
| Pose | yolo26n-pose.pt | (N, 300, 57) |
| OBB | yolo26n-obb.pt | (N, 300, 7) |