彻底搞懂 FunASR 短音频 "choose a window size 400" 断言报错
【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR
批量跑录音转写时,FunASR 在一段 0.3 秒的音频上直接崩了,FBank 特征提取层抛出断言:choose a window size 400 that is [2, 0]。顺着 funasr/frontends/wav_frontend.py 一路查到根因,再给入口加了短音频长度校验,整条流水线恢复。这篇把排查路径完整复盘一遍,遇到同款报错可以直接对照。
怎么复现
触发条件很简单:音频比一帧还短。
- 输入:任意采样率 16kHz 的 wav,时长 0.3 秒以内(典型来源:VAD 切出来的尾段、误触录音、环境噪音片段)。
- 配置:默认 25ms 窗长、10ms 帧移,也就是前端 WavFrontend 里写死的
frame_length=25。 - 现象:批量推理跑到这条就中断,栈顶是特征提取的 Kaldi 兼容实现(funasr/utils/fbank.py 转发的 torchaudio kaldi.fbank):
File ".../funasr/frontends/wav_frontend.py", line 215, in forward_fbank mat = kaldi.fbank(waveform, ...) AssertionError: choose a window size 400 that is [2, 0]换个 1 秒以上的音频再跑,一切正常——问题就锁定在"长度"这个变量上。
问题出在哪
FBank 提特征的方式,是把一条 25ms 宽的"观察窗"从波形左边滑到右边,每滑 10ms 取一帧。16kHz 下 25ms 正好 400 个采样点,这就是报错里的 400。
类比一下:拿一把 25mm 的切刀去切一条 2mm 的面团。切刀落下去之前,程序会先算"合法落点范围"。当音频连一个窗都装不下时,算出来的帧索引下限是 2、上限是 0——下限比上限还大,范围本身就不成立,窗长校验的断言直接炸掉。
所以报错里[2, 0]不是随机数,它是由音频实际长度反推出来的有效帧区间。区间倒挂 = 音频短于最小可切长度。根因不在窗长配置,而在特征层默认"至少有一帧完整数据",而入口没有拦截短音频。
怎么修
改动集中在"进特征层之前"这一层,四条:
- 特征提取前校验采样点数,小于一个窗(16kHz × 25ms = 400 点)直接返回空特征,不再往下传;
- 对"不能丢"的短音频,补静音 padding 到最小帧长再提特征,识别结果按低置信处理;
- 采样率先统一重采样到 16kHz 再算长度,避免 sr 不一致导致"看起来短";
- VAD/切分组件设置最小片段阈值(建议 0.1s),碎段在源头丢弃。
核心判断就三行:
min_samples = 400 # 16kHz × 25ms if len(wav) < min_samples: return # 短音频直接跳过,不进入 FBank如何验证
自己跑一遍就能确认:
- 用触发崩溃的 0.3s 音频重跑批量任务——不再抛断言,该条走"跳过/空结果"分支,批次完整跑完;
- 边界值各测一条:0.05s、0.1s、0.2s、1s,前三个被静默拦截,1s 正常出文本;
- 抽几条 10s 以上的长音频对比修复前后转写结果,确认正常路径没有被改坏。
三条全过,这个问题就可以关单了。
避坑清单 ⚠️
| 场景 | 建议 |
|---|---|
| 音频短于 0.1s | 预处理阶段直接丢弃,别指望它进特征层 |
| 采样率不确定 | 先重采样到 16kHz 并校验 sr,再算长度 |
| VAD / 流式切分 | 配置最小片段长度,尾段碎音源头拦截 |
| 批量推理 | 整批先做长度预检,避免一条坏数据拖崩全批 |
| 读报错信息 | [x, y]是由音频长度推出的帧区间,倒挂即音频过短,别去改 window 配置 |
窗长是固定的,变的是音频。长度校验放在入口,这类断言就永远到不了特征层。
【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考