【免费下载链接】rescript
🎬 Open source, transcript-based video/audio editor that lives in the browser.
Rescript 是一款开源的、基于文本转写(transcript-based)的浏览器端视频/音频编辑器:把媒体文件丢进来,Whisper 在本地完成逐词转写,你像删文字一样删视频。但 Whisper 有个臭名昭著的毛病——在静音、音乐或片段边界处"一本正经地胡说八道"。Rescript 用VAD 语音活动检测(Voice Activity Detection)+N-gram 重复折叠两套机制,在转写前和转写后各守一道关。本文带你完整看懂这套防幻觉设计。
为什么 Whisper 会"幻觉"?
Whisper 这类大模型转写器内部以约 30 秒为窗口工作。当窗口里全是静音、背景音乐或噪声时,模型没有真实语音可依赖,就会从训练数据里"编"出一段内容,典型症状有三类:
- 整句胡说:静音处凭空冒出 "I'm sorry"、"thank you for watching";
- 短语死循环:"little bit of a little bit of a little bit of a…" 重复十几遍;
- 结尾打转:音频末尾一串 "um uh you you you…"。
Rescript 的思路很直接:转写前,别把静音喂给 Whisper;转写后,把漏网的幻觉模式清理掉。
第一道防线:VAD 语音活动检测
核心实现在 lib/vad.ts。它把音频切成 16 kHz 采样率、每帧 512 个采样点(约 32 ms)的小段,逐帧判断"有没有人在说话"。
VAD 双引擎:Silero 优先,能量检测兜底
- Silero VAD:一个小巧的 ONNX 语音检测模型,在 Web Worker 中逐帧推理输出语音概率(见 workers/transcription.worker.ts);
- 能量检测兜底:若 Silero 不可用,退化为 energySpeechFrames——计算每帧 RMS 能量,高于「峰值 × 0.15」或绝对下限 0.005 的帧视为语音。精度略低但保证流程不中断。
检测失败时还有第三级兜底:整段音频直接送转写(segmentsOrFull),宁可慢一点也不报错。
语音分段四步走:合并、补边、限长、切在静默处
speechSegmentsFromFrames 把逐帧标志转成"该转写的片段",共 5 个关键动作:
| 步骤 | 参数 | 作用 |
|---|---|---|
| 收集原始语音段 | — | 找出所有连续为 true 的帧区间 |
| 两侧补边 | padS = 0.25s | 防止吃掉句首句尾的字 |
| 合并短停顿 | maxGapS = 1.5s | 呼吸、短暂停顿留在段内;超过 1.5s 的静默才切段 |
| 超长段切分 | MAX_SEGMENT_S = 120s | 无休止的长讲座会被在最安静的内部位置切开,切口永远落在词与词之间,而不是词中间 |
| 丢弃碎片段 | minSpeechS = 0.15s | 太短的"语音"多半是爆音或键盘声 |
其中 120 秒上限尤其巧妙:一小时连续讲话如果整段送转写,要在内存里复制整个录音(约 230 MB)并让模型状态贯穿全文件;而 2 分钟远长于模型内部 29s 的切块窗口,切分不会损失任何解码上下文(设计动机见 lib/vad.ts 的注释)。
💡 效果:Whisper 只解码真正的语音,静音区从不进入模型,从源头掐断了"对着静音编故事"的幻觉。
第二道防线:转写后清理管道
即便有 VAD,音乐段落的边缘、切块边界仍可能漏出幻觉。转写完成后,cleanTranscript 按顺序执行三步清洗(调用点在 workers/transcription.worker.ts):
1️⃣ 重复 N-gram 折叠:collapseRepeatingNgrams
这是整个机制中最精彩的算法,实现见 lib/hallucinations.ts:
- 从左到右贪婪扫描,对每个位置尝试长度
n(2~8 个词)的"单元",看它是否连续重复了足够多次; - 长短分治:长短语(≥4 词)连续重复 2 次就折叠,短语死循环往往很规整;短词(2~3 词)要重复 3 次才折叠——否则会误伤真实的 "yes yes yes";
- 最大收益优先:同一位置有多个候选时,选删掉词数最多的那个(比如 "little bit of a" ×4 优先于短语对 ×2)。
折叠后所有词的id会重新编号为连续的 0..n-1,保证后续时间线、React 渲染的索引不出错。
2️⃣ 已知幻觉短语剥离:stripHallucinationPhrases
维护一份 Whisper 高频幻觉短语黑名单(lib/hallucinations.ts):"i'm sorry"、"please subscribe"、"see you next time"、"subtitles by the amara.org community" 等。匹配成功才整句删除,周围的真实语音原样保留——所以真正的 "I'm sorry, I forgot" 不会整段消失,只删恰好连续命中的短语。
3️⃣ 尾部退化循环修剪:trimTrailingDegenerateTail
针对"结尾打转":用一个 6 词滑动窗口,若窗口内不同词不超过 2 个(如 um/uh 交替),视为退化区。关键细节是锚定最后一个词——只有转写确实以循环收尾才修剪,且至少删掉 6 个词才动手(lib/hallucinations.ts)。
这是一个用真实 bug 换来的设计:早期版本从"第一个退化窗口"向后整段截断,结果逐字转写中第 3 分钟处的 "um uh um uh" 把后面 40 分钟全部吃掉。回归测试 tests/hallucination-test.ts 专门守着这个坑。
完整流水线串起来看
整个防幻觉链路在 workers/transcription.worker.ts 中组织:
音频加载 → VAD 逐帧检测(Silero/能量兜底) → 语音分段(合并短停顿 + 120s 静默点切分) → Whisper 只解码语音段(29s 块、5s 步长) → 时间戳映射回原始时间轴 → cleanTranscript 三步清洗(N-gram 折叠 → 短语剥离 → 尾部修剪) → 重新精调词级时间戳 → 说话人分离转写前的 VAD 负责"少喂",转写后的清洗负责"兜底",两道防线叠加,让你导出的字幕干净得像人工校对过。相关单元测试可参考 tests/vad-test.ts 与 tests/vad-regression-test.ts。
小结
- VAD 语音活动检测是防幻觉的第一性原理:让 Whisper 永远看不见静音,
maxGapS/MAX_SEGMENT_S等参数在准确率与内存占用间取得平衡; - N-gram 折叠 + 短语黑名单 + 尾部修剪用极简的规则覆盖了大模型幻觉最顽固的三种形态;
- 所有清洗都保守行事(最小删除量、锚定边界、回归测试护航),宁可放过、不可误删真实语音。
这套"检测在前的分段解码 + 清洗在后的模式匹配"组合,是浏览器端离线转写场景下性价比极高的工程方案,也很值得其他基于 Whisper 的项目借鉴。
【免费下载链接】rescript
🎬 Open source, transcript-based video/audio editor that lives in the browser.
相关推荐
ricky0123/vad项目中的语音活动检测算法详解
ricky0123/vad项目中的语音活动检测算法详解 算法概述 ricky0123/vad项目实现了一个基于Silero模型的语音活动检测 VAD 算法,能够
xiaozhi-esp32语音检测:VAD语音活动检测算法深度解析
xiaozhi esp32语音检测:VAD语音活动检测算法深度解析 引言:智能语音交互的核心技术 在嵌入式AI语音交互系统中,语音活动检测(Voice Acti
人工智能AI 应用语音智能硬件物联网dora-rs语音活动检测:Silero VAD实时语音端点检测
dora rs语音活动检测:Silero VAD实时语音端点检测 概述 在实时语音处理应用中,准确检测语音活动(Voice Activity Detection
机器人ROS人工智能流程编排
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考