# PRD: local-transcriber — Локальный CLI для транскрипции аудио/видео ## 1. Обзор продукта **Название**: `local-transcriber` **Тип**: CLI-утилита (Python, управление зависимостями через uv) **Назначение**: Принимает аудио- или видеофайл, выполняет распознавание речи локально (без внешних API), и создаёт рядом с исходным файлом markdown-файл с транскриптом и таймкодами. **Пример использования**: ```bash transcribe meeting-2026-03-17.mp4 # → создаёт meeting-2026-03-17-transcript.md ``` ## 2. Целевые пользователи и сценарии - Разработчик/инженер, которому нужен текст из записи встречи, лекции, подкаста - Дальнейшая обработка транскрипта ИИ (суммаризация, извлечение action items и т.д.) — вне скоупа, но учитывается в формате вывода - Машины с GPU (NVIDIA, CUDA) и без GPU (CPU-only fallback) - Windows (native / WSL2) и Linux ## 3. Функциональные требования ### 3.1. Основной flow 1. Пользователь вызывает CLI, передаёт путь к файлу (или glob-маску, post-MVP) 2. Файл валидируется по пути, размеру и расширению 3. По `device` выбирается backend; аудио декодируется через PyAV без отдельного извлечения дорожки 4. Результат форматируется в markdown с таймкодами 5. Файл `<имя>-transcript.md` сохраняется рядом с исходным (кодировка: UTF-8) **Поведение при перезаписи**: - Явный вызов по файлу → транскрипт перезаписывается, даже если уже существует - Батч-режим (glob-маска, post-MVP) → пропускать файлы, для которых транскрипт уже существует; `--force` для принудительной перезаписи **Пустая речь**: если модель не распознала ни одного сегмента — файл транскрипта всё равно создаётся (шапка с метаданными + `*Речь не обнаружена.*` в теле), выводится предупреждение в stderr: `⚠ Речь не обнаружена в файле <имя>` ### 3.2. CLI-интерфейс ``` transcribe <путь_к_файлу> [опции] Опции: --model, -m Модель распознавания По умолчанию: medium (CUDA) / gigaam-v3-e2e-rnnt (ONNX) --language, -l Язык (ru|en|auto) По умолчанию: ru --output, -o Путь к выходному файлу По умолчанию: -transcript.md --device, -d Устройство (auto|cpu|cuda|onnx|openvino|openvino-gpu|openvino-cpu) По умолчанию: auto (CUDA при наличии, иначе ONNX CPU) --compute-type Тип вычислений По умолчанию: float16 (CUDA) / int8 (ONNX) --verbose, -v Подробный вывод (прогресс сегментов) ``` ### 3.3. Формат выходного файла Файл `*-transcript.md`: ```markdown # Транскрипт: meeting-2026-03-17.mp4 - **Дата транскрипции**: 2026-03-17 14:30:05 - **Модель**: large-v3 - **Язык**: ru (detected) / ru (forced) - **Длительность**: 01:23:45 - **Устройство**: CUDA (NVIDIA GeForce RTX 3060) --- [00:00.00 - 00:04.82] Добрый день, коллеги. Сегодня мы обсудим результаты квартала. [00:04.82 - 00:09.15] Первый вопрос — по метрикам продукта. [00:09.15 - 00:15.40] Как вы видите на слайде, MAU вырос на двадцать три процента по сравнению с предыдущим кварталом. ... ``` **Правила форматирования**: - Таймкоды в формате `[MM:SS.ss - MM:SS.ss]` (минуты:секунды.сотые) - Для записей длиннее 1 часа — `[HH:MM:SS.ss - HH:MM:SS.ss]` - Соседние сегменты объединяются в абзац до паузы 2 секунды или длительности 60 секунд - Метаданные в шапке файла - Пустая строка между абзацами для читаемости ### 3.4. Поддерживаемые форматы **Аудио**: mp3, wav, flac, ogg, m4a, wma, aac **Видео**: mp4, mkv, avi, mov, webm, ts Определение типа — по расширению. Фактическое декодирование выполняет PyAV с встроенными библиотеками FFmpeg; системная установка `ffmpeg` не требуется. ## 4. Нефункциональные требования ### 4.1. Производительность | Конфигурация | Ожидаемая скорость (real-time factor) | |---------------------------|---------------------------------------| | RTX 3060 + large-v3 | ~10-15x (1 час аудио ≈ 4-6 мин) | | RTX 4050 + large-v3 | ~12-18x (1 час аудио ≈ 3-5 мин) | | Quadro M3000M + large-v3 | ~3-5x (1 час аудио ≈ 12-20 мин) | | CPU + ONNX GigaAM RNN-T | ~10-14x (1 час аудио ≈ 4-6 мин) | | CPU + OpenVINO Turbo INT8 | ~7-10x (1 час аудио ≈ 6-9 мин) | | CPU (modern) + large-v3 | ~0.5-1x (1 час аудио ≈ 60-120 мин) | | CPU + small | ~3-5x (1 час аудио ≈ 12-20 мин) | ### 4.1.1. Совместимость GPU | GPU | VRAM | large-v3 int8 (~2.5 GB) | large-v3 float16 (~4.5 GB) | Рекомендация | |-------------------|-------|--------------------------|----------------------------|-------------------------| | RTX 3060 | 6 GB | ✅ | ✅ (впритык) | int8 — безопасный выбор | | RTX 4050 | 6 GB | ✅ | ✅ (впритык) | int8 — безопасный выбор | | Quadro M3000M | 4 GB | ✅ | ⚠️ может OOM | int8 обязательно | | Без GPU | — | ONNX GigaAM INT8 | — | auto выбирает ONNX | Device-aware дефолты выбирают `float16` для CUDA и `int8` для ONNX/OpenVINO. ### 4.2. Требования к окружению - Python ≥ 3.13 - Для GPU: Linux/WSL2 — cuBLAS из nvidia-cublas-cu12 (ставится автоматически через `uv sync`); Windows — системный CUDA toolkit (см. ADR-001) - Дисковое пространство для моделей: зависит от выбранного backend и модели - Выходные файлы: UTF-8 (явная кодировка при записи) ### 4.3. Кроссплатформенность - Linux: нативный запуск - Windows: нативный Python или WSL2 - macOS: ONNX CPU в auto-режиме; FasterWhisper CPU доступен явно ## 5. Технический стек | Компонент | Технология | |---------------------|-------------------------------------------------| | Язык | Python 3.13+ | | Управление проектом | uv (pyproject.toml) | | Распознавание речи | faster-whisper, ONNX Runtime, OpenVINO GenAI | | Медиа-декодирование | PyAV со встроенными библиотеками FFmpeg | | CLI-фреймворк | typer | | Прогресс | rich (progress bar + статус) | ### 5.1. Почему несколько backend - faster-whisper оптимизирован для NVIDIA CUDA и поддерживает много языков - ONNX GigaAM RNN-T даёт быстрый читаемый результат на CPU - OpenVINO предоставляет явные профили для Intel GPU и x86 CPU - Все backend работают локально через Python API, без Docker и облачных ключей - Модели загружаются автоматически и кешируются локально ### 5.2. Структура проекта ``` local-transcriber/ ├── pyproject.toml ├── README.md ├── src/ │ └── local_transcriber/ │ ├── __init__.py │ ├── cli.py # CLI entry point (typer) │ ├── transcriber.py # Оркестрация backend и fallback │ ├── backends/ # Адаптеры FasterWhisper, ONNX и OpenVINO │ ├── formatter.py # Форматирование в markdown │ └── utils.py # Проверки файлов и определение device └── tests/ └── ... ``` ## 6. Риски и ограничения | Риск | Влияние | Митигация | |------|---------|-----------| | Качество распознавания русского текста | Среднее | large-v3 хорошо справляется с ru; при проблемах — попробовать `--language ru` вместо auto | | Нет разделения по спикерам | Низкое | Осознанно выведено за скоуп MVP; добавление diarization (pyannote.audio) — возможное расширение | | Первый запуск: долгая загрузка модели | Низкое | Прогресс-бар при скачивании; модели кешируются в `~/.cache/huggingface/` | | CUDA несовместимость на Windows | Среднее | Автоматический fallback на CPU + предупреждение; в README — инструкция по CUDA | | Большие файлы (>2 часов) | Среднее | Учитывать память выбранного backend; чанкование рассматривается отдельно | | OOM на GPU с 4 GB VRAM | Среднее | CUDA использует float16; при OOM — fallback на CPU с предупреждением или явный более лёгкий профиль | | Файл без речи (тишина, музыка, шум) | Низкое | Создаётся транскрипт с шапкой метаданных и `*Речь не обнаружена.*` в теле + предупреждение в stderr | ## 7. Вне скоупа MVP - Разделение по спикерам (speaker diarization) - Веб-интерфейс / GUI - Пакетная обработка нескольких файлов (батч) — см. post-MVP - Стриминг с микрофона (real-time) - Интеграция с LLM для пост-обработки транскрипта - Перевод (translation mode) - Вывод в форматах SRT / VTT / JSON - Аудиофильтрация / шумоподавление (faster-whisper сам нормализует; ручной препроцессинг может ухудшить результат) ## 8. Возможные расширения (post-MVP) 1. **Speaker diarization** — pyannote.audio, требует отдельной модели + GPU 2. **Батч-режим** — `transcribe ./recordings/*.mp4`; по умолчанию пропускает файлы, для которых транскрипт уже есть; `--force` для перезаписи 3. **Экспорт в SRT/VTT** — для субтитров 4. **Watch-режим** — мониторинг директории, автотранскрипция новых файлов 5. **Интеграция с LLM** — `--summarize` для генерации саммари поверх транскрипта 6. **Конфигурационный файл** — `.transcriber.toml` для дефолтов проекта