Посмотреть как Markdown

Обновление до 1.7.0

Версия 1.7.0 по-прежнему загружает старые чекпойнты YOLO9 с теми же вещественными рамками. Она меняет обучение семейства YOLO9, имена, которые код видит внутри сети, и несколько контрактов валидации и предсказания.

С 1.6.0 на 1.7.0

  • Чекпойнты YOLO9, YOLO9-E2E и YOLO9-P2, сохранённые в 1.7.0, используют новые имена тензоров и не загружаются в 1.6.x: 1.6.x загружает чекпойнты YOLO9 и YOLO9-P2 с предупреждением об отсутствующих ключах и не предсказывает ни одной рамки, а для чекпойнтов YOLO9-E2E вызывает ошибку несовпадения model_family. Обновите все окружения, которые их читают. Чекпойнты с плавающей точкой, квантизованные и обучающие, записанные прежними релизами, загружаются в 1.7.0, а экспорты ONNX не затронуты.

  • Код, который обращается к model.model модели семейства YOLO9, видит имена модулей MultimediaTechLab/YOLO, без алиасов. DDetect теперь YOLO9Head (anchor_convs / class_convs), RepConvN — RepConv, RepNBottleneck — Bottleneck, DFL — Anchor2Vec (anchor2vec), nc — num_classes, а подслои блоков — conv1/conv2/bottleneck. В YOLO9-E2E YOLO9E2EDetect теперь YOLO9E2EHead, а one2one_cv2 / one2one_cv3 — one_to_one_anchor_convs / one_to_one_class_convs. LibreYOLO9Model.fuse(), RepConvN.fuse_convs(), Conv.forward_without_bn(), Concat и yolo9.utils.decode_boxes удалены. Все переименования перечислены в журнале изменений.

  • Имена узлов ONNX следуют новым именам модулей в голове, бэкбоне и neck, например /head/anchor_convs.0/.... Обновите инструменты, завязанные на имена узлов, такие как конфигурации end-узлов Hailo. Входы, выходы и имена выходов модели не изменились.

  • Дообучение YOLO9 с весов без тензоров PGI, к которым относятся опубликованные LibreYOLO9{t,s,m,c}.pt, обучает только основную голову, как в 1.5.0; в 1.6.0 подключалась случайно инициализированная ветвь PGI с aux_weight=0.25. Веса с тензорами PGI и запуски с нуля по-прежнему обучаются с PGI. Передайте aux_weight=0.25, чтобы всё равно подключить новую ветвь, или aux_weight=0, чтобы принудительно её отключить.

  • Когда PGI подключён, YOLO9-m и YOLO9-c строят вспомогательную ветвь MultimediaTechLab: 12.8M (m) и 25.7M (c) параметров, используемых только при обучении, при 80 классах, вместо прежних 7.5M и 10.2M, поэтому обучению этих размеров с PGI нужно больше памяти и времени на шаг. Обучающий чекпойнт m/c из 1.6.0 возобновляется и дообучается с той ветвью, с которой был обучен. Инференс и YOLO9-t/s не изменились.

  • YOLO9, YOLO9-E2E и YOLO9-P2 обрезают L2-норму градиента на 10, а их обучающий assigner оценивает якоря в fp32, поэтому положительные примеры, выбранные при fp16 AMP, могут отличаться. Передайте clip_max_norm=0, чтобы получить обрезку из 1.6.0; запуск, начатый в 1.6.0 и возобновлённый в 1.7.0, тоже обрезает, если это не передать. У назначения в fp32 переключателя нет.

  • Ненулевой perspective искажает по смещению углов во всех семействах, которые используют общее аффинное преобразование (YOLO9 и его варианты E2E и P2, YOLOX, YOLOv7, YOLO-NAS, PP-YOLOE, RTMDet, PicoDet, RT-DETR и RT-DETRv2), включая запуски, возобновлённые с чекпойнта 1.6.0, где он был задан. Значения 0.002 и выше дают одно и то же максимальное искажение, а отрицательные значения вызывают ValueError. Никакая настройка не воспроизводит искажение из 1.6.0; значение по умолчанию perspective=0 не изменилось.

  • Пайплайн mosaic в YOLO9 берёт коэффициент MixUp из Beta(1, 1) вместо Beta(32, 32), без настройки для старого значения. Обучение YOLOv7 по умолчанию меняется, потому что в YOLOv7 MixUp включён по умолчанию. YOLO9, YOLO9-E2E, YOLO9-P2, RT-DETR и RT-DETRv2 меняются, только когда MixUp включён.

  • libreyolo train без name= записывает запуски EC, D-FINE, SegFormer и LingBot-Vision в runs/train/ec_exp, dfine_exp, segformer_exp и lingbotvision_exp вместо runs/train/exp, пробы V-JEPA 2 — в runs/train/train, а запуски YOLO9-P2 — в runs/train/yolo9_exp. Передайте name=exp для прежнего пути или name=yolo9_p2_exp для YOLO9-P2.

  • libreyolo train запускает D-FINE, SegFormer и LingBot-Vision по их собственным рецептам. Для D-FINE это 132 эпохи, lr0=2e-4, weight_decay=1e-4, 2 эпохи прогрева и никаких аугментаций mosaic, MixUp, HSV и аффинных. Чтобы передать значения, которые отправлялись в 1.6.0, укажите epochs=300 optimizer=sgd lr0=0.01 weight_decay=5e-4 warmup_epochs=5 mosaic=1.0 mixup=1.0 hsv_prob=1.0 degrees=10 translate=0.1 shear=2.0.

  • libreyolo.validation.ConfusionMatrix индексируется как matrix[predicted, true] (было [actual, predicted]), считает детекции при conf_thres=0.25 (было 0.15), принимает names= и task= только как именованные аргументы, а его matrix больше нельзя переприсвоить. Транспонируйте код, который индексировал старую матрицу, и передайте conf_thres=0.15 для прежних подсчётов. plots=True записывает счётчики в confusion_matrix.png, а нормализованный график — в confusion_matrix_normalized.png.

  • predict(agnostic_nms=True) подавляет перекрывающиеся рамки между классами вместо предупреждения. Задачи без рамок вызывают ValueError, LibreEnsemble и HRNet вызывают NotImplementedError, а уровень SAM отклоняет этот аргумент с TypeError; уберите аргумент из этих вызовов.

  • Неизвестное значение interpolation классификатора вызывает ValueError, включая режимы torchvision LANCZOS, BOX, HAMMING и NEAREST_EXACT. Используйте bilinear, bicubic, nearest или bilinear_no_antialias.

  • Повторите валидацию, прежде чем сравнивать с числами из 1.6.0, для val(single_cls=True) на модели, обученной на нескольких классах, для датасетов сегментации, где смешаны строки только с рамками и строки с полигонами, и для RTMDet-Ins, который по умолчанию хранит до max_det=300 масок на изображение; передайте max_det=100 для настройки MMDetection.

  • Без libreyolo[rfdetr] вызовы CLI с именем модели RF-DETR или DINOv2 завершаются с кодом ошибки JSON model_load_failed вместо model_not_found, а в сообщении назван pip install libreyolo[rfdetr].

Полный релиз описан в журнале изменений.

С 1.5.0 на 1.6.0

  • Перед установкой extra ONNX обновите окружения с зафиксированным ONNX Runtime ниже 1.18 до onnxruntime>=1.18.0.

  • SAM 3D Body принимает проверенный набор файлов снимка. Установите libreyolo[hf], получите доступ к закрытой модели и используйте автоматическое получение либо укажите неизменённый каталог снимка и зафиксированный файл MHR в доверенной локальной файловой системе.

  • Повторите валидацию после исправлений изменения размера RF-DETR для задач кроме позы и нормализации классификаторов. Перепроверьте развёрнутые пороги уверенности перед сравнением с результатами 1.5.0; флага прежней предобработки нет.

  • D-FINE, DEIM, RT-DETRv4 и детекция YOLO-NAS включают FP16 AMP по умолчанию. Передайте amp=False, чтобы сохранить FP32.

  • Для прежних настроек дообучения YOLO9 задайте aux_weight=0, max_labels=100 и warmup_momentum=0.937. Задайте letterbox_pad="topleft", если новая конверсия с отметкой центрирования должна воспроизвести старую геометрию. Старые чекпойнты с одной головой возобновляют обучение с исходным графом. Новые запуски YOLO9 используют больше памяти GPU, поэтому уменьшите batch, если размер батча из 1.5.0 не помещается в память.

  • RF-DETR и DINOv2 создают каталоги запусков с именем семейства и увеличиваемым номером. Обновите код, использующий пути артефактов, или задайте output_dir="runs/train", exist_ok=True, чтобы сохранить прежнее расположение и повторное использование.

  • Для классификации соблюдайте mixup + cutmix <= 1; некорректные сочетания теперь вызывают ошибку при настройке.

  • QAT отключает EMA, SyncBatchNorm и усреднение чекпойнтов. Используйте чекпойнты QAT best/last, не полагаясь на эти состояния.

  • Собственные загрузчики с хуками изменения датасета должны использовать persistent_workers=False либо пересоздавать рабочие процессы после изменения. Несовместимые постоянные копии в нескольких рабочих процессах теперь вызывают ошибку.

  • NumPy-массивы изображений читаются как BGR, в порядке OpenCV. Передавайте color_format="rgb" там, где передаёте RGB-массив, например np.asarray(pil_image); вывод cv2.imread() и кадры видео менять не нужно.

  • 4D NumPy-массив или тензор считается батчем: predict() возвращает список с одним Results на каждое изображение, а не использует только первое изображение.

  • train(resume=True) и train(resume="path/to/last.pt") восстанавливают сохранённые аргументы обучения запуска и продолжают писать в его каталог запуска; явно переданные аргументы имеют приоритет. Возобновление опубликованных весов или запуска, который уже дошёл до своего epochs, вызывает ValueError.

  • При включённой валидации последняя эпоха всегда проходит валидацию, поэтому запуски короче eval_interval теперь сообщают метрики и записывают best.pt. val=False выключает валидацию, включая последнюю эпоху. Валидация во время обучения пишет в <run>/val, а не в runs/val/.

  • Сбои CLI-команды train сообщают тип ошибки, поэтому ошибки конфигурации завершаются с кодом 2, а не с кодом 1 и io_error.

Полное описание релиза см. в списке изменений, а конверсию чекпойнтов в разделе импорта весов.

С 1.4.0 на 1.5.0

Эта страница — про обновление самого LibreYOLO. Если вы ищете, как загрузить чекпойнт из оригинального проекта, то это импорт существующих весов — другая тема.

Полная запись о релизе — в списке изменений. Ниже — только та часть, которая что-то требует от вас.

Изменения в коде, которые нужно внести

allow_experimental=True больше не существует

Барьер с подтверждением убран вместе с механизмом ddp_aware(experimental_key=...), который стоял за ним. Обучение и экспорт EC, RTMDet, PicoDet и FOMO раньше требовали этого аргумента, поэтому затронут любой скрипт, который обучает одно из этих семейств.

python
# 1.4.0model.train(data="data.yaml", epochs=100, allow_experimental=True) # 1.5.0: удалите аргументmodel.train(data="data.yaml", epochs=100)

Прослойки для обратной совместимости нет. Вызов, который всё ещё его передаёт, получает предупреждение Unknown training config keys (ignored), а сам аргумент ни на что не влияет. Вместе с аргументом удалён BaseModel.EXPERIMENTAL_WEIGHT_FILENAMES. Хук get_download_notice() сохранился, и его по-прежнему переопределяют MiDaS, SegFormer и YOLO9-P2.

Уровни поддержки по-прежнему публикуются, просто это больше не аргумент: см. уровни стабильности.

Уровня экспорта "experimental" больше не существует

python
from libreyolo.export.support import Tier # 1.4.0: Literal["validated", "experimental", "blocked"]# 1.5.0: Literal["validated", "available", "blocked"]

В коде, который ветвится по строке уровня, "experimental" нужно заменить на "available". BaseExporter больше не выдаёт RuntimeWarning для этих форматов. Состояние по каждому формату перечислено в матрице экспорта.

pretrained=False вместе с resume теперь отклоняется

Раньше эта комбинация отрабатывала несогласованно. Теперь она вызывает ошибку:

ValueError: pretrained=False cannot be combined with resume.

Выберите что-то одно. pretrained=False начинает с новой инициализации, задаваемой сидом, — в 1.5.0 это работает для каждого обучаемого семейства, а не для трёх из них, — а resume продолжает прерванный запуск с его чекпойнта. Оба варианта описаны в разделе обучение.

CLI-параметр --imgsz — строка, а не int

Изменение уже, чем кажется. Оба этих случая не затронуты:

bash
libreyolo predict --model yolo9-t --source img.jpg --imgsz 640   # по-прежнему работает
python
model.predict("img.jpg", imgsz=640)   # по-прежнему работает

Менять нужно только тот код, который вызывает функции команд CLI напрямую из Python, потому что в predict, train и val тип --imgsz расширен с int до str, чтобы он принимал прямоугольные размеры:

python
from libreyolo.cli.commands.predict import predict_cmd predict_cmd(..., imgsz=640)      # 1.4.0predict_cmd(..., imgsz="640")    # 1.5.0, и теперь "480x640" тоже работает

Значение по умолчанию у train теперь — строка "640". export --imgsz и раньше принимал строку, а profile не изменился.

Числа, которые меняются

Три изменения сдвигают метрики на настройках по умолчанию. Если вы отслеживаете результаты между версиями, прочитайте их прежде, чем сравнивать запуск на 1.5.0 с запуском на 1.4.0.

faster-coco-eval — бэкенд метрик COCO по умолчанию

val() и валидация по эпохам во время обучения теперь считают метрики COCO на C++-бэкенде faster-coco-eval, а не на pycocotools.

Решение о переключении принято по измеренному совпадению на всех 100 тестовых сплитах RF100-VL: 1381 из 1400 значений метрик побитово идентичны, максимальное отклонение 2.22e-16, отличия в главных метриках ровно 0, при этом в 15.6 раза быстрее в целом и в 56 раз на датасетах с плотной детекцией. Ваши числа сдвигаться не должны. Но получены они всё же другой реализацией — именно поэтому пункт попал в список.

pycocotools остаётся автоматическим запасным вариантом, когда faster-coco-eval не установлен. Чтобы включить его принудительно:

bash
libreyolo val --model yolo9-t --data coco.yaml --no-faster-coco-eval
python
model.val(data="coco.yaml", faster_coco_eval=False)

LIBREYOLO_FASTER_COCO_EVAL=0 делает то же самое глобально. Реально использованный бэкенд пишется в лог на уровне INFO, доступен как model.last_eval_backend после val() и попадает в JSON-вывод CLI под ключом eval_backend. Быстрый путь ставится командой pip install libreyolo[fast-eval].

Чекпойнтам YOLOX, обученным до 1.5.0, нужно переопределение eps

Это ловушка релиза. Прочитайте, если вы дообучали YOLOX.

В YOLOX для BatchNorm заданы eps=1e-3 и momentum=0.03. До 1.5.0 эти значения применялись постфактум, и такая правка не переживала перестройку под число классов, которую train() выполняет, когда nc вашего датасета отличается от nc чекпойнта. Такое дообучение обучалось и считало валидацию во время обучения при значении torch по умолчанию eps=1e-5, а потом перезагружалось для инференса с 1e-3: те же тензоры при другой нормализации.

Размеры с обычными свёртками почти не сдвигаются. Depthwise-размер n сдвигается сильно, потому что его поканальная running_var достаточно мала, чтобы eps начал доминировать. На RF100-VL ball один и тот же чекпойнт nano даёт 0.566 mAP50-95 при оценке с тем eps, с которым он обучался, и 0.151 после обычной перезагрузки.

Чекпойнт, обученный до 1.5.0, несёт семантику eps=1e-5. Чтобы получить для него достоверные числа, либо проводите оценку с BN eps, переопределённым на 1e-5:

python
import torchfrom libreyolo import LibreYOLO model = LibreYOLO("my-yolox-finetune.pt")for module in model.model.modules():    if isinstance(module, torch.nn.BatchNorm2d):        module.eps = 1e-5 model.val(data="data.yaml")

либо один раз вложите sqrt((var + 1e-3) / (var + 1e-5)) в веса BN и сохраните результат. Чекпойнтам, обученным на 1.5.0 и позже, не нужно ни то, ни другое.

Многомасштабное обучение D-FINE использует оригинальный рецепт для каждого размера

base_size_repeat был жёстко зашит в 3 для всех размеров. Теперь он определяется по размеру так, как задано в оригинале: n обучается на фиксированном размере с выключенной многомасштабностью, s — 20, m — 6, l — 4, x — 3. Раньше совпадал только x, поэтому n, s, m и l видят другое распределение масштабов и сходятся к другим метрикам.

Чтобы вернуть прежнее поведение, задайте значение явно:

python
from libreyolo.training.config import DFINEConfig config = DFINEConfig(base_size_repeat=3)

DEIM по-прежнему использует жёстко зашитую 3. Подробности о семействе — на странице D-FINE.

Полезно знать, действий не требуется

  • Результаты при прямоугольном imgsz изменились, потому что раньше были неверными. Координаты рамок, изменение размера масок в RTMDet, масштабирование в YOLO-NAS и масштабирование эталонной разметки (ground truth) в валидаторе теперь используют высоту и ширину по каждой оси, а не один скаляр. При квадратном imgsz результаты побитово те же. Прямоугольный инференс или валидация, запущенные на 1.4.0, масштабировались неверно. YOLO-NAS теперь прямо отклоняет прямоугольный imgsz, а не выдаёт молча неправильный результат.
  • В словарях метрик появились новые ключи. max_det, ar_max_det и AR_max_det из оценщика COCO, а также metrics/loss и metrics/loss/ce из FOMO. Значения при настройках по умолчанию не изменились, но всё, что перебирает ключи метрик, включая пользовательские логгеры и заголовки CSV, увидит новые колонки.
  • Запуски YOLO9 с заданным сидом, которые вызывают перестройку головы, стартуют с другой инициализации, потому что сид теперь применяется до перестройки, а не после. Дообучение с сидом, сделанное на 1.4.0 под другое число классов, не воспроизводится побитово на 1.5.0.
  • libreyolo[hub-kernels] на CUDA теперь действительно задействует нативное ядро MS-deform-attn. В 1.4.0 оно было закрыто условием, в которое RF-DETR никогда не попадал, поэтому ядро не запускалось. Предсказания могут сдвигаться в пределах точности float для RF-DETR и других семейств с deformable attention. Обычные установки это не затрагивает, а LIBREYOLO_HUB_KERNELS=0 отключает ядро.
  • libreyolo predict отбрасывает неподдерживаемые опции вместо ошибки. CLI фильтрует kwargs по сигнатуре __call__ модели, поэтому опция, которую семейство не принимает, игнорируется, а не приводит к TypeError. Неизвестное имя флага по-прежнему отклоняется с No such option.
  • Источники в реальном времени меняют форму JSON-вывода. Веб-камеры, RTSP-потоки и захват экрана неявно включают стриминг, а он выдаёт по одной записи на кадр, а не одну на вызов. Эти источники появились в 1.5.0, поэтому ни один скрипт для 1.4.0 не затронут.
  • Повторный экспорт rfdetr-pose или yolonas-pose в ONNX даёт другие имена выходов. В 1.4.0 их многотензорные головы для оценки позы ошибочно определялись как сегментация — по эвристике на число выходов. Уже лежащие на диске файлы .onnx не затронуты.
  • В установке без torch результаты содержат массивы numpy, а не torch.Tensor, поэтому .boxes.data возвращает другой тип, а разрешение совпадений в NMS может отличаться от torchvision. С установленным torch поведение побайтово прежнее. См. облегчённая установка.
  • Объекты конфигурации сильнее проверяются при создании. У TrainConfig появился __post_init__, которого раньше не было, поэтому конфигурация, которая и так была некорректной, теперь падает сразу, а не в середине запуска. В сериализацию ValidationConfig добавился ключ edge_thresholds, и это ломает строгий обратный разбор дампа 1.4.0 через ValidationConfig(**dump).
  • Имена файлов весов у семейств с суффиксом задачи определяются иначе. segformer-b0 теперь соответствует файлу LibreSegformerb0-sem.pt. Это устраняет 404 при автоскачивании и ломает любой скрипт, в котором было жёстко прописано старое имя без суффикса.
  • Маркер pytest experimental_backend теперь называется extended_backend. Важно, только если вы запускаете набор тестов с -m.

Чекпойнты и датасеты

Чекпойнты, записанные в 1.4.0, загружаются без изменений. В схему добавились imgsz_h и imgsz_w для прямоугольных моделей, и она по-прежнему пишет скалярный imgsz = max(h, w) для кода, который читает её по-старому. Экспорт в ExecuTorch и MNN теперь требует сопроводительного файла — <program>.pte.json и <model>.mnn.json соответственно, — а экспорт HRNet несёт pose_input: "person_crop". Форматы датасетов не изменились.

Проверено с LibreYOLO v1.7.0.