# WhisperX с диаризацией

WhisperX расширяет Whisper от OpenAI тремя ключевыми улучшениями: **метки времени на уровне слов** через принудительное выравнивание фонем, **диаризация говорящих** с использованием pyannote.audio, и **до 70× реального времени** через пакетную инференцию с faster-whisper. Это инструмент выбора для производственных конвейеров транскрибации, которым нужны точные временные метки и определение говорящих.

**GitHub:** [m-bain/whisperX](https://github.com/m-bain/whisperX) **PyPI:** [whisperx](https://pypi.org/project/whisperx/) **Лицензия:** BSD-4-Clause **Статья:** [arxiv.org/abs/2303.00747](https://arxiv.org/abs/2303.00747)

## Ключевые особенности

* **Метки времени на уровне слов** — точность ±50 мс благодаря принудительному выравниванию wav2vec2 (в сравнении с ±500 мс в обычном Whisper)
* **Диаризация говорящих** — определение, кто сказал что, с помощью pyannote.audio 3.1
* **Пакетная инференция** — до 70× реального времени на RTX 4090
* **Предварительная фильтрация VAD** — Silero VAD удаляет тишину перед транскрибацией
* **Все модели Whisper** — от tiny до large-v3-turbo
* **Несколько форматов вывода** — JSON, SRT, VTT, TXT, TSV
* **Автоматическое определение языка** — или принудительно задать конкретный язык для более быстрой обработки

## Требования

| Компонент | Минимум                 | Рекомендуется           |
| --------- | ----------------------- | ----------------------- |
| GPU       | RTX 3060 12 ГБ          | RTX 4090 24 ГБ          |
| VRAM      | 4 ГБ (маленькая модель) | 10 ГБ+ (large-v3-turbo) |
| ОЗУ       | 8 ГБ                    | 16 ГБ+                  |
| Диск      | 5 ГБ                    | 20 ГБ (кеш моделей)     |
| Python    | 3.9+                    | 3.11                    |
| CUDA      | 11.8+                   | 12.1+                   |

**Требуется токен HuggingFace** для диаризации говорящих — примите лицензию на [pyannote/speaker-diarization-3.1](https://huggingface.co/pyannote/speaker-diarization-3.1).

**Рекомендация Clore.ai:** RTX 3090 (~~$0.30–1.00/день) для модели large-v3-turbo с размером батча 16. RTX 4090 (~~$0.50–2.00/день) для максимальной пропускной способности при размере батча 32.

## Установка

```bash
# Установка WhisperX
pip install whisperx

# Проверить GPU
python -c "import torch; print(torch.cuda.get_device_name(0))"
```

Если возникают конфликты версий CUDA:

```bash
pip install torch==2.5.1+cu124 torchaudio==2.5.1+cu124 --index-url https://download.pytorch.org/whl/cu124
pip install whisperx
```

## Быстрый старт

```python
import whisperx
import json

device = "cuda"
compute_type = "float16"  # "int8" для меньшего объёма VRAM
batch_size = 16            # уменьшите до 4–8 при ограниченной VRAM

# 1. Загрузить модель
model = whisperx.load_model("large-v3-turbo", device, compute_type=compute_type)

# 2. Загрузить и транскрибировать аудио
audio = whisperx.load_audio("interview.mp3")
result = model.transcribe(audio, batch_size=batch_size)
print(f"Language: {result['language']}")

# 3. Выравнивание для меток времени на уровне слов
model_a, metadata = whisperx.load_align_model(
    language_code=result["language"], device=device
)
result = whisperx.align(
    result["segments"], model_a, metadata, audio, device,
    return_char_alignments=False,
)

# 4. Печать результатов
for seg in result["segments"]:
    print(f"[{seg['start']:.2f}s → {seg['end']:.2f}s] {seg['text']}")
    for w in seg.get("words", []):
        print(f"  '{w['word']}' @ {w.get('start', 0):.2f}s")

# 5. Сохранение
with open("transcript.json", "w") as f:
    json.dump(result, f, indent=2, ensure_ascii=False)
```

## Примеры использования

### Транскрибация с диаризацией говорящих

```python
import whisperx
import gc
import torch

device = "cuda"
HF_TOKEN = "hf_your_token_here"  # с https://huggingface.co/settings/tokens

# Шаг 1: Транскрибировать
model = whisperx.load_model("large-v3-turbo", device, compute_type="float16")
audio = whisperx.load_audio("meeting.mp3")
result = model.transcribe(audio, batch_size=16)

# Освободите GPU-память перед загрузкой модели выравнивания
del model; gc.collect(); torch.cuda.empty_cache()

# Шаг 2: Выравнивание
model_a, metadata = whisperx.load_align_model(
    language_code=result["language"], device=device
)
result = whisperx.align(result["segments"], model_a, metadata, audio, device)
del model_a; gc.collect(); torch.cuda.empty_cache()

# Шаг 3: Диаризация
diarize_model = whisperx.DiarizationPipeline(
    use_auth_token=HF_TOKEN, device=device
)
diarize_segments = diarize_model(audio, min_speakers=2, max_speakers=6)

# Шаг 4: Назначить говорящих словам
result = whisperx.assign_word_speakers(diarize_segments, result)

for seg in result["segments"]:
    speaker = seg.get("speaker", "UNKNOWN")
    print(f"[{speaker}] [{seg['start']:.1f}s → {seg['end']:.1f}s] {seg['text']}")
```

### Использование из командной строки

```bash
# Базовая транскрибация
whisperx audio.mp3 --model large-v3-turbo --device cuda

# Принудительно задать язык (быстрее, пропускает определение)
whisperx audio.mp3 --model large-v3-turbo --language en --device cuda

# С диаризацией говорящих
whisperx audio.mp3 --model large-v3-turbo --diarize --hf_token hf_your_token

# Вывод субтитров SRT
whisperx audio.mp3 --model large-v3-turbo --output_format srt --output_dir ./subs/

# Режим для малой VRAM
whisperx audio.mp3 --model medium --compute_type int8 --batch_size 4 --device cuda

# Обработка каталога пакетно
for f in /data/audio/*.mp3; do
  whisperx "$f" --model large-v3-turbo --output_dir /data/transcripts/
done
```

### Скрипт генерации SRT

```python
import whisperx

def transcribe_to_srt(audio_path, output_path, model_name="large-v3-turbo"):
    device = "cuda"
    model = whisperx.load_model(model_name, device, compute_type="float16")
    audio = whisperx.load_audio(audio_path)
    result = model.transcribe(audio, batch_size=16)

    model_a, metadata = whisperx.load_align_model(
        language_code=result["language"], device=device
    )
    result = whisperx.align(result["segments"], model_a, metadata, audio, device)

    with open(output_path, "w") as f:
        for i, seg in enumerate(result["segments"], 1):
            start = format_ts(seg["start"])
            end = format_ts(seg["end"])
            f.write(f"{i}\n{start} --> {end}\n{seg['text'].strip()}\n\n")

    print(f"SRT сохранён в {output_path}")

def format_ts(seconds):
    h = int(seconds // 3600)
    m = int((seconds % 3600) // 60)
    s = int(seconds % 60)
    ms = int((seconds % 1) * 1000)
    return f"{h:02d}:{m:02d}:{s:02d},{ms:03d}"

transcribe_to_srt("podcast.mp3", "podcast.srt")
```

## Тесты производительности

| Метод           | Модель             | Аудио 1ч     | GPU          | Прибл. скорость |
| --------------- | ------------------ | ------------ | ------------ | --------------- |
| Обычный Whisper | large-v3           | \~60 мин     | RTX 3090     | 1×              |
| faster-whisper  | large-v3           | \~5 мин      | RTX 3090     | \~12×           |
| **WhisperX**    | **large-v3-turbo** | **\~1 мин**  | **RTX 3090** | **\~60×**       |
| **WhisperX**    | **large-v3-turbo** | **\~50 сек** | **RTX 4090** | **\~70×**       |

| Размер батча | Скорость (RTX 4090)     | VRAM  |
| ------------ | ----------------------- | ----- |
| 4            | \~30× реального времени | 6 GB  |
| 8            | \~45× реального времени | 8 ГБ  |
| 16           | \~60× реального времени | 10 ГБ |
| 32           | \~70× реального времени | 14 ГБ |

## Советы для пользователей Clore.ai

* **Освобождайте VRAM между шагами** — удаляйте модели и вызывайте `torch.cuda.empty_cache()` между транскрибацией, выравниванием и диаризацией
* **Токен HuggingFace** — вы должны принять лицензию модели pyannote перед тем, как диаризация заработает; установите `HF_TOKEN` как переменную окружения
* **Настройка размера батча** — начните с `batch_size=16`, уменьшите до 4–8 на картах 12 ГБ, увеличьте до 32 на картах 24 ГБ
* **`int8` вычисление** — используйте `compute_type="int8"` чтобы сократить использование VRAM вдвое с минимальной потерей качества
* **Docker-образ** — `pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime`
* **Постоянный кеш моделей** — смонтируйте `/root/.cache/huggingface` чтобы не скачивать модели заново при каждом перезапуске контейнера

## Устранение неполадок

| Проблема                        | Решение                                                                                                              |
| ------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `CUDA — недостаточно памяти`    | Уменьшите `batch_size`, используйте `compute_type="int8"`, или используйте меньшую модель (medium, small)            |
| Диаризация возвращает `UNKNOWN` | Убедитесь, что токен HuggingFace действителен и вы приняли лицензию pyannote                                         |
| `Модуль 'whisperx' не найден`   | `pip install whisperx` — убедитесь, что нет опечатки (это `whisperx`, а не на `whisper-x`)                           |
| Плохие метки времени слов       | Проверьте, что `whisperx.align()` вызывается после `transcribe()` — сыой вывод Whisper не имеет точности по словам   |
| Неправильное определение языка  | Принудительно задайте язык с помощью `--language en` или `language="en"` в Python API                                |
| Медленная обработка             | Увеличьте `batch_size`, используйте `large-v3-turbo` вместо `large-v3`, убедитесь, что GPU не используется совместно |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-ru/audio-i-golos/whisperx.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
