feat(cli): добавлен батч-режим и конфигурационный файл (шаги 8–12)
- Зачем: - обработка нескольких файлов за один вызов с загрузкой модели один раз. - хранение дефолтов (модель, язык, устройство) в .transcriber.toml. - Что: - добавлен config.py: поиск .transcriber.toml (CWD → ~/.config), парсинг, валидация, приоритет CLI > конфиг > хардкод. - рефакторинг transcriber.py: выделены load_model() и _transcribe_file() с TranscribeFileResult для переиспользования модели в батче. - добавлены expand_globs() с дедупликацией и has_existing_transcript() в utils.py. - CLI: files: list[Path], --force/-f, prescan-first батч с итоговой статистикой и временем, Status-спиннер для прогресса. - README: секции батч-режим, конфигурационный файл, --force в таблице опций. - ADR-002: зафиксированы архитектурные решения (prescan-first, TranscribeFileResult, конфиг без мержа). - Проверка: - uv run pytest -q — 94 passed, 1 skipped. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# ADR-002: Batch mode и config
|
||||
|
||||
**Статус**: Принято
|
||||
**Дата**: 2026-03-18
|
||||
|
||||
## Контекст
|
||||
|
||||
После завершения MVP (шаги 1–7) пользователям не хватает:
|
||||
- Обработки нескольких файлов за один вызов (batch mode)
|
||||
- Конфигурационного файла для хранения дефолтов (модель, язык, устройство)
|
||||
|
||||
## Решения
|
||||
|
||||
### 1. Prescan-first: валидация до загрузки модели
|
||||
|
||||
Модель загружается **только если есть файлы для обработки**. Перед загрузкой модели выполняется полный prescan: валидация всех файлов и проверка существующих транскриптов.
|
||||
|
||||
**Почему**: загрузка модели (large-v3) занимает ~10 секунд и ~3 GB RAM/VRAM. Повторный запуск по уже обработанным файлам должен быть дешёвым no-op.
|
||||
|
||||
### 2. TranscribeFileResult: возврат обновлённого состояния модели
|
||||
|
||||
При mid-stream CUDA fallback `_transcribe_file()` перезагружает модель на CPU внутри себя. Чтобы следующие файлы в батче не грузили модель повторно, результат включает обновлённые `model` и `actual_device`.
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class TranscribeFileResult:
|
||||
result: TranscribeResult
|
||||
model: WhisperModel # может измениться при fallback
|
||||
actual_device: str # может измениться при fallback
|
||||
```
|
||||
|
||||
**Альтернатива**: передавать модель по ссылке через mutable контейнер — менее явно и сложнее тестировать.
|
||||
|
||||
### 3. Конфиг: CWD → глобальный, без мержа
|
||||
|
||||
Порядок поиска:
|
||||
1. `.transcriber.toml` в текущей директории (проектный конфиг)
|
||||
2. `~/.config/transcriber/config.toml` (глобальный конфиг)
|
||||
|
||||
Первый найденный побеждает, мержа между файлами нет.
|
||||
|
||||
**Почему**: CWD-конфиг удобен для per-project дефолтов (`language = "ru"` для русскоязычного проекта), глобальный — для машинных дефолтов (`device = "cpu"` на ноутбуке без GPU). Мерж усложняет предсказуемость.
|
||||
|
||||
**Приоритет значений**: CLI > конфиг > хардкод.
|
||||
|
||||
### 4. `_transcribe_file()` — внутренний helper
|
||||
|
||||
Публичный API (`transcribe()`) сохранён без изменений. Новая функция `_transcribe_file()` — внутренний helper с префиксом `_`, не часть публичного контракта.
|
||||
|
||||
`transcribe()` стала тонкой обёрткой: `load_model()` + `_transcribe_file()` → `TranscribeResult`.
|
||||
|
||||
## Последствия
|
||||
|
||||
- Обратная совместимость CLI: `transcribe file.mp4` работает как раньше
|
||||
- Все существующие тесты проходят без изменений сигнатур
|
||||
- Batch mode: модель загружается один раз для всех файлов
|
||||
- `--force` флаг для перезаписи существующих транскриптов в батч-режиме
|
||||
Reference in New Issue
Block a user