Why Whisper says "Thank you" to an empty room
By Andrey ChmerevI build Kekoso, which ships Whisper among other engines and filters this failure out, so the last section is interested. The measurements are on whisper.cpp directly, not on my app — the files, the models and the commands are all named so you can repeat them. Run on 6 September 2026.

Feed Whisper thirty seconds of pure digital silence — not a quiet room, but samples that are all zero — and it does not return an empty transcript. It thanks you. Whisper transcribes silence as speech, and this particular whisper hallucination is polite enough that nobody questions it.
[00:00:00.000 --> 00:00:29.980] Thank you.
That is ggml-large-v3-turbo, on a file generated by ffmpeg with
anullsrc, with default settings and no audio in it whatsoever. Whisper says
thank you to an empty room, in a full sentence, with a full stop. I ran it three
times to be sure. Same output every time.
What four models do with nothing
I built three files, each thirty seconds, 16 kHz mono:
- digital silence — every sample zero, measured peak −91 dB
- quiet room — pink noise at roughly the level of an empty room, peak −47 dB
- audible noise — pink noise you would notice, peak −32 dB
Then ran each through four Whisper models with whisper-cli, English forced, no
other flags.
| Model | Digital silence | Quiet room | Audible noise |
|---|---|---|---|
| large-v3-turbo | Thank you. |
Thank you. |
Thank you. |
| large-v3 | Thank you. |
Thank you. |
— |
| medium | you |
[PAUSE] |
— |
| small | you |
eight repetitions, below | [no audio] |
The small model on quiet noise is the one worth reading in full:
[00:00:00.000 --> 00:00:02.000] I think it's a good idea to make sure that we don't let the
[00:00:02.000 --> 00:00:04.000] virus get in the way of us.
[00:00:05.000 --> 00:00:07.000] I think it's a good idea.
[00:00:10.000 --> 00:00:12.000] I think it's a good idea.
[00:00:13.000 --> 00:00:15.000] I think it's a good idea.
[00:00:16.000 --> 00:00:18.000] I think it's a good idea.
[00:00:19.000 --> 00:00:21.000] I think it's a good idea.
[00:00:22.000 --> 00:00:24.000] I think it's a good idea.
There was no voice in that file. There was no virus in that file. There was pink noise at the level of a room with the windows shut.
When Whisper repeats the same sentence like that, it is not a stuck buffer. Two things are visible at once here. The opening sentence is a fingerprint of the training data — hours of pandemic-era video, surfacing when the model has nothing else to go on. And the loop is the other classic failure: once a segment emits text with nothing to condition it, that text conditions the next segment, and the model settles into a groove.
This is not a curiosity of my setup. Koenecke and colleagues measured it at scale in Careless Whisper: Speech-to-Text Hallucination Harms (FAccT 2024): roughly 1% of their transcriptions contained entire hallucinated phrases that were not in the audio in any form, and 38% of those hallucinations carried explicit harms — invented violence, fabricated associations.
One difference between their work and mine is worth naming rather than glossing. They detected hallucinations by running the same audio twice, because on real speech the invented text is non-deterministic and differs between runs. On pure digital silence I got the opposite: the same three words, three runs out of three. Empty input appears to collapse the model onto its single most likely continuation, while ambiguous input scatters it.
The bigger models are the more dangerous ones
The intuition is that a bigger model hallucinates less. What I measured is that it hallucinates more plausibly.
small and medium produced you, [PAUSE], [no audio] — debris that any
reader recognises as machine noise. Both large models produced a clean, correctly
punctuated, entirely ordinary English sentence. Drop Thank you. at the end of a
meeting transcript and nobody will ever question it. Drop [no audio] and
everyone will.
That is the actual risk in this failure mode. Not gibberish, which is obvious, but fluent text that reads exactly like something a participant said.
The settings that look like they should help, and do not
whisper.cpp exposes several knobs that sound designed for this. I tried them
against the same digital silence with large-v3-turbo:
--no-speech-tholdfrom 0.1 through 1.0 in six steps —Thank you.at every value, including the 0.6 default--suppress-nst, which suppresses non-speech tokens —Thank you.--temperature 0.0 --no-fallback, decoding without temperature fallback —Thank you.
None of them made a difference on this input.
One honest note about method. An earlier pass of that same test appeared to
show two of those flags producing empty output, and I nearly wrote it up that
way. Repeating each of them cleanly — writing to a file rather than piping into
head, three runs each — produced Thank you. every time. The first result was
an artefact of how I was capturing the output, not a property of the flag. It is
an easy way to publish a fix that does not exist.
What does work is not asking the model
The problem is structural. Whisper is trained to emit text for a thirty-second window; there is no token for “there was nothing here”. So the fix is not to argue with the model but to keep silence away from it, or to check its answer against the audio afterwards.
Two approaches, and both are in wide use:
Voice activity detection before the model. Run a VAD, cut the file to the regions that contain speech, transcribe only those. whisper.cpp supports this with a Silero model. It costs an extra dependency and can clip quiet speech at the boundaries.
A loudness check afterwards. Keep a map of how loud the original recording was, then discard any segment whose time range had no sound behind it. This is what my own app does, and the details are worth stating precisely because the threshold is where such a filter lives or dies. It stores peaks, not averages — a quiet phrase over noise gives a clear peak and an average close to a pause — in windows of 50 ms, which is shorter than a syllable, so a gap between words does not get smeared away. Anything whose peak stays below 0.002, about −54 dB, is treated as silence.
That number is deliberately low: an order of magnitude below breathing into a microphone, two orders below speech. Room noise on a real microphone track sits around −45 dB and clears it easily, which means on a live pause the filter does not fire at all. It is built for digital zero — the padding at the end of a window, a muted system-audio track — and the single most reliable case it catches is a segment that starts after the recording ends, where there is not only no sound but no file.
Both approaches share the same honest limit, and my measurements show it: the quiet-room file had a peak of −47 dB, above that threshold. A loudness filter would have passed those segments through. It catches the empty, not the merely quiet.
Where this actually bites
Not in the middle of a conversation, where there is speech to transcribe. At the edges:
- the padding at the end of a file, where the model gets a partial window
- a participant who muted themselves for two minutes
- a recording that starts before anyone speaks
- a system-audio track when the permission was never granted, which is digital zero for the entire call
Most whisper transcription errors are ordinary — a misheard name, a dropped article — and a reader spots them. This one is different because there is nothing to spot. In a personal note, an invented “Thank you.” is a curiosity. In a record that someone else will read — a meeting minute, a research interview, a clinical note — it is a sentence attributed to a real person who never said it. That is the reason to care about a bug whose output is polite.
If you want the accuracy picture on real audio rather than silence, I measured what compression costs a transcript, and the different failure of names and technical terms is in a folder of recordings fixed by the agent that transcribed it. How the three engine families differ otherwise is in Whisper vs Parakeet vs SenseVoice.
Questions people ask
Why does Whisper transcribe silence as words?
It has no way to output nothing. The model was trained to produce text for a thirty-second window, so when a window contains no speech it still emits the most likely sequence — which, from its training data, is often a closing pleasantry. In my runs, both large models transcribed pure digital silence as "Thank you."
Why does Whisper repeat the same sentence over and over?
The same reason, compounded. Once a segment produces text with nothing to condition it, that text becomes context for the next segment, and the model can fall into a loop. On thirty seconds of quiet noise, Whisper small produced "I think it's a good idea" eight times in a row after an opening sentence about a virus.
Do bigger Whisper models hallucinate less?
They hallucinate differently, not less. Small and medium emitted "you" or a bracketed marker on digital silence; large-v3 and large-v3-turbo both produced a clean, plausible "Thank you." The larger models are the more dangerous case, because their invention looks like something a person said.
Does setting the no-speech threshold fix it?
Not in my testing. I tried no-speech thresholds from 0.1 to 1.0, suppression of non-speech tokens, and decoding without temperature fallback. Every one of them still produced "Thank you." on thirty seconds of digital zero, reproducibly.
What actually prevents hallucinated text on silence?
Not asking the model about silence in the first place. Either voice activity detection before the model, or a check afterwards against the loudness of the original audio — if there was no sound where a segment claims words, the segment is invention. The second approach is what my app does, with a threshold of about minus 54 decibels.
Does this matter for real recordings?
It matters most at the edges: the padding at the end of a file, a muted participant, a gap between speakers. A transcript that ends with a thank-you nobody said looks harmless. In a meeting record or a medical note it is a fabricated statement attributed to a real person.