73 lines
5.7 KiB
Markdown
73 lines
5.7 KiB
Markdown
# Исправленные проблемы проекта YOLO Train TUI
|
||
|
||
Дата исправления и повторной проверки: 2026-07-17
|
||
|
||
## Итог
|
||
|
||
Все 11 ранее зафиксированных дефектов исправлены и покрыты регрессионными
|
||
проверками.
|
||
|
||
| ID | Приоритет | Статус | Исправление |
|
||
|---|---|---|---|
|
||
| BUG-001 | Критический | Исправлено | `subprocess_runner.main()` возвращает код, а `SystemExit` создаётся только снаружи обрабатывающего блока |
|
||
| BUG-002 | Высокий | Исправлено | Перед каждым запуском `prepare_run()` сбрасывает состояние остановки |
|
||
| BUG-003 | Высокий | Исправлено | Родитель отправляет кооперативный сигнал; принудительный `kill()` используется только после таймаута |
|
||
| BUG-004 | Высокий | Исправлено | Запрос, сделанный до готовности subprocess, сохраняется и доставляется после маркера `READY` |
|
||
| BUG-005 | Высокий | Исправлено | Detection-style авторазбиение запрещено для `classify` в UI и конфигурации |
|
||
| BUG-006 | Средний | Исправлено | `.yaml`/`.yml` разбираются через `yaml.safe_load()`, поле `names` валидируется |
|
||
| BUG-007 | Средний | Исправлено | Датасет с одним изображением отклоняется с понятной ошибкой |
|
||
| BUG-008 | Средний | Исправлено | Изображения и метки ищутся рекурсивно с сохранением вложенных путей |
|
||
| BUG-009 | Средний | Исправлено | Каждый результат создаётся в уникальном `.yolo-tui/splits/<id>` без перезаписи пользовательского `split/` |
|
||
| BUG-010 | Низкий | Исправлено | Traceback выводится в журнал TUI; абсолютный путь другого пользователя удалён |
|
||
| BUG-011 | Низкий | Исправлено | Явно указанный отсутствующий или некорректный файл классов вызывает точную ошибку без fallback |
|
||
|
||
## Жизненный цикл обучения
|
||
|
||
- Дочерний процесс устанавливает обработчики остановки и только затем печатает
|
||
`__YOLO_TUI_READY__`.
|
||
- Если пользователь нажал «Остановить» раньше, родитель запоминает запрос и
|
||
отправляет его после получения маркера готовности.
|
||
- Дочерний `TrainingRunner` устанавливает `trainer.stop = True`; Ultralytics
|
||
останавливается между пакетами данных, затем выполняет штатную финализацию и
|
||
завершающие callbacks.
|
||
- Если процесс не завершился за 30 секунд, используется принудительный fallback.
|
||
- После завершения ссылка на subprocess и таймер очищаются; перед следующим
|
||
запуском флаг остановки сбрасывается.
|
||
|
||
## Работа с датасетами
|
||
|
||
- Текущий splitter предназначен для задач `detect`, `segment`, `pose` и `obb`
|
||
со структурой `images/` + `labels/`.
|
||
- Для `classify` требуется готовый каталог с `train`/`val` и подкаталогами
|
||
классов; несовместимый переключатель в UI отключён.
|
||
- Поддерживаются `classes.txt`, `.yaml` и `.yml`; YAML может хранить `names` как
|
||
список или словарь с последовательными ID от 0.
|
||
- Явный путь к классам считается обязательным и не заменяется автопоиском при
|
||
опечатке или ошибке формата.
|
||
- Split требует минимум два изображения и рекурсивно обрабатывает вложенные
|
||
каталоги.
|
||
- Файлы каждого запуска создаются эксклюзивно в отдельном управляемом каталоге.
|
||
|
||
## Проверка
|
||
|
||
Выполнены команды:
|
||
|
||
```text
|
||
uv run pytest -q
|
||
uv run python -m compileall -q src tests
|
||
git diff --check
|
||
```
|
||
|
||
Результат: `38 passed`; ошибок компиляции и форматирования diff нет.
|
||
|
||
Регрессионные тесты проверяют:
|
||
|
||
1. успешный и ошибочный коды `subprocess_runner.main()`;
|
||
2. сброс остановки между запусками;
|
||
3. кооперативный сигнал вместо немедленного `terminate()`;
|
||
4. доставку раннего запроса после готовности subprocess;
|
||
5. запрет авторазбиения для `classify`;
|
||
6. пользовательские YAML-файлы классов и ошибочный явный путь;
|
||
7. датасеты из одного и двух изображений;
|
||
8. вложенные изображения и метки;
|
||
9. сохранность пользовательского каталога `split/` и уникальность результатов.
|