Long-form transcription silently stops ~8 s before the end of a 603 s file — final sentence never decoded, with and without `vad_filter`

这类问题通常出现在用 faster-whisper 做长音频(约 10 分钟)CPU 转录时:程序不报错,但长音频末尾几秒没有转写出来,表现为 Long-form transcription silently stops ~8 s before the end of a 603 s file — f

快速结论:这类问题通常出现在用 faster-whisper 做长音频(约 10 分钟)CPU 转录时:程序不报错,但长音频末尾几秒没有转写出来,表现为 Long-form transcription silently stops ~8 s before the end of a 603 s file — final sentence never decoded, with and without `vad_filter`。优先排查音频解码链路(喂给模型的 16 kHz 数组是怎么生成的),而不是 VAD 参数。

适用环境:报告者与维护者测试环境为 faster-whisper 1.2.1、ctranslate2 4.8.3、PyAV 19.0.1、Python 3.12/3.12.15(Linux,2 vCPU),模型为 whisper-small(本地目录副本),`device=”cpu”`,`compute_type=”int8″`(维护者另用 `int8_float32` 复测),系统 ffmpeg 8.1.2;原始素材为 603.5 s 单声道音频。

最快修复方案:暂无确认的一步修复方案。Issue 中可优先尝试的是改用 faster-whisper 自带的 `decode_audio()` 生成 16 kHz 输入数组,并配合 `compute_type=”int8_float32″` 复测;该组合在讨论中被提到但最终结论未在摘录中明确。

注意事项:同一音频在不同解码实现下结果不同(报告者用 PyAV 直接解码 MP3 到 16 kHz 时能完整转写,用自带重采样链则停在约 595 s),因此修复效果与解码链路强相关,不能简单归因于 VAD 或模型本身。另外,报告者最初说的“ffmpeg 解码 vs PyAV 解码”对照已被本人更正:两次运行实际都由 PyAV 生成 16 kHz 数组,变量是重采样方式。

问题场景

用户用 faster-whisper 在 CPU 上转录一段约 603.5 s 的连续语音(单声道),调用方式为:

segments, _ = model.transcribe(audio, language="en", vad_filter=True)

并以 `vad_filter=False` 作对照。两种模式下都得到相同的分段边界,最后一段结束在约 595.2 s,文件中最后约 8.3 s 的完整结尾句没有出现在任何转写结果里,也没有任何报错或警告。Silero VAD 对该文件返回单个语音块 `[0.0, 603.46]`(文件内无处静音超过 2 s)。把最后 90 s 单独转录时,两种 VAD 设置都能完整转出结尾句。

报错原文

Long-form transcription silently stops ~8 s before the end of a 603 s file — final sentence never decoded, with and without `vad_filter`

原因分析

可能原因不在 `vad_filter`:开与关两种模式丢失的是同一段音频,所以可与“整段长音频解码”这一环节相关联。更可能的原因在送入模型之前的音频解码/重采样链路。维护者提示“MP3 解码在不同 FFmpeg 版本或不同 CPU 之间并非逐字节一致”,并建议提供 WAV、检查采样率(应为 16 kHz 而不是 24 kHz)、改用 `int8_float32`。

复测中,ffmpeg 生成的 WAV 仍能复现提前停止,说明问题不由 MP3 解码差异单独造成;而报告者用 PyAV 直接把 MP3 解码为 16 kHz 数组时能转到结尾(末段时间戳甚至超过文件时长),用自己“PyAV 解码 + AudioResampler 到 16 kHz”的链路时又停在 595.12 s。也就是说,差异更可能出在重采样/生成 16 kHz 输入数组的方式上,而不是 VAD 或模型本身。最终根因在 Issue 摘录中未给出明确结论。

环境排查

  • faster-whisper 版本:报告为 1.2.1
  • ctranslate2 版本:报告为 4.8.3
  • PyAV 版本:报告为 19.0.1
  • Python 版本:3.12 / 3.12.15,Linux,2 vCPU
  • ffmpeg 版本:系统构建 8.1.2(仅用于生成 WAV)
  • 模型:whisper-small,从本地目录副本加载
  • 推理配置:`device=”cpu”`,`compute_type=”int8″`(可试 `int8_float32`),`language=”en”`
  • 输入音频:确认送入模型的数组是 16 kHz 单声道;WAV 为 24 kHz 时应先重采样
  • 解码方式:确认 16 kHz 数组是通过 faster-whisper 自带 `decode_audio()`,还是自定义 PyAV + AudioResampler 链

解决步骤

  1. 确认实际喂给 `transcribe()` 的音频数组长度是否等于文件时长(报告中解码后数组为完整 603.46 s,说明数据并未在输入阶段被截断)。
  2. 检查音频采样率。维护者指出样例 WAV 是 24 kHz 单声道 PCM s16le,应为 16 kHz,可能对结果有影响。
  3. 改用 faster-whisper 自带的 `decode_audio()` 生成 16 kHz 输入数组,替换自定义 PyAV + `AudioResampler(format=’flt’, rate=16000)` 链路,做对比复测。这是讨论中可优先尝试的方向。
  4. 把 `compute_type` 从 `int8` 改为 `int8_float32` 复测。维护者指出 `int8` 是 auto 选出的类型,可作为对照变量。
  5. 分别在 `vad_filter=True` 与 `vad_filter=False` 下各跑一次,记录分段总数和最后一段的结束时间戳,确认差异来自解码链路而非 VAD。
  6. 用同一音频的最后 90 s 单独转录作对照。若单独片段能完整转出结尾句,可进一步说明问题出在长音频整段解码流程。

验证方法

查看返回的 `segments` 列表:最后一段的结束时间应覆盖到文件末尾附近(约 603 s),结尾句“……what health care AI is really being rewarded for.”应出现在转写结果中。若最后一段仍停在约 595 s,则问题未解决,应继续对比不同解码方式生成的输入数组。讨论中已出现最后一段结束于 10:03.280(约 603.28 s)的完整转写结果,可作为对照参考。

参考来源

SYSTRAN/faster-whisper #1683

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 31511

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注