- Зачем: - документация обещала large-v3-turbo на NVIDIA, где он недоступен, и умалчивала, что модель по умолчанию без CUDA понимает только русскую речь. - Что: - large-v3-turbo перенесён из таблицы faster-whisper в раздел OpenVINO с измеренными размерами моделей. - языковое ограничение авто-профиля и предупреждение CLI описаны в README, gpu.md и ADR-006. - в backlog добавлен пункт про turbo для faster-whisper, в gpu.md снято расхождение по скорости openvino-cpu. - Проверка: - вычитка diff, проверка якорной ссылки на docs/gpu.md.
13 KiB
PRD: local-transcriber — Локальный CLI для транскрипции аудио/видео
1. Обзор продукта
Название: local-transcriber
Тип: CLI-утилита (Python, управление зависимостями через uv)
Назначение: Принимает аудио- или видеофайл, выполняет распознавание речи локально (без внешних API), и создаёт рядом с исходным файлом markdown-файл с транскриптом и таймкодами.
Пример использования:
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
- Пользователь вызывает CLI, передаёт путь к файлу (или glob-маску, post-MVP)
- Файл валидируется по пути, размеру и расширению
- По
deviceвыбирается backend; аудио декодируется через PyAV без отдельного извлечения дорожки - Результат форматируется в markdown с таймкодами
- Файл
<имя>-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 Путь к выходному файлу
По умолчанию: <input_stem>-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:
# Транскрипт: meeting-2026-03-17.mp4
- **Дата транскрипции**: 2026-03-17 14:30:05
- **Модель**: large-v3
- **Язык**: ru (задан явно) / ru (определён автоматически)
- **Длительность**: 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)
- Speaker diarization — pyannote.audio, требует отдельной модели + GPU
- Батч-режим —
transcribe ./recordings/*.mp4; по умолчанию пропускает файлы, для которых транскрипт уже есть;--forceдля перезаписи - Экспорт в SRT/VTT — для субтитров
- Watch-режим — мониторинг директории, автотранскрипция новых файлов
- Интеграция с LLM —
--summarizeдля генерации саммари поверх транскрипта - Конфигурационный файл —
.transcriber.tomlдля дефолтов проекта