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

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

Из публичного API моделей ничего не удалено: все классы и функции, которые работали в 1.4.0, по-прежнему импортируются. Четыре аргумента изменили форму, а три значения по умолчанию сдвигают числа, с которыми вы, возможно, сравниваете.

Применимо к
с 1.4.0 на 1.5.0
Требуемые изменения в коде
Четыре, все точечные
Что сдвигается в результатах
бэкенд COCO, BN eps в YOLOX, многомасштабность D-FINE
Удаления из публичного API
Нет

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

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

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

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

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

python
# 1.4.0
model.train(data="data.yaml", epochs=100, allow_experimental=True)

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

Прослойки для обратной совместимости нет. Вызов, который всё ещё его передаёт, завершается ошибкой TypeError. Вместе с аргументом удалён 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.0
predict_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 torch
from libreyolo import LibreYOLOX

model = LibreYOLOX("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. Опечатка в имени флага теперь молча игнорируется.
  • Источники в реальном времени меняют форму 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.5.0.