Repository navigation
Whisper invents text on silence in meetings and short dictations; the -50 dBFS gate does not catch it #193
Description
HEX version: 2.3.0 for the recording, installed from the signed DMG. The same code is in 2.3.1; source checked again at main f8774a5.
Platform: macOS
System details: macOS 26.4.1, Apple M1 Pro, built-in microphone. Whisper large-v3-turbo, language Italian, recognition hints set (five product names).
What happened?
When I do not speak, Whisper still returns text. The text is a closing phrase ("Grazie a tutti", "Grazie"), my recognition hints copied word for word, or short fragments.
Meetings (beta). I recorded a 63-minute call and mostly listened. In transcript.ndjson, 152 of 185 microphone entries are text I did not say:
| Invented text | Entries |
|---|---|
| "Grazie" / "Grazie a tutti" | 104 |
| the exact recognition-hints string | 29 |
| a URL made from one hint word | 2 |
| short fragments on quiet audio ("e", "o", "nada", "vo, vo, vo") | 17 |
The system track has 10 more (8 "Grazie", 2 hints string) during remote silence. Echo suppression does not remove them, because no remote speech matches them.
Dictation. This is the case from #108, still on 2.3.0. A short press without speech (1–3 s) pastes "Grazie" or "Grazie a tutti". Today's history.json has 8 of these, and process.log for the same hours has no discarded near-silent dictation line, so the gate did not discard them.
Expected: no text when nobody speaks.
Steps to reproduce
- Select Whisper large-v3-turbo and enter some recognition hints. Any language should do: I use Italian, and in English the closing phrase is usually "Thank you." (as in Inserting 'thank you' at the end of dictation sometimes #108).
- Meetings: record a call and stay silent for a few minutes. Dictation: press the shortcut for 1–3 s without speaking.
- Read the transcript or the pasted text. Expect the hints string, a closing phrase in the selected language, or short fragments.
Additional context
Where it comes from in the code
- Meeting chunks have no silence gate. Every rolling chunk (
transcribe_pending) and every chunk oftranscribe_filegoes to the model. - The dictation gate (
is_near_silent) checks only the loudest 30 ms window against -50 dBFS. A click, the key press or room noise passes it. - The recognition hints are Whisper's
initial_prompt. Each meeting chunk is a separate run, so each chunk starts with the prompt. On silence, Whisper often just repeats it. - Whisper's own no-speech check is already active with the
transcribe-cppdefaults (no_speech_thold0.6,logprob_thold-1.0). It does not stop these, because it skips a segment only when the logprob is also low.
Why a level threshold is not enough
I checked each microphone entry of the meeting against the audio under it. A gate "keeps" an entry when it would let that audio reach the model.
| Check on the entry's audio | Invented entries kept (of 152) | Real entries kept (of 33) |
|---|---|---|
| current gate: loudest 30 ms window ≥ -50 dBFS | 130 | 32 |
| stricter level rule: ≥ 250 ms of 30 ms windows above -40 dBFS | 1 | 31 |
Silero VAD v6.2 via transcribe-cpp 0.4.0 VadSession, threshold 0.4, min_speech_ms 160 |
1 | 32 |
- The current gate keeps almost all invented text.
- A stricter level rule removes it, but also drops real speech. It would also go against
silence_gate_discards_only_near_silent_captures, which keeps 100 ms of whispered speech at -43 dBFS. - I also tried the
PauseSegmenterspeech test (12 dB above the adaptive floor). It marks speech in most of my silent stretches, because of room and keyboard noise. - Silero separates the two groups. The one invented entry it keeps is a "Grazie a tutti." over 16 s of silence. I use threshold 0.4, not the default 0.5, because at 0.5 a whisper at -43 dBFS is not heard. The one real entry it misses is a 40 ms "Certo." at a chunk boundary. With Silero's default
min_speech_msof 250, 3 short real replies on the system track ("Ok", "Ciao") were lost; 160 keeps them. - It scans the 63 minutes in 1.6 s on the CPU.
Notes on this test:
- one recording, one machine, entries checked one by one, not the real chunk path (the PR has a run on the real chunk path);
- the GGUF model is
handy-computer/silero-vad-v6.2-gguf, F32.
Proposed fix
transcribe-cpp 0.4.0 has a Silero VAD (VadSession, with Silero v5.1.2 / v6.2.0 in GGUF or whisper.cpp .bin format). HEX pins =0.2.4. #129 also needs 0.4.0.
- Run the VAD before the model. Discard a dictation clip with no speech segment. In meetings, skip chunks with no speech, or send only the speech spans.
- Drop any Whisper segment whose text is the same as the initial prompt. This needs no threshold. Here it removes 29 microphone entries and 2 system entries.
I opened #194 with both parts, on transcribe-cpp 0.4.0. Open questions:
- Should the VAD model ship with the app, or download with the transcription model (as in the PR)?
- Should the VAD run for every model, or only for Whisper?
Related: #108 (same symptom in dictation, closed after the -50 dBFS gate), #129 (transcribe-cpp 0.4.0). The English live draft in meetings (#182, #185) is a separate problem and is not touched.
Activity
thdxr commentedon Oct 28, 2026
Thanks for reporting this! We're working on a brand-new version of Hex (rebuilt from the ground up), and it'll be out soon. This issue is about the current release, so we're closing it to keep the tracker focused on the new version. You can try the new dev build now — download links are in the README: https://github.com/anomalyco/hex#install-hex. If this still happens on the dev build, please open a new issue (or reply here) and we'll take a look.
— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊
0xCaso commentedon Oct 28, 2026
This still happens on the dev build, so I'm replying here as suggested.
Build: Hex 0.0.0-dev-155, the signed DMG from the dev channel, on macOS 27.0.1, M1 Pro, built-in microphone. Whisper large-v3-turbo, Italian, recognition hints set.
Dictation. I pressed the shortcut 6 times for 1–4 s without speaking:
discarded near-silent dictation, loudest window at -50.02 dBFS);On
dev, dictation has the same gate as the release (is_near_silentinsrc/dictation.rs). Meeting chunks now skip audio below -60 dBFS (SILENT_DBinsrc/meeting_transcript.rs). That is a level check too, and the table above shows that room noise passes a level check. I did not record a meeting on the dev build.#194 targets
devand still merges into it cleanly. Could you reopen this issue?thdxr commentedon Oct 28, 2026
Thanks for the careful retest on 0.0.0-dev-155 — the per-press breakdown and the level-vs-VAD comparison make this very clear. Reopening; we're reviewing #194 now.
— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊
thdxr commentedon Oct 28, 2026
#194 is merged into
dev(e68d4e6). Before transcribing, Hex now runs the Silero speech detector on dictation captures and meeting chunks and drops the ones with no speech in them. It also drops Whisper output that only repeats the recognition hints. The detector (1.2 MB) downloads in the background the first time you dictate or when a model downloads, so the very first press after updating may still go to the model.@0xCaso, could you try your silent-press test again on the next dev build, the first one after 0.0.0-dev-155 that includes e68d4e6, and let us know how it goes? Discarded captures log
discarded dictation without detected speechinprocess.log.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊
0xCaso commentedon Oct 28, 2026
Tried it on 0.0.0-dev-167, which includes e68d4e6. The setup is the same as before: macOS 27.0.1, M1 Pro, built-in microphone, Whisper large-v3-turbo, Italian, recognition hints set.
discarded dictation without detected speech, and nothing was pasted.I did not test meetings on this build. Thanks for merging!