为什么从录音中去掉 'um' 比听起来困难
2026年5月2日 · 1547字 · 8分钟阅读语言学家为填充的英语单词(如 um、uh、er 及其延长版本(如 ummmm、uhhhhh))称之为流畅性障碍。我并不经常录制语音音频,但一些朋友确实这样做,他们告诉我手动编辑这些填充词是痛苦的。因此,我构建了 erm 来处理这个问题。uvx erm input.wav 这是常见情况下的整个接口。它在输入旁边写入一个清理后的 .wav 文件和一个 JSON 剪切列表。这篇文章介绍了它是如何工作的,因为明显的方法听起来并不好,而大部分代码都是在解决这个问题。幼稚的版本不起作用 🔗 你会期望工作是:带有单词级时间戳的转录,找到像 um 和 uh 的词元,用 ffmpeg 剪切这些范围。这样你大概完成了 60% 的工作,但结果听起来比原始的还要糟糕。原因有三个:Whisper 安静地省略了很多填充词,因此根本没有 um 词元可以匹配。随机时间点切割音频会在波形中产生一个小的台阶。你的耳朵听到它时就像是一个点击声。即使拼接本身是干净的,剪切前后的背景嘶嘶声也不太匹配,因此你会在每次编辑时听到微弱的切换。erm 主要是为了修复这三件事。关于 Whisper 的快速说明 🔗 Whisper 是 OpenAI 的开源语音转文本模型。你把音频给它,它会返回一个转录,使用正确的标志,它还会告诉你每个单词的开始和结束时间戳。它在本地运行,这使得像这样的工具在不将你的录音发送到任何地方的情况下成为可能。erm 使用 faster-whisper,这是一个实现速度比参考版快数倍且占用更少内存的实现。相同的模型权重,相同的输出,只是一个更好的运行时。默认情况是 medium.en 模型,它在速度和准确性之间取得了良好的平衡。如果你想要小型的 en(更快),可以通过 --model 进行覆盖,但我实际上会选择 large-v3。它在识别填充词方面明显更好,值得额外的计算。检测 🔗 首先,运行 Whisper。erm 要求使用单词级时间戳,并在一开始给它一个小指令,告诉它不要清理转录。呜呜,以前的 Whisper 随意会去掉填充词,因为大多数训练转录都是干净的散文。任何返回的已知填充词(um、uh、er 等)都会被标记为剪切。像 ummmm 这样的延长版本会在飞行中与 um 词干匹配。Whisper 仍然会漏掉一些,因此还有三次通行侧直接查看音频:间隙填充。如果两个转录单词之间有异常长的停顿(默认超过 350 毫秒),erm 会检查在那段“停顿”期间是否有人实际在发声。如果一段声音出现在 Whisper 标记为沉默的区域,那就是 Whisper 完全删除的填充词。它确实只是将它们删除。根本没有词元,只有一个原本是 um 的转录孔。填充词隐藏在单词内部。Whisper 有时将填充词粘附在相邻的单词上,因此“in,uhhhhh”返回为一个单独的 in 词元。erm 查看长的单词,拆分它们在音频中简短的下降处,找出哪个部分是实际的单词(根据该单词说出来所需的合理时间),并将其余部分视为填充。过长的单词。如果一个单词持续的时间远远超过其文本合理上应该花费的时间,那么尾部就可疑。erm 会扫描尾部以寻找有人声的部分,并且可选地使用音调测试进行双重验证:可疑部分听起来像是有人在持续发声(uhhhhh),还是像是有人在慢慢说话?一个持续的元音具有稳定的简单声学形状;真实的语音在声音之间移动时是不断变化的。音调测试使工具无法修剪说话缓慢的人。所有四个通行(Whisper 的一个和三个音频的)独立产生候选剪切,列表在下一步之前合并。细化剪切点 🔗 一个精确在 t = 1.234s 的剪切落在波形的即时位置几乎总是在零的位置。拼接两个任意位置会在波形中留下一个台阶,而那个台阶就是你听到的点击声。两个小修复,按顺序。首先,允许每个剪切端点稍微滑动(最多 60 毫秒),落在附近最安静的地方。如果在原始剪切点前或后有短暂的沉默声,那么就在那里滑动。滑动是有界的,因此它不能越过相邻单词,否则你会吃掉真实的语音。其次,从那个安静的地方,端点会弹到波形正好穿过零的最近时刻。两个互相合并的零点会产生一个连续的波形,没有台阶,也没有点击。经过这一切,非常短的残余片段会被清理:如果两个相邻的剪切之间留下一个少于大约 120 毫秒的音频片段,该片段被合并为一个更大的剪切。这样小的片段无论如何都无法在两侧的平滑中生存,并且只会听起来像一个嗞嗞声。拼接 🔗 ffm
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡