Обновление OpenVINO до 2026.3, large-v3-turbo и ONNX по умолчанию #6
@@ -8,7 +8,7 @@ transcribe meeting.mp4
|
||||
```
|
||||
|
||||
- **Полностью локально** — данные не покидают машину
|
||||
- **Авто-ускорение** — NVIDIA CUDA, Intel GPU (OpenVINO), ONNX (CPU), OpenVINO CPU или CPU fallback
|
||||
- **Авто-ускорение** — NVIDIA CUDA при наличии GPU, иначе ONNX на CPU
|
||||
- **Батч-режим** — обработка нескольких файлов за один вызов
|
||||
- **Из проводника Windows** — пункт Transcribe в меню «Отправить» ([установка](#контекстное-меню-проводника-windows))
|
||||
- **Markdown с таймкодами** — удобен для суммаризации ИИ
|
||||
@@ -33,18 +33,20 @@ uv tool install git+https://github.com/dementev-dev/local-transcriber
|
||||
|
||||
**3. Ускорение (ставится автоматически):**
|
||||
|
||||
- **Intel GPU** (Arc, встроенная графика): работает через OpenVINO — ускорение в ~2x vs CPU
|
||||
- **OpenVINO** (Intel/AMD x86 CPU): ставится автоматически на Linux и Windows — ускорение в 2-4x
|
||||
- **NVIDIA CUDA** (GPU): если есть GPU — транскрипция в 5-10× быстрее
|
||||
- **Windows**: `winget install -e --id Nvidia.CUDA --version 12.9` (от администратора), перезапустить терминал
|
||||
- **Linux / WSL2**: работает из коробки (нужен только драйвер: `nvidia-smi`)
|
||||
- **Без NVIDIA GPU**: автоматически используется ONNX с GigaAM RNN-T на CPU
|
||||
- **OpenVINO** для Intel GPU или x86 CPU остаётся доступен через явный
|
||||
`--device openvino`, `--device openvino-gpu` или `--device openvino-cpu`
|
||||
|
||||
**4. Готово:**
|
||||
|
||||
```bash
|
||||
transcribe meeting.mp4
|
||||
```
|
||||
Модели скачиваются автоматически при первом запуске (~1.5 GB для medium), нужен доступ в интернет.
|
||||
Модели скачиваются автоматически при первом запуске; размер зависит от выбранного
|
||||
профиля, нужен доступ в интернет.
|
||||
|
||||
<details>
|
||||
<summary><code>transcribe: command not found</code></summary>
|
||||
@@ -103,7 +105,7 @@ HuggingFace Hub использует симлинки для экономии м
|
||||
## Использование
|
||||
|
||||
```bash
|
||||
# Простой запуск (medium, русский, автодетект устройства)
|
||||
# Простой запуск (CUDA medium или ONNX GigaAM RNN-T, язык ru)
|
||||
transcribe meeting.mp4
|
||||
|
||||
# Указать язык
|
||||
@@ -180,11 +182,11 @@ transcribe --uninstall-menu
|
||||
|
||||
| Опция | Сокращение | По умолчанию | Описание |
|
||||
|-------|-----------|-------------|----------|
|
||||
| `--model` | `-m` | `medium` | Модель Whisper |
|
||||
| `--model` | `-m` | medium (CUDA) / gigaam-v3-e2e-rnnt (ONNX) | Модель распознавания |
|
||||
| `--language` | `-l` | `ru` | Язык (ru, en, auto и др.) |
|
||||
| `--output` | `-o` | `<файл>-transcript.md` | Путь к выходному файлу |
|
||||
| `--device` | `-d` | `auto` | Устройство (auto, cpu, cuda, openvino, openvino-gpu, openvino-cpu, onnx) |
|
||||
| `--compute-type` | — | float16 (CUDA) / int8 (OpenVINO/ONNX) / float32 (CPU) | Тип вычислений |
|
||||
| `--compute-type` | — | float16 (CUDA) / int8 (ONNX/OpenVINO) / float32 (CPU) | Тип вычислений |
|
||||
| `--threads` | `-t` | 0 (авто) | Потоки CPU (рекомендуется = число физ. ядер) |
|
||||
| `--force` | `-f` | — | Перезаписать существующие транскрипты |
|
||||
| `--verbose` | `-v` | — | Подробный вывод |
|
||||
@@ -193,10 +195,9 @@ transcribe --uninstall-menu
|
||||
|
||||
| | Linux / WSL2 | macOS | Windows |
|
||||
|---|---|---|---|
|
||||
| CPU | ✅ | ✅ | ✅ |
|
||||
| OpenVINO (x86 CPU) | ✅ авто | — | ✅ авто |
|
||||
| OpenVINO (Intel GPU) | ✅ авто | — | ✅ авто |
|
||||
| ONNX (CPU) | ✅ явно | ✅ явно | ✅ явно |
|
||||
| CPU через ONNX | ✅ авто | ✅ авто | ✅ авто |
|
||||
| OpenVINO (x86 CPU) | ✅ явно | — | ✅ явно |
|
||||
| OpenVINO (Intel GPU) | ✅ явно | — | ✅ явно |
|
||||
| GPU (NVIDIA) | ✅ авто | — | ✅ (нужен CUDA 12) |
|
||||
|
||||
<details>
|
||||
@@ -237,8 +238,10 @@ transcribe --uninstall-menu
|
||||
Дефолтные параметры можно задать в `.transcriber.toml`:
|
||||
|
||||
```toml
|
||||
model = "large-v3"
|
||||
language = "en"
|
||||
device = "openvino-cpu"
|
||||
model = "large-v3-turbo"
|
||||
compute_type = "int8"
|
||||
language = "ru"
|
||||
```
|
||||
|
||||
Порядок поиска:
|
||||
@@ -247,6 +250,11 @@ language = "en"
|
||||
|
||||
Приоритет: **CLI-аргумент > конфиг > device-aware дефолт > встроенный дефолт**.
|
||||
|
||||
При `device = "auto"` выбирается CUDA, если доступен `nvidia-smi`, иначе ONNX.
|
||||
Явный `device` из CLI или конфига отключает этот автоматический выбор.
|
||||
Каталоги моделей различаются между бэкендами, поэтому при закреплении `model`
|
||||
в конфиге рекомендуется явно закрепить и совместимый `device`.
|
||||
|
||||
Дефолты зависят от устройства:
|
||||
|
||||
| Параметр | CUDA | OpenVINO (GPU) | OpenVINO (CPU) | ONNX | CPU |
|
||||
@@ -258,7 +266,7 @@ language = "en"
|
||||
## Модели и GPU
|
||||
|
||||
Рекомендации:
|
||||
- **По умолчанию для ONNX:** `gigaam-v3-e2e-rnnt` — читаемый русский текст с
|
||||
- **По умолчанию без CUDA:** ONNX `gigaam-v3-e2e-rnnt` — читаемый русский текст с
|
||||
пунктуацией почти без потери скорости относительно сырого `gigaam-v3`
|
||||
- **Макс. качество (NVIDIA):** `large-v3` + `--compute-type float16`
|
||||
- **Макс. качество (Intel GPU):** `large-v3` + `--device openvino-gpu`
|
||||
|
||||
+33
-31
@@ -24,8 +24,9 @@ transcribe meeting-2026-03-17.mp4
|
||||
### 3.1. Основной flow
|
||||
|
||||
1. Пользователь вызывает CLI, передаёт путь к файлу (или glob-маску, post-MVP)
|
||||
2. Проверка: ffmpeg доступен в PATH
|
||||
3. Файл передаётся в faster-whisper (он сам обрабатывает и аудио, и видео через libav/ffmpeg — отдельное извлечение аудиодорожки не нужно)
|
||||
2. Файл валидируется по пути, размеру и расширению
|
||||
3. По `device` выбирается backend; аудио декодируется через PyAV без отдельного
|
||||
извлечения дорожки
|
||||
4. Результат форматируется в markdown с таймкодами
|
||||
5. Файл `<имя>-transcript.md` сохраняется рядом с исходным (кодировка: UTF-8)
|
||||
|
||||
@@ -41,16 +42,16 @@ transcribe meeting-2026-03-17.mp4
|
||||
transcribe <путь_к_файлу> [опции]
|
||||
|
||||
Опции:
|
||||
--model, -m Модель Whisper (tiny|base|small|medium|large-v3)
|
||||
По умолчанию: large-v3
|
||||
--model, -m Модель распознавания
|
||||
По умолчанию: medium (CUDA) / gigaam-v3-e2e-rnnt (ONNX)
|
||||
--language, -l Язык (ru|en|auto)
|
||||
По умолчанию: auto (автодетект)
|
||||
По умолчанию: ru
|
||||
--output, -o Путь к выходному файлу
|
||||
По умолчанию: <input_stem>-transcript.md
|
||||
--device, -d Устройство (auto|cpu|cuda|openvino|openvino-gpu|openvino-cpu)
|
||||
По умолчанию: auto (CUDA → OpenVINO GPU → OpenVINO CPU → CPU)
|
||||
--compute-type Тип вычислений (float16|int8|int8_float16|float32)
|
||||
По умолчанию: int8 (универсален для GPU 4-8 GB и CPU)
|
||||
--device, -d Устройство (auto|cpu|cuda|onnx|openvino|openvino-gpu|openvino-cpu)
|
||||
По умолчанию: auto (CUDA при наличии, иначе ONNX CPU)
|
||||
--compute-type Тип вычислений
|
||||
По умолчанию: float16 (CUDA) / int8 (ONNX)
|
||||
--verbose, -v Подробный вывод (прогресс сегментов)
|
||||
```
|
||||
|
||||
@@ -82,16 +83,17 @@ transcribe <путь_к_файлу> [опции]
|
||||
**Правила форматирования**:
|
||||
- Таймкоды в формате `[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
|
||||
|
||||
Определение типа — по расширению. Фактическое декодирование выполняет ffmpeg внутри faster-whisper; если формат не поддерживается, ошибка будет от ffmpeg.
|
||||
Определение типа — по расширению. Фактическое декодирование выполняет PyAV с
|
||||
встроенными библиотеками FFmpeg; системная установка `ffmpeg` не требуется.
|
||||
|
||||
## 4. Нефункциональные требования
|
||||
|
||||
@@ -102,6 +104,8 @@ transcribe <путь_к_файлу> [опции]
|
||||
| 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 мин) |
|
||||
|
||||
@@ -112,23 +116,22 @@ transcribe <путь_к_файлу> [опции]
|
||||
| RTX 3060 | 6 GB | ✅ | ✅ (впритык) | int8 — безопасный выбор |
|
||||
| RTX 4050 | 6 GB | ✅ | ✅ (впритык) | int8 — безопасный выбор |
|
||||
| Quadro M3000M | 4 GB | ✅ | ⚠️ может OOM | int8 обязательно |
|
||||
| Без GPU | — | CPU int8 | — | int8 на CPU |
|
||||
| Без GPU | — | ONNX GigaAM INT8 | — | auto выбирает ONNX |
|
||||
|
||||
Дефолт `int8` выбран как универсальный: работает на всех GPU от 4 GB и на CPU, при минимальной потере качества относительно float16.
|
||||
Device-aware дефолты выбирают `float16` для CUDA и `int8` для ONNX/OpenVINO.
|
||||
|
||||
### 4.2. Требования к окружению
|
||||
|
||||
- Python ≥ 3.13
|
||||
- ffmpeg в PATH (используется faster-whisper внутри для декодирования любых медиаформатов)
|
||||
- Для GPU: Linux/WSL2 — cuBLAS из nvidia-cublas-cu12 (ставится автоматически через `uv sync`); Windows — системный CUDA toolkit (см. ADR-001)
|
||||
- Дисковое пространство для моделей: ~3 GB (large-v3)
|
||||
- Дисковое пространство для моделей: зависит от выбранного backend и модели
|
||||
- Выходные файлы: UTF-8 (явная кодировка при записи)
|
||||
|
||||
### 4.3. Кроссплатформенность
|
||||
|
||||
- Linux: нативный запуск
|
||||
- Windows: нативный Python или WSL2
|
||||
- macOS: не приоритет, но faster-whisper поддерживает CPU-режим
|
||||
- macOS: ONNX CPU в auto-режиме; FasterWhisper CPU доступен явно
|
||||
|
||||
## 5. Технический стек
|
||||
|
||||
@@ -136,19 +139,18 @@ transcribe <путь_к_файлу> [опции]
|
||||
|---------------------|-------------------------------------------------|
|
||||
| Язык | Python 3.13+ |
|
||||
| Управление проектом | uv (pyproject.toml) |
|
||||
| Распознавание речи | faster-whisper (CTranslate2 backend) |
|
||||
| Медиа-декодирование | ffmpeg (системная зависимость, используется faster-whisper внутри) |
|
||||
| Распознавание речи | faster-whisper, ONNX Runtime, OpenVINO GenAI |
|
||||
| Медиа-декодирование | PyAV со встроенными библиотеками FFmpeg |
|
||||
| CLI-фреймворк | typer |
|
||||
| Прогресс | rich (progress bar + статус) |
|
||||
|
||||
### 5.1. Почему faster-whisper
|
||||
### 5.1. Почему несколько backend
|
||||
|
||||
- В 4× быстрее оригинального OpenAI Whisper при том же качестве
|
||||
- Меньше потребление VRAM (large-v3 влезает в 6 GB с float16/int8)
|
||||
- Нативный Python API, без Docker
|
||||
- Поддержка CPU fallback из коробки
|
||||
- Активное сообщество, регулярные обновления
|
||||
- Автоматическая загрузка моделей из Hugging Face Hub
|
||||
- faster-whisper оптимизирован для NVIDIA CUDA и поддерживает много языков
|
||||
- ONNX GigaAM RNN-T даёт быстрый читаемый результат на CPU
|
||||
- OpenVINO предоставляет явные профили для Intel GPU и x86 CPU
|
||||
- Все backend работают локально через Python API, без Docker и облачных ключей
|
||||
- Модели загружаются автоматически и кешируются локально
|
||||
|
||||
### 5.2. Структура проекта
|
||||
|
||||
@@ -160,9 +162,10 @@ local-transcriber/
|
||||
│ └── local_transcriber/
|
||||
│ ├── __init__.py
|
||||
│ ├── cli.py # CLI entry point (typer)
|
||||
│ ├── transcriber.py # Обёртка над faster-whisper
|
||||
│ ├── transcriber.py # Оркестрация backend и fallback
|
||||
│ ├── backends/ # Адаптеры FasterWhisper, ONNX и OpenVINO
|
||||
│ ├── formatter.py # Форматирование в markdown
|
||||
│ └── utils.py # Проверки (ffmpeg), определение device и т.д.
|
||||
│ └── utils.py # Проверки файлов и определение device
|
||||
└── tests/
|
||||
└── ...
|
||||
```
|
||||
@@ -173,11 +176,10 @@ local-transcriber/
|
||||
|------|---------|-----------|
|
||||
| Качество распознавания русского текста | Среднее | large-v3 хорошо справляется с ru; при проблемах — попробовать `--language ru` вместо auto |
|
||||
| Нет разделения по спикерам | Низкое | Осознанно выведено за скоуп MVP; добавление diarization (pyannote.audio) — возможное расширение |
|
||||
| ffmpeg отсутствует в системе | Высокое | Проверка при старте + понятное сообщение об ошибке с инструкцией по установке |
|
||||
| Первый запуск: долгая загрузка модели | Низкое | Прогресс-бар при скачивании; модели кешируются в `~/.cache/huggingface/` |
|
||||
| CUDA несовместимость на Windows | Среднее | Автоматический fallback на CPU + предупреждение; в README — инструкция по CUDA |
|
||||
| Большие файлы (>2 часов) | Низкое | faster-whisper работает потоково, не грузит всё в память |
|
||||
| OOM на GPU с 4 GB VRAM | Среднее | Дефолт int8 (~2.5 GB); при OOM — fallback на CPU с предупреждением |
|
||||
| Большие файлы (>2 часов) | Среднее | Учитывать память выбранного backend; чанкование рассматривается отдельно |
|
||||
| OOM на GPU с 4 GB VRAM | Среднее | CUDA использует float16; при OOM — fallback на CPU с предупреждением или явный более лёгкий профиль |
|
||||
| Файл без речи (тишина, музыка, шум) | Низкое | Создаётся транскрипт с шапкой метаданных и `*Речь не обнаружена.*` в теле + предупреждение в stderr |
|
||||
|
||||
## 7. Вне скоупа MVP
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
**Статус**: Принято
|
||||
**Дата**: 2026-03-21
|
||||
**Обновлено**: 2026-08-12
|
||||
|
||||
## Контекст
|
||||
|
||||
@@ -39,7 +40,8 @@ shared libraries. Ни то, ни другое не должно происхо
|
||||
Вместо отдельного `--backend` флага устройство само определяет бэкенд:
|
||||
- `cuda`, `cpu` → FasterWhisperBackend
|
||||
- `openvino` → OpenVINOBackend
|
||||
- `auto` → CUDA (nvidia-smi) → OpenVINO (import check + x86) → CPU
|
||||
- `onnx` → OnnxAsrBackend
|
||||
- `auto` → CUDA при наличии `nvidia-smi`, иначе ONNX на CPU
|
||||
|
||||
### load_model() — единственный владелец pipeline
|
||||
|
||||
@@ -71,18 +73,19 @@ OpenVINO модели предквантизированы (int8/fp16), compute_
|
||||
- Из дефолтов: для large-v3 автоматически выбирается fp16 (стабильнее по качеству)
|
||||
- Несуществующая пара (model + compute_type) при явном выборе → ошибка
|
||||
|
||||
### Обе зависимости по умолчанию
|
||||
### Зависимости бэкендов по умолчанию
|
||||
|
||||
faster-whisper (~37MB) и openvino-genai (~69MB) ставятся вместе — суммарно ~106MB,
|
||||
приемлемо. Модели скачиваются только для активного бэкенда. CUDA (nvidia-cublas-cu12,
|
||||
~554MB) остаётся conditional (Linux x86_64). OpenVINO — conditional (x86_64/AMD64, не macOS).
|
||||
faster-whisper, onnx-asr/onnxruntime и openvino-genai ставятся вместе. Модели
|
||||
скачиваются только для активного бэкенда. CUDA (`nvidia-cublas-cu12`) остаётся
|
||||
conditional для Linux x86_64. OpenVINO — conditional для x86_64/AMD64, кроме
|
||||
macOS; ONNX обеспечивает автоматический CPU-путь на остальных платформах.
|
||||
|
||||
## Последствия
|
||||
|
||||
- Обратная совместимость: `transcribe()` сохранён; `load_model()` изменил сигнатуру (возвращает 4-tuple вместо 2-tuple, добавлен `compute_type_explicit`)
|
||||
- Новый бэкенд добавляется одним файлом в `backends/` + регистрацией в `__init__.py`
|
||||
- Модели скачиваются по запросу — CUDA пользователь не качает OpenVINO модели, и наоборот
|
||||
- ARM и macOS: OpenVINO не ставится (platform markers), работает CPU через faster-whisper
|
||||
- ARM и macOS: OpenVINO не ставится (platform markers), auto использует ONNX
|
||||
|
||||
## Отклонённые альтернативы
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Статус**: Принято
|
||||
**Дата**: 2026-04-25
|
||||
**Обновлено**: 2026-08-11
|
||||
**Обновлено**: 2026-08-12
|
||||
|
||||
## Контекст
|
||||
|
||||
@@ -101,10 +101,11 @@ Mm-hmm-редукция и иностранные вставки **не обна
|
||||
|
||||
## Решение
|
||||
|
||||
**Принять onnx-asr как экспериментальный бэкенд с явным `--device onnx`.
|
||||
GigaAM v3 E2E RNN-T — модель по умолчанию для русских встреч на CPU.**
|
||||
**Принять onnx-asr как CPU-бэкенд автоматического профиля.
|
||||
GigaAM v3 E2E RNN-T — модель по умолчанию на машинах без CUDA.**
|
||||
|
||||
Бэкенд **не в auto-detect** — только при явном указании пользователем (политика experimental backend, как для openvino).
|
||||
Порядок `--device auto`: CUDA при наличии `nvidia-smi`, иначе ONNX. OpenVINO и
|
||||
FasterWhisper CPU остаются доступными через явный CLI-аргумент или конфиг.
|
||||
|
||||
Модели:
|
||||
- **`gigaam-v3-e2e-rnnt`** — модель по умолчанию: практически равна обычному
|
||||
@@ -122,7 +123,9 @@ GigaAM v3 E2E RNN-T — модель по умолчанию для русски
|
||||
- Пользователи CPU-only с русскоязычным контентом получают 3-5× ускорение по сравнению с OpenVINO medium **при превосходящем качестве** (4/5 vs 1-2/5 summary utility на длинных файлах).
|
||||
- Пользователи ONNX без явного `--model` получают пунктуацию и нормализацию
|
||||
RNN-T; более точный сырой CTC остаётся доступен как `--model gigaam-v3`.
|
||||
- Whisper medium (`--device openvino-cpu`) **остаётся допустимым** для коротких (≤30 мин) встреч с равномерной громкостью; на длинных файлах с тихими участками он галлюцинирует целыми блоками — этот риск зафиксирован, но решение не выводит OpenVINO из списка дефолтов (часть пользователей всё ещё нуждается в пунктуации, и для коротких файлов галлюцинации не воспроизводятся).
|
||||
- Whisper medium (`--device openvino-cpu`) **остаётся допустимым явным профилем**
|
||||
для коротких (≤30 мин) встреч с равномерной громкостью; на длинных файлах с
|
||||
тихими участками он может галлюцинировать целыми блоками.
|
||||
- Parakeet-v3 формально доступен, но в README рекомендуется только для англоязычного контента — для русского явно не годится.
|
||||
- GPU faster-whisper large-v3 остаётся эталоном по качеству (для пользователей с NVIDIA GPU).
|
||||
- Пост-процессинг GigaAM-транскрипта LLM-этапом нормализации (восстановление латинских терминов и имён компаний) — рекомендуемая практика для финального конспекта.
|
||||
@@ -131,7 +134,8 @@ GigaAM v3 E2E RNN-T — модель по умолчанию для русски
|
||||
|
||||
- **Galлюцинации Whisper medium на длинных файлах** — отдельный продуктовый риск, требующий собственного исследования. Возможно, имеет смысл ограничить максимальную длину чанка для openvino-medium, или дать предупреждение пользователю.
|
||||
- **Canary** (`nemo-canary-1b-v2`) — тяжелее, но multilingual + пунктуация. Кандидат на «лучшее качество за разумную скорость» для тех, кому важна пунктуация.
|
||||
- **Auto-detect onnx**: после стабилизации в production-использовании (несколько недель) — рассмотреть включение в auto-detect как первый CPU-бэкенд (ниже CUDA, выше OpenVINO).
|
||||
- Проверить профиль на других языках и при необходимости добавить явные
|
||||
многоязычные рекомендации; автоматическая политика намеренно не зависит от языка.
|
||||
|
||||
## Отклонённые альтернативы
|
||||
|
||||
@@ -139,5 +143,4 @@ GigaAM v3 E2E RNN-T — модель по умолчанию для русски
|
||||
|---|---|
|
||||
| NeMo Parakeet напрямую (без onnx-asr) | Требует PyTorch + CUDA, Python ≥ 3.12, ~2 GB зависимостей — слишком тяжело для CLI |
|
||||
| Замена faster-whisper на onnx-asr | faster-whisper поддерживает 99+ языков и пунктуацию, остаётся лучшим GPU-бэкендом |
|
||||
| GigaAM как auto-detect default | Экспериментальный бэкенд, политика — не сюрпризить существующих пользователей; включение в auto-detect — после периода стабилизации |
|
||||
| Parakeet-v3 как multilingual default | Воспроизведённые проблемы из ADR-005 (Mm-hmm-редукция, иноязычные вставки) делают его непригодным для русского; для других языков не валидировано в этом эксперименте |
|
||||
|
||||
@@ -252,16 +252,6 @@ SQL`), словарь пользовательский в `.transcriber.toml`.
|
||||
|
||||
---
|
||||
|
||||
### Включение `onnx` в `--device auto`
|
||||
|
||||
**Что:** После периода стабилизации `--device onnx` (несколько недель production-использования без жалоб) — рассмотреть включение в auto-detect chain.
|
||||
|
||||
**Порядок в chain (предложение):** CUDA → onnx (если CPU x86_64) → OpenVINO → CPU.
|
||||
|
||||
**Почему откладывается:** политика experimental backend — не сюрпризить существующих пользователей до накопления опыта. Источник: [ADR-006](adr/006-onnx-asr-backend.md#решение).
|
||||
|
||||
---
|
||||
|
||||
## Отклонённые направления
|
||||
|
||||
*(пока пусто — добавлять сюда то, что попробовали и решили не делать, с причиной)*
|
||||
|
||||
@@ -304,23 +304,21 @@ INT8 почти равен ему. Они лучше удерживают `FineB
|
||||
|
||||
### Что это означает для профиля по умолчанию
|
||||
|
||||
Результаты поддерживают ONNX GigaAM RNN-T как основной кандидат для русской
|
||||
речи на CPU: он быстрее всех на обеих машинах, дважды занял первое место по
|
||||
читаемости и пригодности для конспекта и использует VAD. Но делать его
|
||||
безусловным глобальным `--device auto` преждевременно:
|
||||
Результаты поддерживают ONNX GigaAM RNN-T как основной CPU-профиль: он быстрее
|
||||
всех на обеих машинах, дважды занял первое место по читаемости и пригодности
|
||||
для конспекта и использует VAD. После обсуждения принята простая политика:
|
||||
`--device auto` выбирает CUDA при наличии `nvidia-smi`, иначе ONNX.
|
||||
|
||||
Ограничения выбора сохраняются:
|
||||
|
||||
- GigaAM ориентирован на русский язык и хуже сохраняет латиницу, аббревиатуры,
|
||||
названия систем и компаний;
|
||||
- OpenVINO Whisper остаётся многоязычным путём и умеет использовать Intel GPU;
|
||||
- Turbo лучше GigaAM по WER и техническим терминам, хотя хуже подготовлен для
|
||||
непосредственного чтения;
|
||||
- изменение существующего auto-пути будет несовместимым изменением поведения и
|
||||
требует отдельной продуктовой задачи с language-aware выбором.
|
||||
|
||||
Практичный кандидат на будущую политику: `CUDA` для NVIDIA, OpenVINO для Intel
|
||||
GPU, ONNX GigaAM RNN-T для явно русской речи на CPU, OpenVINO/Whisper для других
|
||||
языков и явный выбор Turbo для технически насыщенных встреч. В рамках текущей
|
||||
задачи эта политика не реализуется.
|
||||
- изменение существующего auto-пути является несовместимым изменением поведения;
|
||||
явные значения из CLI и конфигурации остаются способом сохранить прежний
|
||||
OpenVINO/Whisper-профиль или выбрать Turbo для технически насыщенных встреч.
|
||||
|
||||
## Вывод
|
||||
|
||||
@@ -338,8 +336,9 @@ GPU, ONNX GigaAM RNN-T для явно русской речи на CPU, OpenVIN
|
||||
протокола может потребоваться последующая расстановка пунктуации.
|
||||
- Автоматических предупреждений о повторах или потере хвоста после обновления
|
||||
не было; ручная проверка нашла у medium одиночный ложный сегмент в конце RSQM.
|
||||
- Модель по умолчанию и порядок `--device auto` оставлены без изменений. Решение
|
||||
об их изменении требует отдельной продуктовой задачи.
|
||||
- В самом benchmark-коммите модель по умолчанию и порядок `--device auto` не
|
||||
менялись; по итогам анализа отдельно принято решение использовать ONNX на
|
||||
машинах без CUDA.
|
||||
- Повторный Ryzen-прогон подтвердил, что прежний блок из 11 повторов `medium`
|
||||
не воспроизводится: четыре последовательных прохода дали одинаковый текст без
|
||||
повторов и ложного хвоста. Это подтверждение для контрольного файла, а не
|
||||
|
||||
+7
-6
@@ -2,7 +2,7 @@
|
||||
|
||||
## Режимы `--device`
|
||||
|
||||
- `auto` (по умолчанию) — CUDA → OpenVINO GPU → OpenVINO CPU → CPU (первый доступный)
|
||||
- `auto` (по умолчанию) — CUDA при наличии `nvidia-smi`, иначе ONNX на CPU
|
||||
- `cuda` — строго NVIDIA GPU, ошибка если недоступен
|
||||
- `openvino` — авто-выбор OpenVINO GPU или CPU
|
||||
- `openvino-gpu` — строго Intel GPU через OpenVINO
|
||||
@@ -14,12 +14,13 @@
|
||||
| Оборудование | Рекомендуемый `--device` | Бэкенд | Ожидаемая скорость |
|
||||
|---|---|---|---|
|
||||
| NVIDIA GPU (6+ GB VRAM) | `auto` / `cuda` | faster-whisper (CTranslate2) | 7-19x реалтайм |
|
||||
| Intel Arc iGPU / dGPU | `auto` / `openvino-gpu` | OpenVINO GenAI (GPU) | TBD |
|
||||
| Intel/AMD x86 CPU | `auto` / `openvino-cpu` | OpenVINO GenAI (CPU) | 3-6x реалтайм* |
|
||||
| Любой CPU (fallback) | `cpu` | faster-whisper (CTranslate2) | ~1.5x реалтайм |
|
||||
| Apple Silicon (macOS) | `cpu` | faster-whisper (CTranslate2) | ~2x реалтайм |
|
||||
| Любой CPU без NVIDIA | `auto` / `onnx` | ONNX GigaAM RNN-T | 10-14x реалтайм* |
|
||||
| Intel Arc iGPU / dGPU | `openvino-gpu` | OpenVINO GenAI (GPU) | TBD |
|
||||
| Intel/AMD x86 CPU | `openvino-cpu` | OpenVINO GenAI (CPU) | 3-10x реалтайм* |
|
||||
| Любой CPU, FasterWhisper | `cpu` | faster-whisper (CTranslate2) | ~1.5x реалтайм |
|
||||
|
||||
\* По результатам тестирования на Intel и AMD CPU. Реальная скорость зависит от CPU и модели.
|
||||
\* По результатам контрольных прогонов на Intel и AMD CPU. Реальная скорость
|
||||
зависит от CPU, модели и записи.
|
||||
|
||||
## OpenVINO
|
||||
|
||||
|
||||
@@ -114,7 +114,11 @@ def _print_quality_warnings(result: TranscribeResult, file_name: str | None = No
|
||||
def main(
|
||||
files: list[Path] | None = typer.Argument(None, help="Пути к аудио/видеофайлам"),
|
||||
model: str | None = typer.Option(
|
||||
None, "--model", "-m", show_default=False, help="Модель Whisper [по умолч.: medium]"
|
||||
None,
|
||||
"--model",
|
||||
"-m",
|
||||
show_default=False,
|
||||
help="Модель [по умолч.: medium (CUDA) / gigaam-v3-e2e-rnnt (ONNX)]",
|
||||
),
|
||||
language: str | None = typer.Option(
|
||||
None, "--language", "-l", show_default=False, help="Язык [по умолч.: ru]"
|
||||
@@ -126,7 +130,10 @@ def main(
|
||||
),
|
||||
compute_type: str | None = typer.Option(
|
||||
None, "--compute-type", show_default=False,
|
||||
help="Тип вычислений [по умолч.: float16 (CUDA) / int8 (OpenVINO GPU/CPU) / float32 (CPU)]"
|
||||
help=(
|
||||
"Тип вычислений [по умолч.: float16 (CUDA) / "
|
||||
"int8 (ONNX/OpenVINO) / float32 (CPU)]"
|
||||
),
|
||||
),
|
||||
threads: int = typer.Option(
|
||||
0, "--threads", "-t", show_default=False, min=0,
|
||||
|
||||
@@ -18,7 +18,7 @@ class TranscribeResult:
|
||||
language: str
|
||||
language_probability: float
|
||||
duration: float # seconds
|
||||
device_used: str # "cpu" / "cuda" / "openvino-gpu" / "openvino-cpu"
|
||||
device_used: str # "cpu" / "cuda" / "onnx" / "openvino-gpu" / "openvino-cpu"
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -16,18 +16,16 @@ SUPPORTED_EXTENSIONS = {
|
||||
def detect_device(requested: str = "auto") -> str:
|
||||
"""Определяет устройство для вычислений.
|
||||
|
||||
При ``requested="auto"`` проверяет: CUDA → OpenVINO GPU → OpenVINO CPU → CPU.
|
||||
``"openvino"`` — алиас для авто-детекта внутри OpenVINO (GPU если доступен, иначе CPU).
|
||||
При ``requested="auto"`` выбирает CUDA при наличии ``nvidia-smi``,
|
||||
иначе ONNX на CPU.
|
||||
``"openvino"`` — алиас для авто-детекта внутри OpenVINO
|
||||
(GPU если доступен, иначе CPU).
|
||||
Возвращает всегда конкретное значение (не абстрактный ``"openvino"``).
|
||||
"""
|
||||
if requested == "auto":
|
||||
if shutil.which("nvidia-smi") is not None:
|
||||
return "cuda"
|
||||
if _is_openvino_gpu_available():
|
||||
return "openvino-gpu"
|
||||
if _is_openvino_available():
|
||||
return "openvino-cpu"
|
||||
return "cpu"
|
||||
return "onnx"
|
||||
if requested == "openvino":
|
||||
if _is_openvino_gpu_available():
|
||||
return "openvino-gpu"
|
||||
|
||||
+51
-7
@@ -73,27 +73,32 @@ def test_cli_happy_path_exit_code_zero(tmp_path):
|
||||
def test_cli_default_options_passed_to_transcribe(tmp_path):
|
||||
audio = tmp_path / "test.mp3"
|
||||
audio.write_bytes(b"fake")
|
||||
result = _make_result()
|
||||
result = _make_result(device_used="onnx")
|
||||
model = _make_model()
|
||||
backend = _make_backend()
|
||||
tfr = _make_tfr(result=result, model=model, backend=backend)
|
||||
tfr = _make_tfr(result=result, model=model, actual_device="onnx", backend=backend)
|
||||
mock_transcribe_file = MagicMock(return_value=tfr)
|
||||
|
||||
with (
|
||||
patch("local_transcriber.cli.load_config", return_value={}),
|
||||
patch("local_transcriber.cli.validate_input_file", return_value=audio),
|
||||
patch("local_transcriber.cli.detect_device", return_value="cpu"),
|
||||
patch("local_transcriber.cli.load_model", return_value=(model, "cpu", backend, "/models/medium")),
|
||||
patch("local_transcriber.cli.detect_device", return_value="onnx"),
|
||||
patch(
|
||||
"local_transcriber.cli.load_model",
|
||||
return_value=(model, "onnx", backend, "/models/gigaam-v3-e2e-rnnt"),
|
||||
),
|
||||
patch("local_transcriber.cli._transcribe_file", mock_transcribe_file),
|
||||
patch("local_transcriber.cli.write_transcript"),
|
||||
):
|
||||
runner.invoke(app, [str(audio)])
|
||||
out = runner.invoke(app, [str(audio)])
|
||||
|
||||
call_kwargs = mock_transcribe_file.call_args[1]
|
||||
assert call_kwargs["model_name"] == "medium"
|
||||
assert call_kwargs["compute_type"] == "float32"
|
||||
assert call_kwargs["model_name"] == "gigaam-v3-e2e-rnnt"
|
||||
assert call_kwargs["compute_type"] == "int8"
|
||||
assert call_kwargs["language"] == "ru"
|
||||
assert call_kwargs["on_segment"] is None # verbose=False
|
||||
assert "Модель: gigaam-v3-e2e-rnnt" in out.output
|
||||
assert "Устройство: onnx" in out.output
|
||||
|
||||
|
||||
def test_cli_custom_options(tmp_path):
|
||||
@@ -660,6 +665,45 @@ def test_cli_config_applied(tmp_path):
|
||||
assert mock_load_model.call_args[0][0] == "tiny"
|
||||
|
||||
|
||||
def test_cli_config_overrides_auto_device(tmp_path):
|
||||
audio = tmp_path / "test.mp3"
|
||||
audio.write_bytes(b"fake")
|
||||
model = _make_model()
|
||||
backend = _make_backend()
|
||||
result = _make_result(device_used="openvino-cpu")
|
||||
tfr = _make_tfr(
|
||||
result=result,
|
||||
model=model,
|
||||
actual_device="openvino-cpu",
|
||||
backend=backend,
|
||||
)
|
||||
mock_detect_device = MagicMock(return_value="openvino-cpu")
|
||||
mock_load_model = MagicMock(
|
||||
return_value=(model, "openvino-cpu", backend, "/models/medium")
|
||||
)
|
||||
|
||||
with (
|
||||
patch(
|
||||
"local_transcriber.cli.load_config",
|
||||
return_value={
|
||||
"device": "openvino-cpu",
|
||||
"model": "medium",
|
||||
"compute_type": "int8",
|
||||
},
|
||||
),
|
||||
patch("local_transcriber.cli.validate_input_file", return_value=audio),
|
||||
patch("local_transcriber.cli.detect_device", mock_detect_device),
|
||||
patch("local_transcriber.cli.load_model", mock_load_model),
|
||||
patch("local_transcriber.cli._transcribe_file", return_value=tfr),
|
||||
patch("local_transcriber.cli.write_transcript"),
|
||||
):
|
||||
out = runner.invoke(app, [str(audio)])
|
||||
|
||||
assert out.exit_code == 0
|
||||
assert mock_detect_device.call_args_list[0].args == ("openvino-cpu",)
|
||||
assert mock_load_model.call_args.args[:3] == ("medium", "openvino-cpu", "int8")
|
||||
|
||||
|
||||
def test_cli_cli_overrides_config(tmp_path):
|
||||
audio = tmp_path / "test.mp3"
|
||||
audio.write_bytes(b"fake")
|
||||
|
||||
@@ -71,11 +71,17 @@ def test_load_config_invalid_device(tmp_path):
|
||||
|
||||
|
||||
def test_resolve_defaults_cli_wins():
|
||||
config = {"model": "tiny", "language": "en"}
|
||||
cli = {"model": "small", "language": None, "device": None, "compute_type": None}
|
||||
config = {"model": "tiny", "language": "en", "device": "openvino-cpu"}
|
||||
cli = {
|
||||
"model": "small",
|
||||
"language": None,
|
||||
"device": "onnx",
|
||||
"compute_type": None,
|
||||
}
|
||||
result = resolve_defaults(cli, config)
|
||||
assert result["model"] == "small"
|
||||
assert result["language"] == "en"
|
||||
assert result["device"] == "onnx"
|
||||
|
||||
|
||||
def test_resolve_defaults_config_wins():
|
||||
|
||||
+10
-9
@@ -61,27 +61,28 @@ def test_detect_device_explicit_passthrough():
|
||||
"""Явные device strings проходят без изменений."""
|
||||
assert detect_device("cpu") == "cpu"
|
||||
assert detect_device("cuda") == "cuda"
|
||||
assert detect_device("onnx") == "onnx"
|
||||
assert detect_device("openvino-gpu") == "openvino-gpu"
|
||||
assert detect_device("openvino-cpu") == "openvino-cpu"
|
||||
|
||||
|
||||
def test_detect_device_auto_openvino_gpu():
|
||||
"""auto + нет nvidia-smi + есть OpenVINO GPU → openvino-gpu."""
|
||||
def test_detect_device_auto_onnx_even_with_openvino_gpu():
|
||||
"""auto + нет nvidia-smi → onnx, даже если доступен OpenVINO GPU."""
|
||||
with (
|
||||
patch("local_transcriber.utils.shutil.which", return_value=None),
|
||||
patch("local_transcriber.utils._is_openvino_gpu_available", return_value=True),
|
||||
):
|
||||
assert detect_device("auto") == "openvino-gpu"
|
||||
assert detect_device("auto") == "onnx"
|
||||
|
||||
|
||||
def test_detect_device_auto_openvino_cpu():
|
||||
"""auto + нет nvidia-smi + есть OpenVINO, нет GPU → openvino-cpu."""
|
||||
def test_detect_device_auto_onnx_even_with_openvino_cpu():
|
||||
"""auto + нет nvidia-smi → onnx, даже если доступен OpenVINO CPU."""
|
||||
with (
|
||||
patch("local_transcriber.utils.shutil.which", return_value=None),
|
||||
patch("local_transcriber.utils._is_openvino_gpu_available", return_value=False),
|
||||
patch("local_transcriber.utils._is_openvino_available", return_value=True),
|
||||
):
|
||||
assert detect_device("auto") == "openvino-cpu"
|
||||
assert detect_device("auto") == "onnx"
|
||||
|
||||
|
||||
def test_detect_device_cuda_over_openvino():
|
||||
@@ -93,14 +94,14 @@ def test_detect_device_cuda_over_openvino():
|
||||
assert detect_device("auto") == "cuda"
|
||||
|
||||
|
||||
def test_detect_device_auto_cpu_fallback():
|
||||
"""Ни nvidia-smi, ни openvino → cpu."""
|
||||
def test_detect_device_auto_onnx_without_accelerators():
|
||||
"""Без CUDA auto выбирает ONNX CPU."""
|
||||
with (
|
||||
patch("local_transcriber.utils.shutil.which", return_value=None),
|
||||
patch("local_transcriber.utils._is_openvino_gpu_available", return_value=False),
|
||||
patch("local_transcriber.utils._is_openvino_available", return_value=False),
|
||||
):
|
||||
assert detect_device("auto") == "cpu"
|
||||
assert detect_device("auto") == "onnx"
|
||||
|
||||
|
||||
def test_detect_device_openvino_resolves_to_gpu():
|
||||
|
||||
Reference in New Issue
Block a user