# WhisperX mit Sprecherdiarisierung

WhisperX erweitert OpenAIs Whisper mit drei entscheidenden Verbesserungen: **Wortgenaue Zeitstempel** durch erzwungene Phonem-Alignment, **Sprecher-Diarisierung** mittels pyannote.audio, und **bis zu 70× Echtzeitgeschwindigkeit** durch gebündelte Inferenz mit faster-whisper. Es ist das bevorzugte Tool für Produktions-Transkriptionspipelines, die präzise Timing- und Sprechererkennung benötigen.

**GitHub:** [m-bain/whisperX](https://github.com/m-bain/whisperX) **PyPI:** [whisperx](https://pypi.org/project/whisperx/) **Lizenz:** BSD-4-Clause **Paper:** [arxiv.org/abs/2303.00747](https://arxiv.org/abs/2303.00747)

## Hauptmerkmale

* **Wortgenaue Zeitstempel** — ±50 ms Genauigkeit durch wav2vec2 erzwungenes Alignment (vs. ±500 ms im normalen Whisper)
* **Sprecher-Diarisierung** — identifizieren, wer was gesagt hat, via pyannote.audio 3.1
* **Gebündelte Inferenz** — bis zu 70× Echtzeitgeschwindigkeit auf RTX 4090
* **VAD Vorfilterung** — Silero VAD entfernt Stille vor der Transkription
* **Alle Whisper-Modelle** — von tiny bis large-v3-turbo
* **Mehrere Ausgabeformate** — JSON, SRT, VTT, TXT, TSV
* **Automatische Spracherkennung** — oder erzwinge eine bestimmte Sprache für schnellere Verarbeitung

## Anforderungen

| Komponente | Minimum               | Empfohlen               |
| ---------- | --------------------- | ----------------------- |
| GPU        | RTX 3060 12 GB        | RTX 4090 24 GB          |
| VRAM       | 4 GB (kleines Modell) | 10 GB+ (large-v3-turbo) |
| RAM        | 8 GB                  | 16 GB+                  |
| Festplatte | 5 GB                  | 20 GB (Modell-Cache)    |
| Python     | 3.9+                  | 3.11                    |
| CUDA       | 11.8+                 | 12.1+                   |

**HuggingFace-Token erforderlich** für Sprecher-Diarisierung — akzeptiere die Lizenz unter [pyannote/speaker-diarization-3.1](https://huggingface.co/pyannote/speaker-diarization-3.1).

**Clore.ai-Empfehlung:** RTX 3090 (~~$0.30–1.00/Tag) für das large-v3-turbo Modell mit Batch-Größe 16. RTX 4090 (~~$0.50–2.00/Tag) für maximalen Durchsatz bei Batch-Größe 32.

## Installation

```bash
# WhisperX installieren
pip install whisperx

# GPU überprüfen
python -c "import torch; print(torch.cuda.get_device_name(0))"
```

Falls du CUDA-Versionskonflikte bekommst:

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

## Schnellstart

```python
import whisperx
import json

device = "cuda"
compute_type = "float16"  # "int8" für weniger VRAM
batch_size = 16            # auf 4–8 reduzieren, wenn VRAM knapp ist

# 1. Modell laden
model = whisperx.load_model("large-v3-turbo", device, compute_type=compute_type)

# 2. Audio laden und transkribieren
audio = whisperx.load_audio("interview.mp3")
result = model.transcribe(audio, batch_size=batch_size)
print(f"Sprache: {result['language']}")

# 3. Für wortgenaue Zeitstempel alignen
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. Ergebnisse ausgeben
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. Speichern
with open("transcript.json", "w") as f:
    json.dump(result, f, indent=2, ensure_ascii=False)
```

## Beispielanwendungen

### Transkription mit Sprecher-Diarisierung

```python
import whisperx
import gc
import torch

device = "cuda"
HF_TOKEN = "hf_your_token_here"  # von huggingface.co/settings/tokens

# Schritt 1: Transkribieren
model = whisperx.load_model("large-v3-turbo", device, compute_type="float16")
audio = whisperx.load_audio("meeting.mp3")
result = model.transcribe(audio, batch_size=16)

# Vor dem Laden des Alignment-Modells GPU-Speicher freigeben
del model; gc.collect(); torch.cuda.empty_cache()

# Schritt 2: Alignen
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()

# Schritt 3: Diarisieren
diarize_model = whisperx.DiarizationPipeline(
    use_auth_token=HF_TOKEN, device=device
)
diarize_segments = diarize_model(audio, min_speakers=2, max_speakers=6)

# Schritt 4: Sprecher den Wörtern zuweisen
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']}")
```

### Kommandozeilen-Nutzung

```bash
# Basis-Transkription
whisperx audio.mp3 --model large-v3-turbo --device cuda

# Sprache erzwingen (schneller, überspringt Erkennung)
whisperx audio.mp3 --model large-v3-turbo --language en --device cuda

# Mit Sprecher-Diarisierung
whisperx audio.mp3 --model large-v3-turbo --diarize --hf_token hf_your_token

# SRT Untertitel-Ausgabe
whisperx audio.mp3 --model large-v3-turbo --output_format srt --output_dir ./subs/

# Low-VRAM-Modus
whisperx audio.mp3 --model medium --compute_type int8 --batch_size 4 --device cuda

# Verarbeite ein Verzeichnis im Batch
for f in /data/audio/*.mp3; do
  whisperx "$f" --model large-v3-turbo --output_dir /data/transcripts/
done
```

### SRT-Generierungsskript

```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 gespeichert nach {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")
```

## Leistungs-Benchmarks

| Methode          | Modell             | 1h Audio     | GPU          | Ca. Geschwindigkeit |
| ---------------- | ------------------ | ------------ | ------------ | ------------------- |
| Normales Whisper | large-v3           | \~60 min     | RTX 3090     | 1×                  |
| faster-whisper   | large-v3           | \~5 Min      | RTX 3090     | \~12×               |
| **WhisperX**     | **large-v3-turbo** | **\~1 min**  | **RTX 3090** | **\~60×**           |
| **WhisperX**     | **large-v3-turbo** | **\~50 Sek** | **RTX 4090** | **\~70×**           |

| Batch-Größe | Geschwindigkeit (RTX 4090) | VRAM  |
| ----------- | -------------------------- | ----- |
| 4           | \~30× Echtzeit             | 6 GB  |
| 8           | \~45× Echtzeit             | 8 GB  |
| 16          | \~60× Echtzeit             | 10 GB |
| 32          | \~70× Echtzeit             | 14 GB |

## Tipps für Clore.ai-Nutzer

* **Zwischen den Schritten freien VRAM** — Modelle löschen und aufrufen `torch.cuda.empty_cache()` zwischen Transkription, Alignment und Diarisierung
* **HuggingFace-Token** — du musst die pyannote-Modelllizenz akzeptieren, bevor Diarisierung funktioniert; setze `HF_TOKEN` als Umgebungsvariable
* **Batch-Größen-Tuning** — starte mit `batch_size=16`, auf 4–8 bei 12-GB-Karten reduzieren, auf 32 bei 24-GB-Karten erhöhen
* **`int8` Berechnung** — verwenden Sie `compute_type="int8"` um den VRAM-Verbrauch bei minimalem Qualitätsverlust zu halbieren
* **Docker-Image** — `pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime`
* **Persistenter Modell-Cache** — mounte `/root/.cache/huggingface` um zu vermeiden, Modelle bei jedem Container-Neustart erneut herunterzuladen

## Fehlerbehebung

| Problem                            | Lösung                                                                                                                      |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `CUDA out of memory`               | Reduziere `batch_size`, verwende `compute_type="int8"`, oder verwende ein kleineres Modell (medium, small)                  |
| Diarisierung gibt zurück `UNKNOWN` | Stelle sicher, dass der HuggingFace-Token gültig ist und du die pyannote-Lizenz akzeptiert hast                             |
| `Kein Modul namens 'whisperx'`     | `pip install whisperx` — überprüfe, dass kein Tippfehler vorliegt (es ist `whisperx`, nicht `whisper-x`)                    |
| Ungenaue Wort-Zeitstempel          | Prüfe, dass `whisperx.align()` nach aufgerufen wird `transcribe()` — rohes Whisper-Ausgabe fehlt Wortgenauigkeit            |
| Spracherkennung falsch             | Sprache erzwingen mit `--language en` oder `language="en"` in der Python-API                                                |
| Langsame Verarbeitung              | Erhöhen Sie `batch_size`, verwende `large-v3-turbo` anstelle von `large-v3`, stelle sicher, dass die GPU nicht geteilt wird |
