openvibers/openvibe.live Commits

Transcribe: drop whisper's subtitle-boilerplate hallucinations

OP OpenVibers committed 18 Aug 2026 · a98f08511c · 1 file, +8 −0

A real live segment came back as "For more information, visit www.fema.org."
Whisper's training data was full of subtitle boilerplate and it emits those
phrases verbatim over noise even when VAD says a voice is present, so the
existing exact-match blocklist cannot cover them.

Match on shape instead: a short line that is mostly a URL, a subtitle credit,
or a sign-off. Real stream speech essentially never looks like that, and the
length bound keeps genuine sentences that happen to contain a URL — verified
that "check out www.mysite.com for the build I was talking about..." survives
while the fema.org and Amara.org lines are dropped.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Xw6Sf5zzSALw8m93XNu5JE

Changes

ddiff --git a/server/ai/transcribe.js b/server/ai/transcribe.js
iindex 417a42f6..c914e848 100644
---- a/server/ai/transcribe.js
++++ b/server/ai/transcribe.js
@@@ -125,6 +125,14 @@ function _isNoise(t) {
if (/^♪/.test(s) || /♪$/.test(s)) return true;
const norm = s.toLowerCase().replace(/[.!?,…]+$/g, '').trim();
if (HALLUCINATIONS.has(norm)) return true;
++ // Whisper's training data was full of subtitle boilerplate, and it emits those exact
++ // phrases over noise even when VAD says a voice is present — a real live segment came
++ // back as "For more information, visit www.fema.org." These are recognisable by shape:
++ // a short line that is mostly a URL or a subtitle credit, which real stream speech
++ // essentially never is.
++ if (/\b(?:www\.|https?:\/\/)\S+/i.test(norm) && norm.split(/\s+/).length <= 12) return true;
++ if (/subtitle[sd]?\s+(?:by|from)|amara\.org|subscribe to|closed caption/i.test(norm)) return true;
++ if (/^(?:for more info(?:rmation)?|visit our website|see you (?:next time|in the next video))/i.test(norm)) return true;
if (!vadModel() && FILLER_WORDS.has(norm)) return true;
return false;
}