2026-05-29 07:28:16 +00:00
|
|
|
|
# WhisperX Meeting Transcription
|
|
|
|
|
|
|
|
|
|
|
|
Пайплайн для транскрибации аудиозаписей совещаний с диаризацией (кто говорил) и таймкодами.
|
|
|
|
|
|
|
|
|
|
|
|
## Стек
|
|
|
|
|
|
|
|
|
|
|
|
- **WhisperX** — ASR + alignment + диаризация (всё-в-одном)
|
|
|
|
|
|
- **python-docx** — генерация `.docx`
|
|
|
|
|
|
- **PyYAML** — конфигурация
|
|
|
|
|
|
|
|
|
|
|
|
## Установка
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
pip install -r requirements.txt
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Дополнительно потребуется:
|
|
|
|
|
|
- [ffmpeg](https://ffmpeg.org/download.html) (для обработки аудио)
|
|
|
|
|
|
- HuggingFace токен для pyannote (см. ниже)
|
|
|
|
|
|
|
|
|
|
|
|
## HuggingFace Token (обязателен для диаризации)
|
|
|
|
|
|
|
|
|
|
|
|
### Зачем нужен токен?
|
|
|
|
|
|
|
|
|
|
|
|
WhisperX для определения спикеров (диаризация) использует модели `pyannote.audio`, которые хранятся на платформе HuggingFace. Эти модели:
|
|
|
|
|
|
- **НЕ являются публично доступными** без регистрации
|
|
|
|
|
|
- Требуют принятия пользовательского соглашения (license)
|
|
|
|
|
|
- Требуют аутентификации через токен при скачивании
|
|
|
|
|
|
|
|
|
|
|
|
Без токена диаризация **не будет работать** — вы получите ошибку авторизации.
|
|
|
|
|
|
|
|
|
|
|
|
### Как получить токен (пошагово)
|
|
|
|
|
|
|
|
|
|
|
|
**Шаг 1: Регистрация**
|
|
|
|
|
|
1. Перейдите на [huggingface.co](https://huggingface.co)
|
|
|
|
|
|
2. Нажмите "Sign Up" (регистрация через email или GitHub/Google)
|
|
|
|
|
|
3. Подтвердите email
|
|
|
|
|
|
|
|
|
|
|
|
**Шаг 2: Создание токена**
|
|
|
|
|
|
1. Войдите в аккаунт
|
|
|
|
|
|
2. Перейдите в [Settings → Access Tokens](https://huggingface.co/settings/tokens)
|
|
|
|
|
|
3. Нажмите "New token"
|
|
|
|
|
|
4. Введите название (например, `transcription`)
|
|
|
|
|
|
5. Выберите тип: **`Read`** (только чтение — достаточно)
|
|
|
|
|
|
6. Нажмите "Generate token"
|
|
|
|
|
|
7. **Скопируйте токен сразу** — он показывается только один раз!
|
|
|
|
|
|
|
|
|
|
|
|
**Шаг 3: Принятие соглашений**
|
|
|
|
|
|
|
|
|
|
|
|
Нужно принять соглашение для **каждой** из этих моделей (зайдите по ссылкам и нажмите "Access repository", затем согласитесь с условиями):
|
|
|
|
|
|
|
|
|
|
|
|
1. [pyannote/speaker-diarization-3.1](https://huggingface.co/pyannote/speaker-diarization-3.1)
|
|
|
|
|
|
2. [pyannote/segmentation-3.0](https://huggingface.co/pyannote/segmentation-3.0)
|
|
|
|
|
|
|
|
|
|
|
|
> **Важно:** Если не принять соглашения, даже с правильным токеном будет ошибка 403 (Forbidden)!
|
|
|
|
|
|
|
|
|
|
|
|
**Шаг 4: Установка токена**
|
|
|
|
|
|
|
|
|
|
|
|
Вариант A — через переменную окружения (рекомендуется):
|
|
|
|
|
|
```bash
|
|
|
|
|
|
export HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxx
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Вариант B — в `config.yaml` (менее безопасно, токен попадёт в git):
|
|
|
|
|
|
```yaml
|
|
|
|
|
|
hf_token: "hf_xxxxxxxxxxxxxxxxxxxxxxxx"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Вариант C — в `.env` файл (если добавить `.env` в `.gitignore`):
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# .env
|
|
|
|
|
|
HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxx
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
> **Безопасность:** Токен — это ваш пароль от HuggingFace. Никогда не коммитьте его в публичный репозиторий!
|
|
|
|
|
|
|
|
|
|
|
|
### Проверка токена
|
|
|
|
|
|
|
|
|
|
|
|
После установки можно проверить:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
python -c "import os; print('Token установлен:', bool(os.environ.get('HF_TOKEN')))"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-05-29 07:29:51 +00:00
|
|
|
|
## Работа офлайн — всё локально!
|
|
|
|
|
|
|
|
|
|
|
|
**Да, все модели работают полностью локально.**
|
|
|
|
|
|
|
|
|
|
|
|
Токен HuggingFace нужен **только один раз** — чтобы скачать модели при первом запуске. После этого:
|
|
|
|
|
|
|
|
|
|
|
|
- ✅ **Интернет не нужен** — можно отключить Wi-Fi
|
|
|
|
|
|
- ✅ **Аудио не уходит никуда** — обработка только на вашем устройстве
|
|
|
|
|
|
- ✅ **Текст не уходит в облако** — результат только у вас
|
|
|
|
|
|
- ✅ **Подходит для конфиденциальных совещаний**
|
|
|
|
|
|
|
|
|
|
|
|
### Что скачивается при первом запуске
|
|
|
|
|
|
|
|
|
|
|
|
| Компонент | Размер | Зачем |
|
|
|
|
|
|
|-----------|--------|-------|
|
|
|
|
|
|
| Whisper `large-v3` | ~3 GB | Распознавание речи |
|
|
|
|
|
|
| Pyannote диаризация | ~400 MB | Разделение спикеров |
|
|
|
|
|
|
| Wav2Vec2 (русский) | ~1 GB | Точные таймкоды слов |
|
|
|
|
|
|
| **Итого** | **~4–5 GB** | **Скачиваются один раз** |
|
|
|
|
|
|
|
|
|
|
|
|
Модели сохраняются в системный кэш (`~/.cache/` на Linux/Mac, `%USERPROFILE%\.cache\` на Windows) и переиспользуются при каждом запуске.
|
|
|
|
|
|
|
2026-05-29 07:28:16 +00:00
|
|
|
|
## Использование
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
python run.py -i meeting.wav -o meeting.docx
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Аргументы
|
|
|
|
|
|
|
|
|
|
|
|
| Аргумент | Описание |
|
|
|
|
|
|
|----------|----------|
|
|
|
|
|
|
| `-i, --input` | Путь к аудиофайлу (обязательный) |
|
|
|
|
|
|
| `-o, --output` | Путь к выходному файлу (docx/md/txt) |
|
|
|
|
|
|
| `-p, --profile` | Профиль: `mac_m4`, `gpu_8gb`, `cpu_best` |
|
|
|
|
|
|
| `-c, --config` | Путь к `config.yaml` |
|
|
|
|
|
|
| `-d, --device` | Принудительно: `cpu`, `cuda`, `mps` |
|
|
|
|
|
|
| `-m, --model` | Модель: `tiny`, `base`, `small`, `medium`, `large-v3` |
|
|
|
|
|
|
| `-l, --language` | Язык: `ru`, `en`, ... |
|
|
|
|
|
|
| `-f, --format` | Формат: `docx`, `md`, `txt` |
|
|
|
|
|
|
|
|
|
|
|
|
### Примеры
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Базовый запуск
|
|
|
|
|
|
python run.py -i meeting.wav
|
|
|
|
|
|
|
|
|
|
|
|
# Сменить профиль
|
|
|
|
|
|
python run.py -i meeting.wav -p gpu_8gb
|
|
|
|
|
|
|
|
|
|
|
|
# Быстрый тест на маленькой модели
|
|
|
|
|
|
python run.py -i meeting.wav -m base
|
|
|
|
|
|
|
|
|
|
|
|
# Только CPU
|
|
|
|
|
|
python run.py -i meeting.wav -d cpu -m small
|
|
|
|
|
|
|
|
|
|
|
|
# Markdown выход
|
|
|
|
|
|
python run.py -i meeting.wav -f md -o meeting.md
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Профили оборудования
|
|
|
|
|
|
|
|
|
|
|
|
Профили настроены в `config.yaml`:
|
|
|
|
|
|
|
|
|
|
|
|
- **`mac_m4`** (по умолчанию): CPU + int8, `large-v3`. Оптимально для MacBook Air M4 16GB.
|
|
|
|
|
|
- **`gpu_8gb`**: CUDA + float16/int8, `large-v3`, `batch_size=1`. Для видеокарты с 8GB VRAM.
|
|
|
|
|
|
- **`cpu_best`**: CPU + int8, `large-v3`. Универсальный CPU.
|
|
|
|
|
|
|
|
|
|
|
|
## Выходной формат
|
|
|
|
|
|
|
|
|
|
|
|
### DOCX
|
|
|
|
|
|
- Заголовок "Протокол совещания"
|
|
|
|
|
|
- Каждый спикер — отдельный абзац
|
|
|
|
|
|
- Таймкоды в формате `[HH:MM:SS.mmm]`
|
|
|
|
|
|
- Новый абзац при смене спикера или паузе > 2 сек
|
|
|
|
|
|
|
|
|
|
|
|
### Markdown / TXT
|
|
|
|
|
|
- Аналогичная структура
|
|
|
|
|
|
- Таймкоды опционально (включаются в `config.yaml`)
|
|
|
|
|
|
|
|
|
|
|
|
## Настройка
|
|
|
|
|
|
|
|
|
|
|
|
Измените `config.yaml`:
|
|
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
|
active_profile: mac_m4 # или gpu_8gb
|
|
|
|
|
|
|
|
|
|
|
|
profiles:
|
|
|
|
|
|
mac_m4:
|
|
|
|
|
|
device: cpu
|
|
|
|
|
|
compute_type: int8
|
|
|
|
|
|
model: large-v3
|
|
|
|
|
|
language: ru
|
|
|
|
|
|
|
|
|
|
|
|
output:
|
|
|
|
|
|
format: docx
|
|
|
|
|
|
include_timestamps: true
|
|
|
|
|
|
paragraph_pause_sec: 2.0
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Ограничения
|
|
|
|
|
|
|
|
|
|
|
|
- Перекрывающаяся речь (overlap) распознаётся плохо
|
|
|
|
|
|
- Качество зависит от записи: тихий/шумный звук требует более мощных моделей
|
|
|
|
|
|
- На CPU `large-v3` работает медленно (1 час записи ≈ 30-60 мин обработки)
|