Link to this sectionEntendendo a Detecção End-to-End no Ultralytics YOLO26#
Link to this sectionIntrodução#
Se você está atualizando para o YOLO26 a partir de um modelo anterior como o YOLOv8 ou o YOLO11, uma das maiores mudanças que você notará é a remoção da Non-Maximum Suppression (NMS). Os modelos YOLO tradicionais produzem milhares de previsões sobrepostas que precisam de uma etapa separada de pós-processamento de NMS para filtrar até as detecções finais. Isso adiciona latência, complica os grafos de exportação e pode se comportar de forma inconsistente em diferentes plataformas de hardware.
O YOLO26 adota uma abordagem diferente. Ele gera as detecções finais diretamente do modelo — sem necessidade de filtragem externa. Isso é conhecido como detecção de object detection end-to-end, e está habilitado por padrão em todos os modelos YOLO26. O resultado é um pipeline de implantação mais simples, menor latência e inferência até 43% mais rápida em CPUs.
Este guia te orienta sobre o que mudou, se você precisa atualizar seu código, quais formatos de exportação suportam inferência end-to-end e como migrar suavemente de modelos YOLO antigos.
Para um olhar mais profundo sobre a motivação por trás desta mudança arquitetônica, veja o post no blog da Ultralytics sobre por que o YOLO26 remove a NMS.
- Usando a API ou CLI da Ultralytics? Nenhuma alteração necessária — apenas troque o nome do seu modelo para
yolo26n.pt. - Usando código de inferência personalizado (ONNX Runtime, TensorRT, etc.)? Atualize seu pós-processamento — a saída de detecção agora é
(N, 300, 6)no formatoxyxy, sem necessidade de NMS. Outras tarefas anexam dados extras (coeficientes de máscara, keypoints ou ângulo). - Exportando? A maioria dos formatos suporta a saída end-to-end nativamente. No entanto, alguns formatos (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU e QNN) retornam automaticamente para a saída tradicional devido a restrições de operadores não suportados (ex:
torch.topk). Workflows de Hailo HEF compilam a partir do ONNX com scripts específicos do Hailo, então verifique o cabeçote de detecção e a configuração de NMS para o seu modelo.
Link to this sectionComo a Detecção End-to-End Funciona#
O YOLO26 usa uma arquitetura de cabeçote duplo durante o training. Ambos os cabeçotes compartilham o mesmo backbone e pescoço (neck), mas produzem saídas de maneiras diferentes:
| Cabeçote | Objetivo | Saída de Detecção | Pós-processamento |
|---|---|---|---|
| Um-para-Um (padrão) | Inferência end-to-end | (N, 300, 6) | Apenas limiar de confiança |
| Um-para-Muitos | Saída YOLO tradicional | (N, nc + 4, 8400) | Requer NMS |
As formas acima são para detection. Outras tarefas estendem a saída um-para-um com dados adicionais por detecção:
| Tarefa | Saída End-to-End | Dados Extras |
|---|---|---|
| Detecção | (N, 300, 6) | — |
| Segmentação de instâncias | (N, 300, 6 + nm) + proto (N, nm, H, W) | nm coeficientes de máscara (padrão 32) |
| Pose | (N, 300, 57) | 17 keypoints × 3 (x, y, visibilidade) |
| OBB | (N, 300, 7) | Ângulo de rotação |
During training, both heads run simultaneously — the one-to-many head provides a richer learning signal, while the one-to-one head learns to produce clean, non-overlapping predictions. During inference and export, only the one-to-one head is active by default, producing up to 300 detections per image in the format [x1, y1, x2, y2, confidence, class_id].
Quando você chama model.fuse(), ele dobra as camadas Conv + BatchNorm para uma inferência mais rápida e, em modelos end-to-end, também remove o cabeçote um-para-muitos — reduzindo o tamanho do modelo e FLOPs. Para mais detalhes sobre a arquitetura de cabeçote duplo, veja a página do modelo YOLO26.
Link to this sectionPreciso Alterar Meu Código?#
Link to this sectionUsando a API Python ou CLI da Ultralytics#
Nenhuma alteração necessária. Se você usa a Ultralytics Python API ou a CLI padrão, tudo funciona automaticamente — prediction, validation e export lidam com modelos end-to-end nativamente.
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 Inferência Personalizado#
Sim, o formato de saída é diferente. Se você escreveu lógica de pós-processamento personalizada para o YOLOv8 ou YOLO11 (por exemplo, ao executar inferência com ONNX Runtime ou TensorRT), você precisará atualizá-la para lidar com a nova forma de saída:
| YOLOv8 / YOLO11 | YOLO26 (end-to-end) | |
|---|---|---|
| Saída de detecção | (N, nc + 4, 8400) | (N, 300, 6) |
| Formato da caixa (bbox) | xywh (x do centro, y do centro, largura, altura) | xyxy (x superior esquerdo, y superior esquerdo, x inferior direito, y inferior direito) |
| Layout | Coordenadas da caixa + pontuações de classe por âncora | [x1, y1, x2, y2, conf, class_id] |
| NMS necessária | Sim | Não |
| Pós-processamento | NMS + filtro de confiança | Apenas filtro de confiança |
Para tarefas de segmentation, pose e OBB, o YOLO26 anexa dados específicos da tarefa a cada detecção — veja a tabela de formas de saída acima.
Onde N é o batch size e nc é o número de classes (ex: 80 para COCO).
Com modelos end-to-end, o pós-processamento torna-se muito mais simples — por exemplo, ao usar o 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 sectionMudando para o Cabeçote Um-para-Muitos#
Se você precisar do formato de saída YOLO tradicional (por exemplo, para reutilizar código de pós-processamento baseado em NMS existente), você pode mudar para o cabeçote um-para-muitos a qualquer momento definindo 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 sectionCompatibilidade de Formato de Exportação#
A maioria dos export formats suporta inferência end-to-end nativamente, incluindo ONNX, TensorRT, CoreML, OpenVINO, TFLite, TF.js e MNN.
Os seguintes formatos não suportam end-to-end e retornam automaticamente para o cabeçote um-para-muitos: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU e Qualcomm QNN.
Quando você exporta para um desses formatos, a Ultralytics muda automaticamente para o cabeçote um-para-muitos e registra um aviso — nenhuma intervenção manual necessária. Isso significa que você precisará de NMS em seu pipeline de inferência para esses formatos, exatamente como no YOLOv8 ou YOLO11.
Para Hailo HEF, a etapa de compilação acontece fora de model.export(format=...) após uma exportação ONNX. Use os logs DFC do Hailo, o script de modelo .alls e o JSON de NMS que correspondem exatamente ao seu modelo de detecção; se um grafo YOLO26 end-to-end não for suportado pela sua toolchain Hailo, exporte o modelo ONNX com end2end=False e compile o cabeçote de detecção tradicional.
O TensorRT suporta end-to-end, mas ele é desabilitado automaticamente ao exportar com int8=True no TensorRT 10.3.0 no JetPack 6.
Link to this sectionCompensações de Precisão e Velocidade#
A detecção end-to-end oferece benefícios significativos de implantação com impacto mínimo na accuracy:
| Métrica | End-to-End (padrão) | Um-para-Muitos + NMS (end2end=False) |
|---|---|---|
| Velocidade de Inferência em CPU | Até 43% mais rápido | Base |
| Impacto no mAP | ~0.5 mAP menor | Iguala ou supera o YOLO11 |
| Pós-processamento | Apenas filtro de confiança | Pipeline NMS completo |
| Complexidade de Implantação | Mínima | Requer implementação de NMS |
Para a maioria das aplicações do mundo real, a diferença de ~0.5 mAP é insignificante, especialmente ao considerar os ganhos de velocidade e simplicidade. Se a precisão máxima for sua prioridade principal, você sempre pode retornar ao cabeçote um-para-muitos usando end2end=False.
Veja as métricas de desempenho do YOLO26 para benchmarks detalhados em todos os tamanhos de modelo (n, s, m, l, x).
Link to this sectionMigrando do YOLOv8 ou YOLO11#
Se você está atualizando um projeto existente para o YOLO26, aqui está uma lista de verificação rápida para garantir uma transição suave:
- Usuários da API / CLI Ultralytics: Nenhuma alteração necessária — apenas atualize o nome do modelo para
yolo26n.pt(ouyolo26n-seg.pt,yolo26n-pose.pt,yolo26n-obb.pt) - Código de pós-processamento personalizado: Atualize para lidar com as novas formas de saída —
(N, 300, 6)para detecção, mais dados específicos da tarefa para segmentation, pose e OBB. Observe também a alteração do formato da caixa dexywhparaxyxy - Pipelines de exportação: Verifique a seção compatibilidade de formato acima para seu formato de destino
- TensorRT + INT8: No JetPack 6, o TensorRT 10.3.0 desabilita automaticamente o end-to-end com
int8=True— use uma versão diferente do TensorRT para manter o end-to-end - Exportações FP16: Se você precisar de todas as saídas em FP16, exporte com
end2end=False— veja por que output0 permanece FP32 - iOS / CoreML: O end-to-end é totalmente suportado. Se precisar de suporte ao Xcode Preview, use
end2end=Falsecomnms=True - Dispositivos de borda (NCNN, RKNN): Esses formatos retornam automaticamente para um-para-muitos, então inclua NMS em seu pipeline no dispositivo
Link to this sectionFAQ#
Link to this sectionPosso usar end2end=True e nms=True juntos?#
Não. Essas opções são mutuamente exclusivas. Se você definir nms=True em um modelo end-to-end durante a export, ele será forçado automaticamente para nms=False com um aviso. O cabeçote end-to-end já lida internamente com a filtragem de duplicatas, portanto, uma NMS externa é desnecessária.
No entanto, end2end=False combinado com nms=True é uma configuração válida — ele integra a NMS tradicional no grafo de exportação. Isso pode ser útil para exportações CoreML porque permite que você use a função Preview no Xcode diretamente com o modelo de detecção.
Link to this sectionO que o parâmetro max_det controla em modelos end-to-end?#
O parâmetro max_det (padrão: 300) define o número máximo de detecções que a one-to-one head pode produzir por imagem. Você pode ajustá-lo no momento da inferência ou da exportação:
model.predict("image.jpg", max_det=100) # fewer detections, slightly faster
model.export(format="onnx", max_det=500) # more detections for dense scenesObserve que os checkpoints padrão do YOLO26 foram treinados com max_det=300. Embora você possa aumentar esse valor, a one-to-one head foi otimizada durante o treinamento para produzir até 300 detecções limpas, portanto, detecções além desse limite podem ter qualidade inferior. Se precisar de mais de 300 detecções por imagem, considere treinar novamente com um valor de max_det mais alto.
Link to this sectionMeu modelo ONNX exportado produz (1, 300, 6) — isso está correto?#
Sim, esse é o formato de saída end-to-end esperado para detecção: batch size de 1, até 300 detecções, cada uma com 6 valores [x1, y1, x2, y2, confidence, class_id]. Basta filtrar pelo limiar de confiança e pronto — não é necessário NMS.
Para outras tarefas, a forma da saída é diferente:
| Tarefa | Forma da Saída | Descrição |
|---|---|---|
| Deteção | (1, 300, 6) | [x1, y1, x2, y2, conf, class_id] |
| Segmentação | (1, 300, 38) + (1, 32, 160, 160) | 6 valores de caixa + 32 coeficientes de máscara, além de um tensor de máscara protótipo |
| Pose | (1, 300, 57) | 6 valores de caixa + 17 keypoints × 3 (x, y, visibilidade) |
| OBB | (1, 300, 7) | 6 valores de caixa + 1 ângulo de rotação |
Link to this sectionComo verifico se meu modelo exportado é end-to-end?#
Você pode verificar usando a API Python da Ultralytics ou inspecionando diretamente os metadados do 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, verifique a forma da saída — modelos de detecção end-to-end produzem (1, 300, 6), enquanto modelos tradicionais produzem (1, nc + 4, 8400). Para formas de outras tarefas, consulte o FAQ de formas de saída.
Link to this sectionO end-to-end é suportado para tarefas de segmentação de instância, pose e OBB?#
Sim. As variantes de tarefa estilo detecção do YOLO26 — detecção, segmentação de instância, estimativa de pose e detecção de objetos orientados (OBB) — suportam inferência end-to-end por padrão. O fallback end2end=False também está disponível nessas tarefas.
Cada tarefa estende a saída de detecção base com dados específicos da tarefa:
| Tarefa | Modelo | Saída End-to-End |
|---|---|---|
| Deteção | yolo26n.pt | (N, 300, 6) |
| Segmentação de Instância | 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) |