Divide by zero crash on Windows for specific audio files when word level timestamps are enabled with faster-whisper-large-v2 model

在 Windows 上使用 faster-whisper 处理部分音频文件时,开启词级时间戳(word_timestamps)会触发原生代码整数除零崩溃,进程被直接终止且无法在 Python 层捕获;优先排查受影响的音频片段、启用的 word_timestamps 和 vad_filter 组合,并

快速结论:在 Windows 上使用 faster-whisper 处理部分音频文件时,开启词级时间戳(word_timestamps)会触发原生代码整数除零崩溃,进程被直接终止且无法在 Python 层捕获;优先排查受影响的音频片段、启用的 word_timestamps 和 vad_filter 组合,并升级 CTranslate2 至包含上游修复的版本。

适用环境:Windows Server 2019 Standard v1809(另有 Windows 11 CPU 转写复现)、NVIDIA L4 24GB、CUDA 12.3、Python 3.10、faster-whisper 搭配 Systran/faster-whisper-large-v2 模型;依赖 cublas64_12.dll 6.14.11.1234、cudnn64_9.dll 9.10.2.21 等 CUDA/cuDNN 库。

最快修复方案:暂无确认的一步修复方案。Issue 中给出的根因修复位于上游 CTranslate2 PR(OpenNMT/CTranslate2#2065),并需要 faster-whisper 侧补充一个空对齐防护;在依赖版本更新之前,可优先尝试关闭 word_timestamps 或 vad_filter 来规避崩溃。

注意事项:该崩溃属于原生层未定义行为(UB),是否触发与编译器/代码生成有关,因此看起来像“特定文件在特定机器上”才出现。上游修复后 align() 对退化窗口返回空对齐,但 faster-whisper 的 find_alignment 若未加空对齐防护,可能改为抛出 IndexError。

问题场景

用户使用 faster-whisper 对一批 PCM S16 LE 的 .wav 音频进行转写,模型为 Systran/faster-whisper-large-v2,在 GPU(NVIDIA L4)上运行,且开启了 word_timestamps(词级时间戳)。绝大多数音频正常,但个别文件会直接杀进程,Python 无法捕获异常。该问题同样在 Windows 11 的 CPU 转写上复现。用户还提供了一个复现仓库,但因音频属于客户数据无法直接公开。

报错原文

C:\faster-whisper-divide-by-zero-issue\venv\Scripts\python.exe C:\faster-whisper-divide-by-zero-issue\main.py "C:\<PATH_TO_MODEL_FOLDER>" C:\<AUDIO_FILE>.wav 
INFO:faster_whisper:Processing audio with duration 04:04.692
INFO:faster_whisper:Detected language 'en' with probability 1.00
DEBUG:faster_whisper:Processing segment at 00:00.000
DEBUG:faster_whisper:Processing segment at 00:27.760
...
DEBUG:faster_whisper:Processing segment at 04:04.680
DEBUG:faster_whisper:Compression ratio threshold is not met with temperature 0.0 (13.250000 > 2.400000)
...

原生崩溃码:0xC0000094(STATUS_INTEGER_DIVIDE_BY_ZERO)。

原因分析

已定位的根因:部分音频上 Whisper 会在片段末尾之外幻觉出一个尾部片段(例如 60 秒音频上出现 60.0→90.0s 的 segment),VAD/分段路径因此产生约 10ms 的最终窗口,并以 num_frames=1 调用 model.align()。CTranslate2 的 Whisper::align() 会按 encoder stride 将 num_frames 折半(1 → 0),随后 MedianFilter 在自身短轴保护之前先计算 input.size() / depth,此时 depth == 0,触发原生整数除零,在 Windows/CUDA 上直接杀死进程。该行为属于 UB,是否崩溃取决于编译器/代码生成,因此表现为“特定文件在特定机器上”才出现。

环境排查

  • 确认操作系统是否为 Windows(Server 2019 或 Windows 11)。
  • 确认是否使用 CUDA 12.3 及对应的 cuBLAS/cuDNN 库版本。
  • 确认 Python 是否为 3.10。
  • 确认 faster-whisper 与 CTranslate2 的具体版本,是否包含 CTranslate2 PR #2065 的修复。
  • 确认转写时是否启用 word_timestamps,以及是否启用 vad_filter。
  • 确认音频格式是否为 PCM S16 LE 的 .wav。
  • 确认模型是否为 Systran/faster-whisper-large-v2(用户案例)或其他 large 系模型。

解决步骤

  1. 定位触发文件:先用能稳定复现的音频确认崩溃只在少数文件上出现,并确认这些文件在 VAD 后是否产生极短的尾部窗口。
  2. 临时规避:在不影响业务的前提下,先关闭 word_timestamps 或关闭 vad_filter,观察崩溃是否消失,用于确认触发路径。
  3. 升级依赖:等待并安装包含 OpenNMT/CTranslate2#2065 修复的 CTranslate2 版本,使 align() 对退化窗口返回空对齐而不是崩溃。
  4. 补充 faster-whisper 防护:确认 faster-whisper 的 find_alignment 对空对齐做保护(空对齐 → 空词列表),避免在 time_indices[jumps] 处抛出 IndexError。Issue 中提到作者会就此提交配套 PR。
  5. 若暂时无法升级,继续收集并保留可复现的音频片段,以便在依赖更新后验证。

验证方法

升级并应用防护后,用原先会崩溃的音频重新运行开启 word_timestamps + vad_filter 的转写流程,确认进程不再以 0xC0000094 退出;同时检查幻觉出的尾部片段是否只返回空词级时间戳,而不是报 IndexError。也可用 Issue 中提供的无音频复现代码,确认 model.align(encoded, [50258, 50259, 50359], [[1396, 264, 1002]], [1]) 不再触发除零崩溃。

参考来源

SYSTRAN/faster-whisper #1342

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 27503

发表回复

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