Entendendo a Detecção End-to-End no Ultralytics YOLO26#
Se estás a atualizar para o YOLO26 a partir de um modelo anterior como o YOLOv8 ou o YOLO11, uma das maiores mudanças que vais notar é a remoção da Non-Maximum Suppression (NMS). Os modelos YOLO tradicionais produzem milhares de previsões sobrepostas que necessitam de um passo de pós-processamento NMS separado para filtrar até às deteções finais. Isto adiciona latência, complica os grafos de exportação e pode comportar-se de forma inconsistente em diferentes plataformas de hardware.
O YOLO26 adota uma abordagem diferente. Produz as deteções finais diretamente a partir do modelo — sem ser necessária filtragem externa. Isto é conhecido como detetção de objetos end-to-end, e está ativado por predefinição em todos os modelos YOLO26. O resultado é um pipeline de implementaçã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 uma análise mais profunda da motivação por trás desta mudança arquitetónica, consulta a publicação no blog da Ultralytics sobre o motivo pelo qual o YOLO26 remove o NMS.
- Estás a usar a API ou a CLI da Ultralytics? Não são necessárias alterações — basta mudares o nome do teu modelo para
yolo26n.pt. - Estás a usar código de inferência personalizado (ONNX Runtime, TensorRT, etc.)? Atualiza o teu pós-processamento — a saída de deteção é agora
(N, 300, 6)no formatoxyxy, sem necessidade de NMS. Outras tarefas acrescentam dados extra (coeficientes de máscara, pontos-chave ou ângulo). - A exportar? A maioria dos formatos suporta a saída end-to-end de forma nativa. No entanto, alguns formatos (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU e QNN) recorrem automaticamente à saída tradicional devido a restrições de operadores não suportados (por exemplo,
torch.topk). Os workflows do Hailo HEF são compilados a partir de ONNX com scripts específicos do Hailo, por isso verifica a cabeça de deteção e a configuração de NMS para o teu modelo.
Como a Detecção End-to-End Funciona#
O YOLO26 utiliza uma arquitetura de cabeça dupla durante o treino. Ambas as cabeças partilham a mesma espinha dorsal e o mesmo pescoço, mas produzem saídas de formas 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 deteção. Outras tarefas estendem a saída de um para um com dados adicionais por deteção:
| Tarefa | Saída End-to-End | Dados Extras |
|---|---|---|
| Detecção | (N, 300, 6) | — |
| Segmentação de Instância | (N, 300, 6 + nm) + proto (N, nm, H, W) | coeficientes de máscara nm (predefinição 32) |
| Pose | (N, 300, 57) | 17 keypoints × 3 (x, y, visibilidade) |
| OBB | (N, 300, 7) | Ângulo de rotação |
Durante o treino, ambas as cabeças funcionam em simultâneo — a cabeça de um para muitos fornece um sinal de aprendizagem mais rico, enquanto a cabeça de um para um aprende a produzir previsões limpas e sem sobreposições. Durante a inferência e a exportação, apenas a cabeça de um para um está ativa por predefinição, produzindo até 300 deteções por imagem no formato [x1, y1, x2, y2, confidence, class_id].
Quando chamas model.fuse(), este agrupa as camadas Conv + BatchNorm para uma inferência mais rápida e, nos modelos end-to-end, também remove a cabeça de um para muitos — reduzindo o tamanho do modelo e os FLOPs. Para mais detalhes sobre a arquitetura de cabeça dupla, consulta a página do modelo YOLO26.
Preciso Alterar Meu Código?#
Usando a API Python ou CLI da Ultralytics#
Não são necessárias alterações. Se utilizas a API Python da Ultralytics ou a CLI padrão, tudo funciona automaticamente — a previsão, a validação e a exportação lidam com modelos end-to-end de raiz.
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 Inferência Personalizado#
Sim, o formato de saída é diferente. Se escreveste lógica de pós-processamento personalizada para o YOLOv8 ou o YOLO11 (por exemplo, ao executar inferência com ONNX Runtime ou TensorRT), precisas de a atualizar 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 (centro x, centro y, largura, altura) | xyxy (canto superior esquerdo x, canto superior esquerdo y, canto inferior direito x, canto inferior direito y) |
| 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 segmentação, pose e OBB, o YOLO26 adiciona dados específicos da tarefa a cada deteção — consulta a tabela de formas de saída.
Onde N é o tamanho do lote e nc é o número de classes (por exemplo, 80 para o COCO).
Com os modelos end-to-end, o pós-processamento torna-se muito mais simples — por exemplo, ao utilizar 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!Mudando para o Cabeçote Um-para-Muitos#
Se precisares do formato de saída YOLO tradicional (por exemplo, para reutilizar código de pós-processamento baseado em NMS existente), podes mudar para a cabeça de um para muitos quando esta estiver disponível, 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)Compatibilidade de Formato de Exportação#
A maioria dos formatos de exportação suporta inferência end-to-end de raiz, incluindo ONNX, TensorRT, CoreML, OpenVINO, LiteRT e MNN.
Os seguintes formatos não suportam end-to-end e recorrem automaticamente à cabeça de um para muitos: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU e Qualcomm QNN.
Para o Hailo HEF, o passo de compilação ocorre fora de model.export(format=...) após uma exportação ONNX. Utiliza os registos DFC do Hailo, o script de modelo .alls e o JSON de NMS correspondentes ao teu modelo de deteção exato; se um grafo YOLO26 end-to-end não for suportado pela tua cadeia de ferramentas Hailo, exporta o modelo ONNX com end2end=False e compila a cabeça de deteção tradicional.
O TensorRT suporta end-to-end, mas é desativado automaticamente ao exportar com quantize=8 no TensorRT 10.3.0 no JetPack 6.
Compensações de Precisão e Velocidade#
A deteção end-to-end oferece vantagens significativas de implementação com um impacto mínimo na precisão:
| 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 é negligenciável, especialmente quando se consideram os ganhos de velocidade e simplicidade. Se a precisão máxima for a tua principal prioridade, podes sempre recorrer à cabeça de um para muitos utilizando end2end=False.
Consulta as métricas de desempenho do YOLO26 para benchmarks detalhados em todos os tamanhos de modelo (n, s, m, l, x).
Migrando 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:
- Utilizadores da API / CLI da Ultralytics: Não são necessárias alterações — basta atualizar o nome do modelo para
yolo26n.pt(ouyolo26n-seg.pt,yolo26n-pose.pt,yolo26n-obb.pt) - Código de pós-processamento personalizado: Atualiza para lidar com as novas formas de saída —
(N, 300, 6)para deteção, além de dados específicos da tarefa para segmentação, pose e OBB. Tem também em atenção a alteração do formato da caixa dexywhparaxyxy - Pipelines de exportação: Verifica a secção de compatibilidade de formatos para o teu formato de destino
- TensorRT + INT8: No JetPack 6, o TensorRT 10.3.0 desativa automaticamente o end-to-end com
quantize=8— utiliza uma versão diferente do TensorRT para manter o end-to-end - Exportações FP16: Se precisares de todas as saídas em FP16, exporta com
end2end=False— consulta por que razão o output0 permanece em FP32 - iOS / CoreML: O end-to-end é totalmente suportado. Se precisares de suporte para a Pré-visualização do Xcode, utiliza
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
Conclusão#
A deteção end-to-end é a predefinição no YOLO26 e não requer alterações de código se utilizares a API Python da Ultralytics ou a CLI. Apenas os pipelines de pós-processamento personalizados precisam de ser atualizados para ler a nova saída (N, 300, 6) e remover o passo NMS — exceto para os formatos de exportação que recorrem à saída de um para muitos (como NCNN e RKNN), que ainda requerem NMS no dispositivo. Para benchmarks detalhados de velocidade e precisão em todos os tamanhos de modelo, consulta a página do modelo YOLO26 e, para o conjunto completo de opções e formatos de exportação, consulta a documentação do modo Export.
FAQ#
Não. Estas opções são mutuamente exclusivas. Se definires
nms=Truenum modelo end-to-end durante a exportação, esta será forçada automaticamente paranms=Falsecom um aviso. A cabeça end-to-end já lida internamente com a filtragem de duplicados, pelo que o NMS externo é desnecessário.No entanto,
end2end=Falsecombinado comnms=Trueé uma configuração válida — incorpora o NMS tradicional no grafo de exportação. Isto pode ser útil para exportações CoreML porque te permite utilizar a função de Pré-visualização no Xcode diretamente com o modelo de deteção.O parâmetro
max_det(predefinição: 300) define o número máximo de deteções devolvidas por imagem. Podes ajustá-lo no momento da inferência ou da exportação:model.predict("image.jpg", max_det=100) # fewer detections model.export(format="onnx", max_det=500) # more detections for dense scenesTem em atenção que os pontos de controlo YOLO26 predefinidos foram treinados com
max_det=300. Embora possas aumentar este valor, a cabeça de um para um foi otimizada durante o treino para produzir até 300 deteções limpas, pelo que deteções além desse limite podem ser de menor qualidade. Se precisares de mais de 300 deteções por imagem, considera retreinar com um valor demax_detmais elevado.Sim, esse é o formato de saída end-to-end esperado para deteção: tamanho do lote de 1, até 300 deteções, cada uma com 6 valores
[x1, y1, x2, y2, confidence, class_id]. Basta filtrar pelo limiar de confiança e está feito — sem necessidade de 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 Você pode verificar usando a API Python da Ultralytics ou inspecionando diretamente os metadados do modelo ONNX exportado:
Verifique se um modelo é end-to-endfrom 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 enabledEm alternativa, verifica a forma da saída — os modelos de deteção end-to-end produzem
(1, 300, 6), enquanto os modelos tradicionais produzem(1, nc + 4, 8400). Para outras formas de tarefas, consulta as FAQ sobre formas de saída.Sim. As variantes de tarefas do tipo deteção do YOLO26 — deteção, segmentação de instâncias, estimativa de pose e detetção de objetos orientados (OBB) — suportam inferência end-to-end por predefinição. O recurso de recuperação
end2end=Falsetambém está disponível nestas 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)