docs: ADR-003, обновлены gpu.md и README для OpenVINO

- Зачем:
  - документация должна отражать новую архитектуру бэкендов и поддержку OpenVINO.
- Что:
  - docs/adr/003-pluggable-backends.md: Protocol, lazy imports, fallback, compute_type контракт.
  - docs/gpu.md: секция OpenVINO с таблицей моделей, таблица бэкендов, CUDA 12 для Windows исправлен везде.
  - README.md: OpenVINO в фичах, платформах, CLI опциях, дефолтах; fp16 документирован как OpenVINO-тип.
- Проверка:
  - uv run pytest -q — 124 passed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-22 00:02:52 +03:00
co-authored by Claude Opus 4.6
parent 262bfd91d1
commit 2d35bda976
3 changed files with 165 additions and 32 deletions
+23 -18
View File
@@ -8,7 +8,7 @@ transcribe meeting.mp4
``` ```
- **Полностью локально** — данные не покидают машину - **Полностью локально** — данные не покидают машину
- **Авто-GPU** — автоматически использует NVIDIA CUDA, если доступен - **Авто-ускорение** — NVIDIA CUDA, OpenVINO (Intel/AMD CPU) или CPU fallback
- **Батч-режим** — обработка нескольких файлов за один вызов - **Батч-режим** — обработка нескольких файлов за один вызов
- **Markdown с таймкодами** — удобен для суммаризации ИИ - **Markdown с таймкодами** — удобен для суммаризации ИИ
- **Аудио и видео** — mp3, wav, mp4, mkv и [другие форматы](#поддерживаемые-форматы) - **Аудио и видео** — mp3, wav, mp4, mkv и [другие форматы](#поддерживаемые-форматы)
@@ -30,10 +30,10 @@ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | ie
uv tool install git+https://github.com/dementev-dev/local-transcriber uv tool install git+https://github.com/dementev-dev/local-transcriber
``` ```
**3. (Опционально) GPU-ускорение:** **3. Ускорение (ставится автоматически):**
Если есть NVIDIA GPU — транскрипция будет в 5–10× быстрее. Требуется **CUDA 12** (ctranslate2 4.7 не совместим с CUDA 11 и 13).
- **OpenVINO** (Intel/AMD x86 CPU): ставится автоматически на Linux и Windows — ускорение в 2-4 раза
- **NVIDIA CUDA** (GPU): если есть GPU — транскрипция в 5-10× быстрее
- **Windows**: `winget install -e --id Nvidia.CUDA --version 12.9` (от администратора), перезапустить терминал - **Windows**: `winget install -e --id Nvidia.CUDA --version 12.9` (от администратора), перезапустить терминал
- **Linux / WSL2**: работает из коробки (нужен только драйвер: `nvidia-smi`) - **Linux / WSL2**: работает из коробки (нужен только драйвер: `nvidia-smi`)
@@ -106,8 +106,8 @@ transcribe *.mp4 --force
| `--model` | `-m` | `medium` | Модель Whisper | | `--model` | `-m` | `medium` | Модель Whisper |
| `--language` | `-l` | `ru` | Язык (ru, en, auto и др.) | | `--language` | `-l` | `ru` | Язык (ru, en, auto и др.) |
| `--output` | `-o` | `<файл>-transcript.md` | Путь к выходному файлу | | `--output` | `-o` | `<файл>-transcript.md` | Путь к выходному файлу |
| `--device` | `-d` | `auto` | Устройство (auto, cpu, cuda) | | `--device` | `-d` | `auto` | Устройство (auto, cpu, cuda, openvino) |
| `--compute-type` | — | float16 (GPU) / float32 (CPU) | Тип вычислений | | `--compute-type` | — | float16 (CUDA) / int8 (OpenVINO) / float32 (CPU) | Тип вычислений |
| `--force` | `-f` | — | Перезаписать существующие транскрипты | | `--force` | `-f` | — | Перезаписать существующие транскрипты |
| `--verbose` | `-v` | — | Подробный вывод | | `--verbose` | `-v` | — | Подробный вывод |
@@ -116,6 +116,7 @@ transcribe *.mp4 --force
| | Linux / WSL2 | macOS | Windows | | | Linux / WSL2 | macOS | Windows |
|---|---|---|---| |---|---|---|---|
| CPU | ✅ | ✅ | ✅ | | CPU | ✅ | ✅ | ✅ |
| OpenVINO (x86 CPU) | ✅ авто | — | ✅ авто |
| GPU (NVIDIA) | ✅ авто | — | ✅ (нужен CUDA 12) | | GPU (NVIDIA) | ✅ авто | — | ✅ (нужен CUDA 12) |
<details> <details>
@@ -166,11 +167,11 @@ language = "en"
Дефолты зависят от устройства: Дефолты зависят от устройства:
| Параметр | GPU (CUDA) | CPU | | Параметр | CUDA | OpenVINO | CPU |
|----------|-----------|-----| |----------|------|----------|-----|
| model | medium | medium | | model | medium | medium | medium |
| compute_type | float16 | float32 | | compute_type | float16 | int8 | float32 |
| language | ru | ru | | language | ru | ru | ru |
## Модели и GPU ## Модели и GPU
@@ -195,19 +196,23 @@ language = "en"
<details> <details>
<summary>Типы квантизации (--compute-type)</summary> <summary>Типы квантизации (--compute-type)</summary>
| Тип | Устройство | VRAM/RAM | Качество | Когда использовать | | Тип | Бэкенд | VRAM/RAM | Качество | Когда использовать |
|-----|-----------|----------|----------|--------------------| |-----|--------|----------|----------|--------------------|
| `float16` | GPU | ~4.5-5 GB | Отлично | **По умолчанию для GPU** | | `float16` | CUDA | ~4.5-5 GB | Отлично | **По умолчанию для CUDA** |
| `int8_float16` | GPU | ~4.7 GB | Отлично | GPU от 6 GB, альтернатива float16 | | `int8_float16` | CUDA | ~4.7 GB | Отлично | GPU от 6 GB, альтернатива float16 |
| `int8` | GPU/CPU | Низкое | Хорошо, но бывают галлюцинации | GPU от 4 GB, CPU | | `int8` | CUDA / OpenVINO | Низкое | Хорошо, но бывают галлюцинации | **По умолчанию для OpenVINO** |
| `fp16` | OpenVINO | Низкое | Отлично | OpenVINO large-v3 (выбирается автоматически) |
| `float32` | CPU | Среднее | Отлично | **По умолчанию для CPU** | | `float32` | CPU | Среднее | Отлично | **По умолчанию для CPU** |
**Важно:** `int8` на длинных записях может давать галлюцинации (повтор фраз, потеря контента). **Важно:** `int8` на длинных записях может давать галлюцинации (повтор фраз, потеря контента).
`float16` и `float32` значительно стабильнее на записях >20 минут. `float16`/`fp16` и `float32` значительно стабильнее на записях >20 минут.
> Для OpenVINO `--compute-type` выбирает предквантизированную модель (int8 или fp16),
> а не runtime-параметр. Для `large-v3` по умолчанию выбирается `fp16`.
</details> </details>
Подробнее: бенчмарки, совместимость GPU, результаты тестирования — [docs/gpu.md](docs/gpu.md). Подробнее: бенчмарки, OpenVINO, совместимость GPU, результаты тестирования — [docs/gpu.md](docs/gpu.md).
<details> <details>
<summary>Формат вывода</summary> <summary>Формат вывода</summary>
+96
View File
@@ -0,0 +1,96 @@
# ADR-003: Pluggable backends и OpenVINO
**Статус**: Принято
**Дата**: 2026-03-21
## Контекст
На CPU (faster-whisper/CTranslate2) транскрипция работает медленно (~1.5x реалтайм для medium).
CUDA доступна на малом проценте машин (ноутбуки с NVIDIA GPU), на офисных ПК её нет.
OpenVINO ускоряет inference на x86 CPU (Intel и AMD) в 2-4 раза. Для его поддержки
нужен второй движок транскрипции, а архитектура должна позволять добавлять новые
бэкенды (CoreML для Mac, AMD XDNA NPU) без переписывания существующего кода.
## Решение
### Backend Protocol (structural typing)
Минимальный интерфейс в `backends/base.py`:
```python
class Backend(Protocol):
def ensure_model_available(self, model_name, compute_type, on_status) -> str: ...
def create_model(self, model_path, device, compute_type) -> Any: ...
def transcribe(self, model, file_path, language, on_segment, on_status) -> TranscribeResult: ...
```
Protocol вместо ABC — бэкенды не наследуются, достаточно реализовать методы.
Соответствует стилю проекта (наследование нигде не используется).
### Ленивые импорты
Бэкенды импортируются только при выборе — `get_backend(device)` делает import внутри.
Импорт faster-whisper запускает CUDA bootstrap (~1ms), импорт openvino-genai загружает ~50MB
shared libraries. Ни то, ни другое не должно происходить, если бэкенд не выбран.
### Device как селектор бэкенда
Вместо отдельного `--backend` флага устройство само определяет бэкенд:
- `cuda`, `cpu` → FasterWhisperBackend
- `openvino` → OpenVINOBackend
- `auto` → CUDA (nvidia-smi) → OpenVINO (import check + x86) → CPU
### load_model() — единственный владелец pipeline
`load_model()` выполняет ensure_model_available + create_model в одном вызове.
CLI не вызывает ensure_model_available отдельно — это убирает двойной resolution
и гарантирует, что модель скачивается для правильного бэкенда.
### Cross-backend fallback
Fallback живёт в `transcriber.py` (оркестратор), не в бэкендах:
- CUDA ошибка → CPU (FasterWhisper)
- OpenVINO ошибка → CPU (FasterWhisper)
- `strict_device=True` (явный `--device`) → ошибка без fallback
При fallback в батч-режиме обновляются model, backend, model_path и actual_device
через TranscribeFileResult — следующий файл использует правильный бэкенд.
### Аудио для OpenVINO
OpenVINO GenAI WhisperPipeline принимает raw PCM float массив, не путь к файлу.
Используем `faster_whisper.decode_audio()` (PyAV) → `.tolist()``pipe.generate()`.
Системный ffmpeg не требуется — PyAV бандлит FFmpeg внутри wheel.
### compute_type для OpenVINO
OpenVINO модели предквантизированы (int8/fp16), compute_type определяет какую модель
скачать. Контракт:
- Явный `--compute-type` или значение из конфига — уважается всегда
- Из дефолтов: для 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).
## Последствия
- Обратная совместимость: `transcribe()` сохранён; `load_model()` изменил сигнатуру (возвращает 4-tuple вместо 2-tuple, добавлен `compute_type_explicit`)
- Новый бэкенд добавляется одним файлом в `backends/` + регистрацией в `__init__.py`
- Модели скачиваются по запросу — CUDA пользователь не качает OpenVINO модели, и наоборот
- ARM и macOS: OpenVINO не ставится (platform markers), работает CPU через faster-whisper
## Отклонённые альтернативы
| Альтернатива | Почему отклонена |
|---|---|
| OpenVINO как optional extra (`pip install .[openvino]`) | Теряется zero-config UX; пользователь должен знать про extras |
| whisper.cpp (pywhispercpp) | Другой движок, больший объём интеграции; OpenVINO GenAI проще |
| Единый бэкенд с OpenVINO для всего | CTranslate2 лучше оптимизирован для CUDA; OpenVINO — для CPU |
| ABC вместо Protocol | Наследование не используется в проекте; Protocol проще |
| librosa для загрузки аудио в OpenVINO | Лишняя зависимость; для видеоконтейнеров ненадёжна без системного ffmpeg |
| `--backend` как отдельный флаг | Усложняет CLI; device уже однозначно определяет бэкенд |
+44 -12
View File
@@ -1,10 +1,46 @@
# GPU и CUDA # Ускорение транскрипции
## Режимы `--device` ## Режимы `--device`
- `auto` (по умолчанию) — выберет GPU если `nvidia-smi` доступен, иначе CPU - `auto` (по умолчанию) — CUDA → OpenVINO → CPU (первый доступный)
- `cuda` — строго GPU, ошибка если недоступен (без silent fallback) - `cuda` — строго NVIDIA GPU, ошибка если недоступен
- `cpu` — строго CPU - `openvino` — OpenVINO на CPU (ускорение 2-4x на x86)
- `cpu` — строго CPU (faster-whisper/CTranslate2)
## Какой бэкенд на каком оборудовании
| Оборудование | Рекомендуемый `--device` | Бэкенд | Ожидаемая скорость |
|---|---|---|---|
| NVIDIA GPU (6+ GB VRAM) | `auto` / `cuda` | faster-whisper (CTranslate2) | 7-19x реалтайм |
| Intel/AMD x86 CPU | `auto` / `openvino` | OpenVINO GenAI | 3-6x реалтайм* |
| Любой CPU (fallback) | `cpu` | faster-whisper (CTranslate2) | ~1.5x реалтайм |
| Apple Silicon (macOS) | `cpu` | faster-whisper (CTranslate2) | ~2x реалтайм |
\* Ожидаемая оценка на основе бенчмарков OpenVINO. Реальная скорость зависит от CPU и модели.
## OpenVINO
OpenVINO ускоряет inference на x86 процессорах (Intel и AMD) через оптимизированные инструкции
(AVX2, AVX-512, VNNI, AMX). Ставится автоматически на Linux и Windows (x86_64/AMD64).
- **Модели**: предконвертированные из [HuggingFace](https://huggingface.co/OpenVINO) (int8/fp16)
- **Дефолт**: `medium` + `int8` (для `large-v3` автоматически выбирается `fp16`)
- **Аудиодекодирование**: через PyAV (бандлит FFmpeg), системный ffmpeg не нужен
### Доступные OpenVINO модели
| Модель | int8 | fp16 |
|--------|------|------|
| tiny | OpenVINO/whisper-tiny-int8-ov | — |
| base | — | OpenVINO/whisper-base-fp16-ov |
| small | OpenVINO/whisper-small-int8-ov | — |
| medium | OpenVINO/whisper-medium-int8-ov | — |
| large-v3 | OpenVINO/whisper-large-v3-int8-ov | OpenVINO/whisper-large-v3-fp16-ov |
### Качество OpenVINO int8
OpenVINO использует NNCF (калиброванная post-training квантизация), отличается от runtime-квантизации
CTranslate2. Качество может быть другим — **тестирование на реальных сэмплах рекомендуется**.
## Настройка по платформам ## Настройка по платформам
@@ -17,12 +53,10 @@
### Windows ### Windows
Нужен системный CUDA toolkit: Нужен системный **CUDA 12** (ctranslate2 4.7 не совместим с CUDA 11 и 13):
```bash ```bash
choco install cuda winget install -e --id Nvidia.CUDA --version 12.9 # требует запуска от имени администратора
# или
winget install -e --id Nvidia.CUDA # требует запуска от имени администратора
``` ```
После установки перезапустите терминал. После установки перезапустите терминал.
@@ -77,11 +111,9 @@ SQL, PostgreSQL, Greenplum, Airflow, ClickHouse, Docker, CDR, GTP, MAP).
### Windows: ошибка при загрузке модели на GPU ### Windows: ошибка при загрузке модели на GPU
GPU на Windows требует CUDA toolkit (включает cuBLAS). Установите: GPU на Windows требует **CUDA 12** (ctranslate2 4.7 не совместим с CUDA 11 и 13). Установите:
```bash ```bash
choco install cuda winget install -e --id Nvidia.CUDA --version 12.9 # требует запуска от имени администратора
# или
winget install -e --id Nvidia.CUDA
``` ```
После установки перезапустите терминал. После установки перезапустите терминал.