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

Устранение неполадок

Ошибки сгруппированы по сообщению, которое вы видите. Две записи в конце — про обратную проблему: код отрабатывает, возвращает что-то правдоподобное и при этом неверен.

Ошибки сгруппированы по тексту, который вы видите. Если вашего сообщения здесь нет, FAQ отвечает на вопросы, не связанные со сбоями, а libreyolo models показывает, что ваша установка действительно может загрузить.

ModuleNotFoundError с именем пакета, который вы не импортировали

Некоторым семействам нужен опциональный extra. В сообщении назван недостающий пакет, а не extra, поэтому по трейсбеку не всегда понятно, что чинить.

Запустите libreyolo models. Для каждого семейства с недостающей зависимостью выводится точная команда pip, которая его включает, так что сопоставлять пакет с extra вручную не нужно. libreyolo models --json выводит то же самое в виде объекта.

На странице установки перечислены все extra и то, что каждый из них покрывает.

ONNX inference requires onnxruntime

ImportError: ONNX inference requires onnxruntime. Install with: pip install onnxruntime

Базовый пакет не зависит ни от одной среды выполнения (runtime): какая из них нужна, определяется вашим железом. Установите onnxruntime для CPU или onnxruntime-gpu для CUDA. Оба дают один и тот же модуль onnxruntime, поэтому ставьте один, а не оба.

ONNX model not found

FileNotFoundError: ONNX model not found: <path>

Путь разрешается относительно рабочей директории, а не скрипта. Это же сообщение появляется, когда экспорт молча записал файл в другое место: export() возвращает путь, по которому записал, поэтому лучше сохранить возвращаемое значение, а не угадывать имя.

NotImplementedError из train()

Обучаются не все семейства. Некоторые портированы только для предсказания, валидации и экспорта, и их train() выбрасывает исключение, а не делает вид, что работает.

Ответ в FAQ объясняет причину. Чтобы проверить конкретное семейство, прежде чем писать скрипт обучения, посмотрите его страницу модели — там указано, обучается ли оно.

NotImplementedError из export()

Семейство может поддерживать задачу, но не поддерживать её экспорт. Чаще всего с этим сталкиваются в семействе EoMT: export() принимает семантическую задачу и выбрасывает исключение для segment и panoptic, потому что для них не определён нужный контракт среды выполнения query-mask.

NotImplementedError: LibreEoMT instance and panoptic export need query-mask runtime contracts.

На странице каждого семейства есть матрица экспорта: в ней видно, какие сочетания задачи и формата проверены.

CUDA out of memory

Сначала уменьшите batch, затем imgsz. Память меняется примерно пропорционально обоим, но батч — то, что можно уменьшить, не меняя того, что видит модель.

Если падает на валидации, а не на обучении, то у валидации свой размер батча — уменьшите и его.

В Windows у GPU с подключённым монитором есть второй сценарий отказа, который выглядит как случайная ошибка CUDA, а не как нехватка памяти: драйвер сбрасывает устройство, если оно не отвечает дольше таймаута, и убивает всё, что на нём выполнялось. Долго выполняющиеся ядра на карте, которая обслуживает монитор, могут это вызвать.

Веса не скачиваются

Веса скачиваются с Hugging Face при первом использовании и кэшируются локально. В FAQ описано, где лежит кэш и как работать полностью офлайн.

Если скачивание завершается ошибкой 404, проверьте имя файла, которое вы передали. URL строится из него, включая суффикс задачи, поэтому имя, не совпадающее с опубликованным чекпойнтом, даёт несуществующий URL. В таблице чекпойнтов на странице каждой модели перечислены точные опубликованные имена файлов.

Обучение зависает или перезапускается в Windows или macOS

В Windows нет fork, а Python на macOS по умолчанию его не использует, поэтому воркеры загрузчика данных запускаются, заново импортируя ваш скрипт. Без защиты if __name__ == "__main__": каждый воркер заново выполняет ваш вызов обучения, что либо приводит к взаимной блокировке, либо бесконечно порождает новые процессы.

python
def main():    ...  # собрать модель и вызвать train() if __name__ == "__main__":    main()

workers=0 тоже это устраняет, но ценой пропускной способности. Защита — более правильное решение.

Два сбоя, которые не выбрасывают исключение

Вся остальная страница — про ошибки. Эти два случая хуже, потому что код отрабатывает и возвращает что-то похожее на правду.

Индексирование одного результата

predict() возвращает один Results для одного изображения и список для нескольких. Индексирование результата для одного изображения выбирает детекцию, а не изображение:

python
result = model.predict("image.jpg")   # один Resultsresult.boxes                          # все детекции, верноresult[0].boxes                       # ОДНА детекция, без ошибки

Исключения не возникает, потому что индексирование Results — допустимая операция, возвращающая подмножество. Код, написанный под форму со списком, молча отдаёт по одной рамке на изображение. Индексируйте только то, что точно список.

Чтение метрик как атрибутов

val() возвращает словарь с ключами по именам метрик. Его единственный атрибут, box, содержит результаты по отдельным изображениям и пороги по классам, а не значения метрик:

python
metrics = model.val(data="coco8.yaml")metrics["metrics/mAP50-95"]   # верноmetrics.box.map               # AttributeError

Ключи разнесены по префиксам metrics/ и speed/. Выведите словарь один раз, чтобы посмотреть, что получилось для вашей задачи, — набор ключей зависит от задачи.

Проверка датасета до обучения

Большинство сбоев обучения — проблемы с датасетом. libreyolo doctor data.yaml прогоняет проверки датасета для детекции и выводит найденное с разбивкой по степени серьёзности, а это быстрее, чем разбирать трейсбек с первой эпохи.

python
from libreyolo import doctor report = doctor.diagnose("data.yaml", imgsz=640)if report.errors:    ...

Каталог проверок — на странице команды doctor.

Постоянные рабочие процессы не видят изменения датасета

Активные хуки close_mosaic или set_epoch должны достигать копий датасета, используемых рабочими процессами. Если собственный загрузчик с несколькими рабочими процессами сохраняет несовместимые постоянные копии, используйте persistent_workers=False или пересоздайте процессы после изменения. Путь без постоянных процессов, используемый по умолчанию, не затронут.

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