YOLO Vision 2026:

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.

Resumo Rápido
  • 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 formato xyxy, 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çoteObjetivoSaída de DetecçãoPós-processamento
Um-para-Um (padrão)Inferência end-to-end(N, 300, 6)Apenas limiar de confiança
Um-para-MuitosSaí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:

TarefaSaída End-to-EndDados 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.

Nenhuma alteração de código necessária com a API 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")

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 / YOLO11YOLO26 (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)
LayoutCoordenadas da caixa + pontuações de classe por âncora[x1, y1, x2, y2, conf, class_id]
NMS necessáriaSimNão
Pós-processamentoNMS + filtro de confiançaApenas 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:

Usando o cabeçote um-para-muitos para saída tradicional baseada em 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)

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.

O que acontece quando o end-to-end não é suportado

Quando exportas para um destes formatos, a Ultralytics muda automaticamente para a cabeça de um para muitos e regista um aviso — sem necessidade de intervenção manual. Isto significa que vais precisar de NMS no teu pipeline de inferência para estes formatos, tal como com o YOLOv8 ou o YOLO11.

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.

TensorRT + INT8

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étricaEnd-to-End (padrão)Um para Muitos + NMS (end2end=False)
Velocidade de Inferência em CPUAté 43% mais rápidoBase
Impacto no mAP~0.5 mAP menorIguala ou supera o YOLO11
Pós-processamentoApenas filtro de confiançaPipeline NMS completo
Complexidade de ImplantaçãoMínimaRequer 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 (ou yolo26n-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 de xywh para xyxy
  • 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=False com nms=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=True num modelo end-to-end durante a exportação, esta será forçada automaticamente para nms=False com 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=False combinado com nms=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 scenes

    Tem 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 de max_det mais 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:

    TarefaForma da SaídaDescriçã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-end
    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

    Em 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=False também está disponível nestas tarefas.

    Cada tarefa estende a saída de detecção base com dados específicos da tarefa:

    TarefaModeloSaída End-to-End
    Deteçãoyolo26n.pt(N, 300, 6)
    Segmentação de Instânciayolo26n-seg.pt(N, 300, 38) + proto (N, 32, 160, 160)
    Poseyolo26n-pose.pt(N, 300, 57)
    OBByolo26n-obb.pt(N, 300, 7)

Comentários