Meet YOLO26: next-gen vision AI.

Link to this sectionПонимание сквозного обнаружения в Ultralytics YOLO26#

Link to this sectionВведение#

Если ты переходишь на YOLO26 с более ранней модели, такой как YOLOv8 или YOLO11, одно из самых больших изменений, которое ты заметишь, — это удаление Non-Maximum Suppression (NMS). Традиционные модели YOLO создают тысячи перекрывающихся предсказаний, для фильтрации которых до финальных результатов обнаружения требуется отдельный этап постобработки NMS. Это увеличивает задержку, усложняет графы экспорта и может приводить к несогласованному поведению на различных аппаратных платформах.

YOLO26 использует другой подход. Она выдает финальные результаты обнаружения напрямую из модели — внешняя фильтрация не требуется. Это называется сквозным object detection, и данная функция включена по умолчанию во всех моделях YOLO26. В результате конвейер развертывания становится проще, задержка ниже, а скорость вывода на CPU выше до 43%.

Это руководство поможет тебе понять, что изменилось, нужно ли обновлять твой код, какие форматы экспорта поддерживают сквозной вывод и как плавно перейти с более старых моделей YOLO.

Для более глубокого понимания мотивации этого архитектурного сдвига ознакомься с блоге Ultralytics о том, почему YOLO26 удаляет NMS.

Краткая сводка
  • Используешь Ultralytics API или CLI? Изменения не требуются — просто замени имя модели на yolo26n.pt.
  • Используешь собственный код для вывода (ONNX Runtime, TensorRT и т.д.)? Обнови свою постобработку — выходной результат обнаружения теперь имеет формат (N, 300, 6) в представлении xyxy, NMS не требуется. Другие задачи добавляют дополнительные данные (коэффициенты масок, ключевые точки или углы).
  • Экспорт? Большинство форматов поддерживают сквозной вывод нативно. Однако некоторые форматы (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU и QNN) автоматически возвращаются к традиционному выводу из-за ограничений неподдерживаемых операторов (например, torch.topk). Рабочие процессы Hailo HEF компилируются из ONNX с помощью скриптов, специфичных для Hailo, поэтому проверь настройки головы обнаружения и NMS для своей модели.

Link to this sectionКак работает сквозное обнаружение#

YOLO26 использует двухголовую архитектуру во время обучения. Обе головы используют общие backbone и neck, но выдают результаты разными способами:

ГоловаНазначениеВыход обнаруженияПостобработка
Один-к-одному (по умолчанию)Сквозной вывод(N, 300, 6)Только порог уверенности
Один-ко-многимТрадиционный выход YOLO(N, nc + 4, 8400)Требует NMS

Указанные выше размерности относятся к обнаружению. Другие задачи расширяют выход один-к-одному дополнительными данными для каждого обнаруженного объекта:

ЗадачаСквозной выходДополнительные данные
Обнаружение(N, 300, 6)
Сегментация экземпляров(N, 300, 6 + nm) + proto (N, nm, H, W)Коэффициенты маски nm (по умолчанию 32)
Позы(N, 300, 57)17 ключевых точек × 3 (x, y, видимость)
OBB(N, 300, 7)Угол поворота

Во время обучения обе головы работают одновременно — голова один-ко-многим предоставляет более богатый сигнал обучения, в то время как голова один-к-одному учится создавать чистые, неперекрывающиеся предсказания. Во время вывода и экспорта активна только голова один-к-одному по умолчанию, выдавая до 300 обнаружений на изображение в формате [x1, y1, x2, y2, confidence, class_id].

Когда ты вызываешь model.fuse(), это объединяет слои Conv + BatchNorm для более быстрого вывода, а в моделях со сквозным обнаружением также удаляет голову один-ко-многим, сокращая размер модели и количество FLOPs. Более подробную информацию о двухголовой архитектуре смотри на странице модели YOLO26.

Link to this sectionНужно ли мне менять свой код?#

Link to this sectionИспользование Python API или CLI от Ultralytics#

Изменения не требуются. Если ты используешь стандартный Python API Ultralytics или CLI, все работает автоматически — предсказание, валидация и экспорт поддерживают сквозные модели «из коробки».

С Ultralytics API изменения кода не требуются
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 sectionИспользование собственного кода для вывода#

Да, формат вывода другой. Если ты написал собственную логику постобработки для YOLOv8 или YOLO11 (например, при выполнении вывода с помощью ONNX Runtime или TensorRT), тебе нужно будет обновить её для обработки новой формы выходных данных:

YOLOv8 / YOLO11YOLO26 (сквозное)
Выход обнаружения(N, nc + 4, 8400)(N, 300, 6)
Формат bboxxywh (центр x, центр y, ширина, высота)xyxy (верхний левый x, верхний левый y, нижний правый x, нижний правый y)
РасположениеКоординаты bbox + оценки классов для каждого якоря[x1, y1, x2, y2, conf, class_id]
Требуется NMSДаНет
ПостобработкаNMS + фильтр уверенностиТолько фильтр уверенности

Для задач сегментации, поз и OBB YOLO26 добавляет специфические для задачи данные к каждому обнаружению — см. таблицу выходных форм выше.

Где N — это размер пакета, а nc — количество классов (например, 80 для COCO).

Со сквозными моделями постобработка становится гораздо проще — например, при использовании 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 sectionПереключение на голову один-ко-многим#

Если тебе нужен традиционный формат вывода YOLO (например, для повторного использования существующего кода постобработки на основе NMS), ты можешь в любой момент переключиться на голову один-ко-многим, установив end2end=False:

Использование головы один-ко-многим для традиционного вывода на основе 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)

Link to this sectionСовместимость форматов экспорта#

Большинство форматов экспорта поддерживают сквозной вывод «из коробки», включая ONNX, TensorRT, CoreML, OpenVINO, TFLite, TF.js и MNN.

Следующие форматы не поддерживают сквозное обнаружение и автоматически возвращаются к голове один-ко-многим: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU и Qualcomm QNN.

Что происходит, когда сквозное обнаружение не поддерживается

При экспорте в один из этих форматов Ultralytics автоматически переключается на голову один-ко-многим и записывает предупреждение — ручное вмешательство не требуется. Это означает, что тебе потребуется NMS в твоем конвейере вывода для этих форматов, так же, как в YOLOv8 или YOLO11.

Для Hailo HEF этап компиляции происходит вне model.export(format=...) после экспорта в ONNX. Используй логи Hailo DFC, скрипт модели .alls и JSON с NMS, которые соответствуют твоей конкретной модели обнаружения; если сквозной граф YOLO26 не поддерживается твоим инструментарием Hailo, экспортируй модель ONNX с параметром end2end=False и скомпилируй традиционную голову обнаружения.

TensorRT + INT8

TensorRT поддерживает сквозное обнаружение, но оно автоматически отключается при экспорте с int8=True в версиях TensorRT ≤10.3.0.

Link to this sectionКомпромиссы между точностью и скоростью#

Сквозное обнаружение обеспечивает значительные преимущества при развертывании с минимальным влиянием на точность:

ПоказательСквозное (по умолчанию)Один-ко-многим + NMS (end2end=False)
Скорость вывода на CPUДо 43% быстрееБазовый уровень
Влияние на mAP~0.5 mAP нижеСоответствует или превышает YOLO11
ПостобработкаТолько фильтр уверенностиПолный конвейер NMS
Сложность развертыванияМинимальнаяТребует реализации NMS

Для большинства реальных приложений разница в ~0.5 mAP пренебрежимо мала, особенно если учесть выигрыш в скорости и простоте. Если максимальная точность — твой главный приоритет, ты всегда можешь вернуться к голове один-ко-многим, используя end2end=False.

Смотри показатели производительности YOLO26 для детальных бенчмарков по всем размерам моделей (n, s, m, l, x).

Link to this sectionПереход с YOLOv8 или YOLO11#

Если ты обновляешь существующий проект до YOLO26, вот краткий список для обеспечения плавного перехода:

  • Пользователи Ultralytics API / CLI: Изменения не нужны — просто обнови имя модели на yolo26n.pt (или yolo26n-seg.pt, yolo26n-pose.pt, yolo26n-obb.pt)
  • Собственный код постобработки: Обнови его для обработки новых выходных форм — (N, 300, 6) для обнаружения плюс специфические для задач данные для сегментации, поз и OBB. Также обрати внимание на изменение формата bbox с xywh на xyxy
  • Конвейеры экспорта: Проверь раздел совместимости форматов выше для твоего целевого формата
  • TensorRT + INT8: Убедись, что твоя версия TensorRT выше 10.3.0 для поддержки end-to-end.
  • Экспорт в FP16: Если тебе нужны все выходные данные в FP16, используй экспорт с end2end=False — см. почему output0 остается в FP32.
  • iOS / CoreML: End-to-end поддерживается полностью. Если тебе нужна поддержка Xcode Preview, используй end2end=False вместе с nms=True.
  • Периферийные устройства (NCNN, RKNN): Эти форматы автоматически переключаются на режим one-to-many, поэтому включай NMS в свой конвейер на устройстве.

Link to this sectionFAQ#

Link to this sectionМожно ли использовать end2end=True и nms=True одновременно?#

Нет. Эти опции взаимоисключающие. Если ты установишь nms=True для end-to-end модели во время экспорта, значение будет автоматически изменено на nms=False с предупреждением. Внутренний механизм end-to-end уже выполняет фильтрацию дубликатов, поэтому внешняя NMS не нужна.

Тем не менее, комбинация end2end=False и nms=True является допустимой конфигурацией — она встраивает традиционную NMS в граф экспорта. Это может быть полезно для экспорта в CoreML, так как позволяет использовать функцию Preview в Xcode напрямую с моделью детектирования.

Link to this sectionЗа что отвечает параметр max_det в end-to-end моделях?#

Параметр max_det (по умолчанию: 300) задает максимальное количество детектирований, которое «голова» модели one-to-one может выдать для одного изображения. Ты можешь настроить его во время инференса или экспорта:

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

Обрати внимание, что стандартные чекпоинты YOLO26 были обучены с параметром max_det=300. Хотя ты можешь увеличить это значение, «голова» one-to-one была оптимизирована в процессе обучения на выдачу до 300 качественных детектирований, поэтому результаты сверх этого лимита могут быть менее точными. Если тебе нужно более 300 детектирований на изображение, рассмотри возможность переобучения с более высоким значением max_det.

Link to this sectionМоя экспортированная ONNX модель выдает (1, 300, 6) — это правильно?#

Да, это ожидаемый формат вывода end-to-end для детектирования: размер батча равен 1, до 300 детектирований, каждое из которых содержит 6 значений [x1, y1, x2, y2, confidence, class_id]. Просто отфильтруй результаты по порогу достоверности, и все готово — NMS не требуется.

Для других задач форма вывода отличается:

ЗадачаФорма выводаОписание
Детектирование(1, 300, 6)[x1, y1, x2, y2, conf, class_id]
Сегментация(1, 300, 38) + (1, 32, 160, 160)6 значений рамки + 32 коэффициента маски, плюс тензор прототипа маски
Поза(1, 300, 57)6 значений рамки + 17 ключевых точек × 3 (x, y, видимость)
OBB(1, 300, 7)6 значений рамки + 1 угол поворота

Link to this sectionКак проверить, является ли моя экспортированная модель end-to-end?#

Ты можешь проверить это с помощью Python API Ultralytics или просмотрев метаданные экспортированной ONNX модели напрямую:

Проверка, является ли модель 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

Альтернативно, проверь форму выходных данных — end-to-end модели детектирования выводят (1, 300, 6), в то время как традиционные модели выдают (1, nc + 4, 8400). Для форм других задач см. FAQ по формам вывода.

Link to this sectionПоддерживается ли end-to-end для задач сегментации экземпляров, оценки позы и OBB?#

Да. Варианты задач в стиле YOLO26 — детектирование, сегментация экземпляров, оценка позы и ориентированное детектирование объектов (OBB) — поддерживают end-to-end инференс по умолчанию. Возможность отката через end2end=False также доступна для всех этих задач.

Каждая задача расширяет базовый вывод детектирования данными, специфичными для задачи:

ЗадачаМодельСквозной выход
Детектированиеyolo26n.pt(N, 300, 6)
Сегментация экземпляровyolo26n-seg.pt(N, 300, 38) + proto (N, 32, 160, 160)
Позаyolo26n-pose.pt(N, 300, 57)
OBByolo26n-obb.pt(N, 300, 7)

Комментарии