Et lille ASR evalueringsprojekt med Whisper
Jeg har lavet et lille projekt der kunne teste hvor godt openAIs Whisper model klarer dansk og engelsk lyd. Ikke et stort men bare en lille pipeline der kan tage nogle lydfiler, transskribere dem, sammenligne med en korrekt tekst og give et nogenlunde brugbart tal tilbage.
Projektet endte med at hedde asr-eval-pipeline og er bygget i Python med FastAPI, Whisper og jiwer.
Det korte svar er at det virker ganske fint som et lille MVP projekt. Men der er også nogle detaljer, især omkring dansk og meget korte lydklip, hvor man hurtigt finder ud af at talegenkendelse ikke bare er “smid en fil ind og få sandheden ud”.
Hvad projektet gør
Projektet kan grundlæggende tre ting.
Det kan transskribere en lydfil med Whisper. Det kan evaluere transskriptionen mod en reference tekst og beregne WER (word error rate). Og det kan køre enten via en lille FastAPI app eller som et command line script over en CSV manifest fil.
Manifest filen ser sådan her ud:
id,language,audio_path,reference
da_001,da,data/samples/da_001.m4a,det er en test
en_001,en,data/samples/en_001.wav,this is a test
Så lægger man sine lydfiler i data/samples, skriver hvad den korrekte tekst burde være, og kører evalueringen.
PYTHONPATH=src python scripts/run_eval.py \
--manifest data/manifests/sample_manifest.csv \
--model small \
--output data/results/results.csv
Resultatet bliver skrevet som en CSV fil med en linje pr lydfil og en lille JSON summary ved siden af.
WER og normalisering
WER står for word error rate og er en meget brugt måde at måle talegenkendelse på. Hvis reference teksten er:
det er en test
og modellen svarer:
Det er en test.
så er det i praksis korrekt, selv om store bogstaver og punktum er anderledes. Derfor normaliserer projektet teksten før WER bliver beregnet. Det betyder blandt andet at teksten bliver lavet til små bogstaver, tegnsætning bliver fjernet og flere mellemrum bliver lavet om til et enkelt mellemrum.
I mit lille testeksempel fik jeg:
reference: det er en test
prediction: Det er en test.
normalized_reference: det er en test
normalized_prediction: det er en test
wer: 0.0
Det er det resultat man gerne vil se. Modellen har ramt alle ordene korrekt, så WER er 0.0.
Man skal dog være lidt forsigtig med WER. Det lyder meget objektivt, men resultatet afhænger ret meget af hvordan man normaliserer teksten. Hvis man arbejder med tal, forkortelser, navne eller fagord kan normaliseringen hurtigt komme til at betyde en del.
FastAPI delen
Jeg lavede også en lille API, mest fordi det er rart at kunne teste med curl eller koble en frontend på senere.
Man starter API’et sådan her:
PYTHONPATH=src uvicorn api.main:app --reload --host 0.0.0.0 --port 8000
Og så kan man transskribere en dansk lydfil sådan her:
curl -X POST "http://localhost:8000/transcribe?model=small&language=da" \
-F "file=@data/samples/da_test.m4a"
Hvis man også vil evaluere mod en reference tekst:
curl -X POST "http://localhost:8000/evaluate?model=small&language=da" \
-F "file=@data/samples/da_test.m4a" \
-F "reference=det er en test"
Jeg endte med at tilføje language=da, fordi Whisper ellers nogle gange gættede forkert på korte danske klip. Det er ikke overraskende, men det er en god påmindelse om at auto-detect ikke altid er det man vil bruge i et evalueringssetup.
Dansk og korte lydklip
Min første testfil var bare mig der sagde “dette er en test” på dansk. Det er en lydfil på omkring fire sekunder optaget som en .m4a fra Apple Voice Memos.
Med Whisper base fik jeg først noget der lignede volapyk. Det er meget typisk for små modeller på korte klip. De kan godt hallucinere noget mærkeligt i stedet for bare at give et lidt forkert svar.
Efter at jeg satte sproget til dansk og ændrede nogle decoding defaults blev resultatet bedre. Med small modellen fik jeg:
Det er en test.
Det er ret fint. Efter normalisering matcher det reference teksten præcist.
Min foreløbige konklusion er at base modellen er hurtig, men ikke specielt brugbar på kort dansk lyd. small virker som et bedre udgangspunkt hvis man vil teste dansk uden at bruge alt for meget tid eller hukommelse.
Latency
Projektet måler også hvor lang tid selve transskriberingen tager.
For min lille danske testfil på omkring fire sekunder tog Whisper small cirka et sekund på min gamle M1 Mac mini. Det vil sige at den kørte cirka fire gange hurtigere end afspilning af lydfilen.
Det lyder fint, men man skal ikke lægge for meget i et enkelt kort klip. Første request kan også være langsommere, fordi modellen skal loades eller downloades. Og latency afhænger selvfølgelig af modelstørrelse, hardware, lydlængde og om der køres på CPU eller GPU.
Men det er stadig en nyttig metrik at have med. Hvis man senere vil sammenligne tiny, base, small og måske medium, er det ikke nok bare at kigge på WER. Man vil også gerne vide hvad svartiden er.