transcription/README.md
2026-05-29 18:04:38 +03:00

360 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# WhisperX Meeting Transcription
Пайплайн для транскрибации аудиозаписей совещаний с диаризацией (кто говорил) и таймкодами.
## Стек
- **WhisperX** — ASR + alignment + диаризация (всё-в-одном)
- **python-docx** — генерация `.docx`
- **PyYAML** — конфигурация
## Установка
### 1. Python зависимости
```bash
pip install -r requirements.txt
```
### 2. ffmpeg (обязателен для видео)
Программа нуждается в ffmpeg для извлечения аудио из видео файлов.
**macOS:**
```bash
brew install ffmpeg
```
**Ubuntu/Debian:**
```bash
sudo apt-get update && sudo apt-get install ffmpeg
```
**Windows:**
Скачайте с [ffmpeg.org/download.html](https://ffmpeg.org/download.html) и добавьте в PATH.
### 3. HuggingFace токен
Нужен для диаризации (см. раздел ниже).
## 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')))"
```
## Первый запуск
**Важно:** при первом запуске программа скачает модели искусственного интеллекта. Это **нормально** и происходит только один time.
### Что скачивается
| Компонент | Размер | Назначение |
|-----------|--------|------------|
| Whisper `large-v3` | ~3.0 GB | Распознавание речи |
| Pyannote диаризация | ~0.4 GB | Разделение спикеров |
| Wav2Vec2 (русский) | ~1.0 GB | Точные таймкоды слов |
| **Итого** | **~45 GB** | **Скачиваются один раз** |
Время скачивания зависит от скорости интернета (обычно 1030 минут).
Все последующие запуски используют локальные файлы и работают **без интернета**.
### Где хранятся модели
Модели сохраняются в системный кэш:
- **Linux/Mac:** `~/.cache/`
- **Windows:** `%USERPROFILE%\.cache\`
## Работа офлайн — всё локально!
**Да, все модели работают полностью локально.**
Токен HuggingFace нужен **только один раз** — чтобы скачать модели при первом запуске. После этого:
-**Интернет не нужен** — можно отключить Wi-Fi
-**Аудио не уходит никуда** — обработка только на вашем устройстве
-**Текст не уходит в облако** — результат только у вас
-**Подходит для конфиденциальных совещаний**
### Что скачивается при первом запуске
| Компонент | Размер | Зачем |
|-----------|--------|-------|
| Whisper `large-v3` | ~3 GB | Распознавание речи |
| Pyannote диаризация | ~400 MB | Разделение спикеров |
| Wav2Vec2 (русский) | ~1 GB | Точные таймкоды слов |
| **Итого** | **~45 GB** | **Скачиваются один раз** |
Модели сохраняются в системный кэш (`~/.cache/` на Linux/Mac, `%USERPROFILE%\.cache\` на Windows) и переиспользуются при каждом запуске.
## Использование
```bash
python run.py -i meeting.wav -o meeting.docx
```
### Аргументы
| Аргумент | Описание |
|----------|----------|
| `-i, --input` | Путь к аудиофайлу (обязательный) |
| `-o, --output` | Путь к выходному файлу (если один формат) |
| `-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
# Базовый запуск (по умолчанию: docx + md)
python run.py -i meeting.wav
# Быстрый тест на маленькой модели
python run.py -i meeting.wav -m base
# Только один формат
python run.py -i meeting.wav -f docx
# Markdown выход
python run.py -i meeting.wav -f md -o meeting.md
```
**Видео файлы (автоматически извлекается аудио):**
```bash
# Из видео совещания
python run.py -i recording.mp4
# Из Zoom записи
python run.py -i zoom_meeting.mp4 -o protocol.docx
# Из Teams записи (MKV формат)
python run.py -i teams_recording.mkv
```
**Вывод в несколько форматов одновременно:**
```bash
# docx + md (по умолчанию из конфига)
python run.py -i meeting.wav
# docx + md + txt — все сразу
python run.py -i meeting.wav -f docx,md,txt
# Только docx и md
python run.py -i meeting.wav -f docx,md
# Явно указать выход только для одного формата, остальные рядом
python run.py -i meeting.wav -f docx,md -o output/meeting.docx
# Создаст: output/meeting.docx и output/meeting.md
```
**Продвинутые опции:**
```bash
# Сменить профиль
python run.py -i meeting.wav -p gpu_8gb
# Только CPU
python run.py -i meeting.wav -d cpu -m small
# Отключить диаризацию (быстрее, но без разделения спикеров)
# (нужно изменить diarize: false в config.yaml)
```
## Профили оборудования
Профили настроены в `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:
formats: [docx, md] # Можно указать один или несколько
include_timestamps: true
paragraph_pause_sec: 2.0
```
## 🐳 Docker
Проект полностью контейнеризирован — все модели ИИ внутри образа.
### Быстрый старт
```bash
# Установите токен
export HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxx
# Сборка и запуск (модели загрузятся в образ)
docker compose up --build -d
# Готово! Откройте http://localhost:8000
```
### Переменные окружения
| Переменная | Обязательная | Описание |
|------------|-------------|----------|
| `HF_TOKEN` | **Да** | HuggingFace токен для диаризации. Передаётся и при сборке, и при запуске. |
### Команды
```bash
# Сборка с токеном (модели внутри образа)
export HF_TOKEN=your_token
docker compose up --build -d
# Только запуск (если образ уже собран)
docker compose up -d
# Просмотр логов
docker compose logs -f
# Остановка
docker compose down
# Полная очистка (удалит данные!)
docker compose down -v
```
### Volumes
| Volume | Описание |
|--------|----------|
| `uploads` | Загруженные файлы |
| `processed` | Результаты транскрибации |
| `tmp` | Временные файлы |
Данные сохраняются между перезапусками контейнера.
## 🌐 Веб-интерфейс
Проект включает веб-сервис с минималистичным фронтендом для удобной работы через браузер.
### Функции веб-интерфейса
- 📤 **Drag & Drop загрузка** — перетащите файлы или выберите через диалог
- 📦 **Пакетная загрузка** — загружайте несколько файлов одновременно
- 📊 **Прогресс в реальном времени** — WebSocket показывает статус обработки каждого файла
- 🌳 **Файловый менеджер** — дерево обработанных совещаний с датами
- 📝 **Просмотр Markdown** — встроенный рендерер с подсветкой синтаксиса
- ⬇️ **Скачивание** — docx и md файлы доступны для скачивания
### Запуск веб-сервера
```bash
# Установите HF_TOKEN
export HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxx
# Запустите сервер
python start_server.py
```
Сервер поднимается на `http://localhost:8000`
Откройте браузер и перетащите файлы в зону загрузки. Обработка происходит в фоне, прогресс отображается в реальном времени.
### API Endpoints
| Endpoint | Метод | Описание |
|----------|-------|----------|
| `/` | GET | Фронтенд |
| `/upload` | POST | Загрузка одного файла |
| `/upload-batch` | POST | Пакетная загрузка |
| `/ws` | WebSocket | Прогресс обработки |
| `/api/tasks` | GET | Список задач |
| `/api/files` | GET | Дерево обработанных файлов |
| `/api/files/content?path=...` | GET | Содержимое файла |
| `/api/files/download?path=...` | GET | Скачивание файла |
## Ограничения
- Перекрывающаяся речь (overlap) распознаётся плохо
- Качество зависит от записи: тихий/шумный звук требует более мощных моделей
- На CPU `large-v3` работает медленно (1 час записи ≈ 30-60 мин обработки)