# 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 |


---

# 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-de/audio-and-sprache/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.
