Whisper lokal für Transkription

Whisper lokal für Transkription

- Matt

Ich habe eine Handvoll Sprachnotizen und ein paar mitgeschnittene Besprechungen, aus denen ich Text bräuchte. Die bequemen Wege führen alle über einen Dienst, bei dem am Ende meine Aufnahme auf einem fremden Server liegt. Das wollte ich für ein paar interne Mitschnitte nicht, also habe ich mir angesehen, was lokal geht. Whisper von OpenAI läuft auf der eigenen Maschine, und für .NET gibt es mit Whisper.net eine Anbindung an das C++-Original whisper.cpp.

Einbinden

Zwei Pakete, eines für die Bindung, eines für die native Laufzeit:

dotnet add package Whisper.net
dotnet add package Whisper.net.Runtime

Das eigentliche Modell ist eine separate Datei im ggml-Format. Die kleineren Varianten kann man beim ersten Lauf herunterladen lassen:

using Whisper.net;
using Whisper.net.Ggml;

var modelName = "ggml-base.bin";
if (!File.Exists(modelName))
{
    using var modelStream = await WhisperGgmlDownloader.Default
        .GetGgmlModelAsync(GgmlType.Base);
    using var fileWriter = File.OpenWrite(modelName);
    await modelStream.CopyToAsync(fileWriter);
}

Die Transkription selbst folgt dem Factory-und-Builder-Muster. ProcessAsync liefert die Abschnitte als asynchronen Strom, jeder mit Start, Ende und Text:

using var factory = WhisperFactory.FromPath(modelName);
using var processor = factory.CreateBuilder()
    .WithLanguage("auto")
    .Build();

using var audio = File.OpenRead("aufnahme.wav");
await foreach (var segment in processor.ProcessAsync(audio))
{
    Console.WriteLine($"{segment.Start}->{segment.End}: {segment.Text}");
}

Der Haken mit dem Eingabeformat

Hier bin ich hängengeblieben, und in den Beispielen steht es nur nebenbei: whisper.cpp verarbeitet ausschließlich WAV mit 16 kHz, mono, 16 Bit. Meine Aufnahmen waren MP3 und eine WAV-Datei mit 44,1 kHz in Stereo. Beides führt nicht zu einer Fehlermeldung, sondern zu leerem oder wirrem Text, was die Suche nach der Ursache erst richtig zäh macht. Der Zwischenschritt gehört zwingend davor, bei mir mit ffmpeg:

ffmpeg -i aufnahme.mp3 -ar 16000 -ac 1 -c:a pcm_s16le aufnahme.wav

Wann es sich nicht lohnt

Das Base-Modell läuft auf der CPU und ist bei deutschem Diktat brauchbar, aber nicht makellos: Fachbegriffe und Eigennamen sitzen oft daneben, und ohne Grafikkarte braucht ein 40-Minuten-Mitschnitt bei mir etwa acht Minuten. Wer bessere Erkennung will, nimmt ein größeres Modell und zahlt mit Speicher und Zeit, oder schiebt die Rechnung mit Whisper.net.Runtime.Cuda.Windows auf die GPU. Wie sehr das hilft, hängt an der Hardware, ähnlich wie schon bei lokalen Sprachmodellen.

Für einzelne Aufnahmen, die im Haus bleiben sollen, ist der Weg trotzdem der richtige. Für einen Stapel von hundert Interviews mit Anspruch auf saubere Namen wäre ich ehrlicher mit einem Dienst bedient, der eine geprüfte Ausgabe liefert.