指南

为什么你的转录会把同一句话反复重复

问题不在你的录音,也不是下载出了错。这是 Whisper 在没人说话时会做的事——而且有几种具体办法可以制止它。

你转录了一段长录音,打开文稿,发现中间某处变成了这样:

[ Silence ]
[ Silence ]
[ Silence ]
[ Silence ]

或者更糟:它挑了文件前面某个真实的句子,然后重复四十遍,配着看似合理的时间戳,就好像真有人以每秒一次的频率说了一分钟的"感谢观看"。

这是关于自动转录最常见的一条抱怨,而几乎每个基于 OpenAI Whisper 构建的工具都有某种版本的这个问题。值得弄明白它的成因,因为解决办法不是"买个更大的模型"。

实际发生了什么 #

Whisper 是一个语言模型。它并不是"听见词然后写下来"——它是在给定音频和它此前已写内容的条件下,预测最有可能的下一段文字。

这个框架解释了这个 bug。当音频里有语音时,最有可能的下一段文字就是正在被说出的词。当音频里没有语音时——一段停顿、房间底噪、等待音乐、掌声、老师走向白板的过程——模型仍然必须产出点什么。并不存在一个表示"这里什么都没发生"的标记。

于是它退回到语言模型在没有信号时会做的事:重复自己。它刚写完一个句子,那个句子在统计上最有可能的延续就是一个相似的句子,而音频里又没有任何东西来推翻这个猜测,于是它就绕起圈来。Whisper 以 30 秒为窗口处理音频,所以一旦某个窗口陷入循环,你就会在整个窗口里得到同一行,然后下一个窗口重新开始,往往又来一遍。

这就是为什么这个问题会以非常特定的模式出现:

  • 长录音,因为它们包含更多静音。
  • 文件的中段和末尾,此时有意思的部分已经结束,但录音还在继续。
  • 音乐和掌声,它们是密集的音频,里面却没有词。
  • 说话人声音轻、房间噪声大的录音,模型无法把两者分开。

一场贴近麦克风进行的五分钟访谈几乎从不出现这种情况。一场两小时的会议,散场后录音又跑了二十分钟,则几乎必然出现。

为什么"[ Silence ]"和"[BLANK_AUDIO]"是同一件事的另一种症状 #

Whisper 的训练数据里包含带方括号标注的文稿——[ Silence ][BLANK_AUDIO](music)♪♪♪。所以当它遇到非语音内容时,可能的输出之一就是这些标记,一遍又一遍。

这是较为无害的版本:至少文稿如实说明了那里什么都没有。但它仍然会用几百行垃圾填满你的文档,也仍然意味着工具在花真实的时间去解码静音。

四种解决办法 #

大致按效果好坏排序。

1. 语音活动检测(真正的解决办法) #

语音活动检测——VAD——是一个小型的独立模型,它在转录之前运行,标出音频中哪些部分含有人声。之后交给转录器的就只有这些部分。

这从源头上解决了问题,因为只有当 Whisper 拿到不含语音的音频时才会出现循环。静音根本不到模型面前,也就没什么可幻觉的。它还让长文件更快,因为你不必再花时间去解码二十分钟的空房间。

被广泛使用的是 Silero VAD,而较新版本的 whisper.cpp 直接支持它。如果你的应用提供 VAD 或"跳过静音"选项,就打开它。如果没有,向开发者提出这个需求是合情合理的。

2. 自己裁掉静音 #

如果你的工具没有 VAD 选项,你可以手动做一个粗糙版本:转录之前把录音的头尾裁掉,那二十分钟收拾东西的杂音就不会被处理。

任何音频编辑软件都能做到。这很枯燥,而且对文件中间的静音毫无办法,但对于"末尾录多了"这种非常常见的情况,三十秒就能去掉其中最糟的部分。

3. 事后把标记过滤掉 #

如果你的文稿里全是 [ Silence ]♪♪♪,用查找替换很容易去掉它们,因为它们是形态可辨的整行内容。

有一点要小心:只删除整行都是标记的那些行。像"然后——(笑)——我们就发布了"这样的行是真实的语音,你会想保留它。这正是一个好应用应该替你执行的规则。

4. 把文件切开 #

因为循环被限制在 Whisper 的窗口之内,把长录音切成较短的片段可以限制损失范围——一个坏窗口毁掉的是一分钟,而不是融成一整片重复的文字墙。有些应用会在内部这么做。

这是变通办法,不是解决办法。它缩小了波及范围,但没有阻止模型在静音上产生幻觉。

什么不能解决它 #

**更大的模型。**从 Base 换到 Large 会花掉你大量时间和磁盘空间,却不会消除循环,因为成因不是能力不足——而是你要求它去转录一段不含语音的内容。大模型同样会循环。(更多内容见规模的取舍。)

**云服务。**好的云工具会在流水线里跑 VAD 和后处理,所以它们遇到这个问题的次数较少。底层机制是一样的,其中不少在安静文件上照样会产出五十遍"谢谢"。按分钟付费买不到一个不同的解码器。

**再跑一遍。**Whisper 的采样并非完全确定,所以第二次尝试可能在另一个地方循环。那不是解决办法,那是掷硬币。

我们为此做了什么 #

具体地说,因为在这里给一个含糊的回答毫无用处。

Offline Transcription 在转录前运行 Silero VAD,所以静音和非语音片段从不会到达解码器。在此之上,像 [ Silence ] 这样的整段标记和单纯的音乐符号会被从结果中过滤掉,而那些仅仅包含一处方括号插入语的行会被保留,因为它们是真实的语音。

对于长文件,它还会分窗口转录,并在音频最安静的位置切分每个窗口,这样边界落在句子之间,而不是从句子中间穿过。

实话实说的一点提醒:这让重复短语的问题变得非常少见,但不是不可能发生。任何基于 Whisper 的工具,包括我们的,都是一个在做预测的语言模型,而会预测的模型就可能出错。如果你转录的内容对准确度有要求,就对照音频阅读你打算依赖的那些部分——我们的访谈指南介绍了一种快速做到这一点的方法。

简短版本 #

这种循环是 Whisper 在为不含语音的音频预测文字。语音活动检测通过压根不让它看到那段音频来消除成因。如果你的工具没有 VAD,裁掉静音和过滤标记会有帮助。更大的模型则完全没用。

获取 Offline Transcription

音频和视频全程在你自己的 Mac 上转录。不上传任何内容,无需账户,也没有按分钟计费。

macOS 13.0 or higher · iOS 16.4 or higher