Zum Inhalt
Anmelden

/docs · SignalLab · Deep

Segmentierung von Sprecherwechseln: der pragmatische Stack

Diarisierung ist ein schwieriges ML-Problem. Die Segmentierung von Sprecherwechseln, die günstige Variante, ist gut genug gelöst, um sie überall einzusetzen.


Echte Diarisierung, „kennzeichne jedes Audiosegment damit, wer gerade spricht”, ist ein schwieriges ML-Problem und ein aktives Forschungsgebiet. Die Segmentierung von Sprecherwechseln, „finde die Momente, in denen der Sprecher wechselt”, ist deutlich einfacher und für die meisten nachgelagerten Anwendungen nützlich.

Bei einem Audioarchiv ist „zeig mir die Wechsel” die häufigere Anfrage als „sag mir, wer spricht”. In diesem Dokument geht es darum, wie man die einfachere Variante gut umsetzt.

Die zwei Probleme, getrennt betrachtet

ProblemSchwierigkeitsgradWerkzeuge
Segmentierung von SprecherwechselnAllein anhand des Signals lösbarÄnderungen der Energie- + Spektralhüllkurve
SprecheridentifikationSchwierig, benötigt EmbeddingsModelle wie pyannote, NeMo, Resemblyzer
SprecherdiarisierungKombinierte Version aus beidemSchwierig, durchgängige ML-Systeme

Die meisten Menschen, die nach „Diarisierung” fragen, wollen eigentlich die Segmentierung von Sprecherwechseln. Kläre das, bevor du zu den schweren Werkzeugen greifst.

Der signalbasierte Ansatz

Ein Sprecherwechsel zeigt sich im Signal als Diskontinuität. Die einfachsten Merkmale, die ihn erfassen:

  1. Diskontinuität der Energiehüllkurve: Sprecher haben eine unterschiedliche Grundlautstärke. Ein Wechsel äußert sich oft als sprunghafte Änderung des kurzzeitigen RMS.
  2. Änderung der Spektralhüllkurve: Verschiedene Sprecher haben unterschiedliche Formantmuster. Selbst ohne festzustellen, wer es ist, kannst du erkennen, dass eine Änderung stattgefunden hat.
  3. Pausenstruktur: Wechsel werden meist von kurzen Pausen (50–300 ms) eingerahmt. Das Muster Pause-dann-anderes-Spektrum ist hochgradig prädiktiv.

Eine einfache Pipeline:

def segment_turns(samples, sr, min_turn_sec=2.0):
    # 1. Compute MFCCs in 25 ms frames, 10 ms hop
    mfccs = mfcc(samples, sr, n_mfcc=13, hop=int(0.01 * sr))
    # 2. Compute cosine distance between consecutive MFCC frames
    dists = [cosine_distance(mfccs[i], mfccs[i+1]) for i in range(len(mfccs)-1)]
    # 3. Smooth and threshold
    smoothed = moving_average(dists, window=5)
    threshold = percentile(smoothed, 95)
    # 4. Find peaks above threshold separated by min_turn_sec
    peaks = find_peaks(smoothed, height=threshold, distance=int(min_turn_sec / 0.01))
    return [p * 0.01 for p in peaks]  # convert to seconds

Das ist kein State-of-the-Art-Diarisierungssystem. Es ist eine 30-zeilige Funktion, die bei sauberem Material mit zwei Sprechern 80 % der Wechsel erfasst.

Warum es funktioniert

Sprecher unterscheiden sich in ihren Spektralhüllkurven (bestimmt durch Formantpositionen, Länge des Vokaltrakts, Tonhöhe) so stark, dass MFCC-Vektoren in unterschiedlichen Regionen des Merkmalsraums landen. Wenn der Sprecher mitten in einer Aufnahme wechselt, „springt” der MFCC-Vektor durch diesen Raum, und der Kosinusabstand zwischen aufeinanderfolgenden Frames schnellt nach oben.

Die einfache Glättung und die Perzentil-Schwellenwertbildung bewältigen den Großteil des Rauschens. Du wirst Wechsel verpassen, bei denen Sprecher ähnliche Stimmen haben, bei denen ein Sprecher deutlich leiser ist oder bei denen es starke Überlappung gibt. Für eine brauchbare Zeitleiste bei den meisten Podcast- und Interviewmaterialien funktioniert das.

Wann auf echte Diarisierung umzusteigen ist

Den schwereren ML-Stack brauchst du, wenn:

  1. Mehr als 2–3 Sprecher vorhanden sind, besonders mit Überlappung.
  2. Cross-Channel-Mixing: eine einzelne Mono-Datei mit mehreren weit entfernten Mikrofonen.
  3. Sprecheridentifikation erforderlich ist (nicht nur „ein Wechsel hat stattgefunden”, sondern „Sprecher A ist zurück”).
  4. Verrauschtes Audio aus der Praxis: Straßenaufnahmen, Besprechungen mit schlechter Akustik.

Hierfür ist pyannote.audio derzeit die beste quelloffene Diarisierungs-Pipeline. NeMo ist eine eher unternehmenstaugliche Alternative. Beide laufen auf der GPU und benötigen ~1-5 GB an Modellgewichten und sind ohne erheblichen Aufwand nicht browsertauglich.

Was SignalLab macht

Der SignalLab Indexer (Vorschau auf Browserseite) verwendet das oben beschriebene signalbasierte Muster zur Segmentierung von Sprecherwechseln. Die vollständige serverseitige Version leitet an pyannote weiter, wenn die Diarisierungsgenauigkeit zählt. Die browserseitige Version ist gut genug für QA und Erkundung; die serverseitige Version ist gut genug für Produktionsarchive.

Der Entscheidungsbaum:

  • Machst du schnelle QA beim Ingest? Verwende signalbasierte Segmentierung.
  • Erzeugst du Metadaten pro Sprecher für ein Archiv? Verwende pyannote.
  • Machst du Echtzeit-Transkription mit Sprecherlabels? Verwende die eingebaute Diarisierung des ASR-Anbieters (Deepgram, AWS).

Verwandt