解决转写漏句(有人说话但没识别出来)问题:silero VAD 对呻吟/轻语/BGM 混叠声学切段能力天然不足,把真话当非语音剔除(实测 savr-1054 全片仅 召回 115 条)。新增 decode_full 参数(默认 false 保持 VAD 现状): - decode_full=true 时强制无 VAD 整段解码 + 跳过自动 VAD 分析,救回被 剔除的弱语音(savr-1054 全片 115 条 → 340 条) - 副作用是长时寒暄套话幻觉(おやすみなさい/ご視聴ありがとうございま した 等),whisper 转录后连带时间戳整条删除(clean_japanese_ha lllucinations),不留下 '-' 占位污染下游(占位会渲染进 ASS 成减号) - llm-translate 翻译后同样整条删除中文长时寒暄幻觉(clean_srt_text) - 短时(≤15s)相同词可能是剧情真实道晚安,保留(15s 阈值实测校准) - subtitle_cleanup 由 '-' 占位式改为整条删除式 + 剩余重编号,新增 JAPANESE_HALLUCINATION_TOKENS 词表 新增工作流 learn-translate(学习资料转译+翻译字幕)示范 decode_full 用法,并确立参数标注约定:params._note_<参数名> 存放设定理由与正反例、 _node_help 放节点参数手册(_ 前缀说明键,节点执行时忽略,零运行影响)。 调研记录见 docs/调研-whisper漏句与decode_full验证.md(A/B 实验、结论 修正与 5 个待决问题)。
8.3 KiB
调研记录:whisper "说话没识别" 漏句问题 与 decode_full 方案验证
本文档记录 2026-09 对"转写时有人说话但没识别出来(漏句/漏识别)"问题的完整调研过程、 实验数据与结论修正。调研中发现早期结论被后续更严谨的验证推翻,特此如实记录, 供后续对话继续推进时参考,避免重复踩坑。
状态:调研暂告段落,方案未定稿,代码改动未提交。详见文末"当前状态"。
1. 问题背景
用户反馈:whisper 转写时动态配置参数(自动 VAD 调参),生成的字幕中有时出现 "有人说话但没识别出来"的情况,怀疑与动态参数配置有关。
链路(demo/learn-translate):提音(ffmpeg-extract) → 转写(faster-whisper) → 翻译(llm) → ASS。
whisper 节点关键动态逻辑(改动前):
vad_filter=true(默认开启)WOV_AUTO_VAD=1(默认):每视频信号分析 → 动态生成vad_parameters(nodes/vad_profiler.py,按静音比例/BGM 覆盖/长停顿 四分支给 threshold/min_silence/speech_pad)chunk_seconds=60分块、condition_on_previous_text=false、beam_size=1
2. 实验一:savr-1054 全片 A/B(VAD vs 无VAD)
素材:/mnt/fnOS/123/savr-1054/4k2.me@savr01054_2_8k.mp4(1383s,呻吟/BGM 密集)。
| 配置 | 全片条数 | 覆盖时长 | 幻觉长段 |
|---|---|---|---|
| 生产 VAD(vad_filter=true+自动VAD,threshold0.5/ms1000/pad200) | 115 | 621s | 0 |
| 无 VAD(decode_full 前身) | 369 | 983s | 有(119-149s、600-630s 30s"ご視聴…") |
- 无 VAD 确实大幅增加召回(115→369),其中 65-135s 的"入ってるところ見える? /奥までジュボジュボ入ってるよ"等与线上 CN.srt 空洞吻合 → 当时判定为"救回真话"。
- 但无 VAD 副作用明显:119-149s/600-630s 出现 30s 长"ご視聴ありがとうございました"幻觉。
2.1 人声分离(demucs)实验
htdemucs --two-stems=vocals分离后:vocals 轨 VAD 切段与混音几乎一样(瓶颈是 silero 对呻吟/轻语本身概率低,不是底噪);- 分离 vocals + 无VAD 与混音无VAD 召回相当(16 vs 15 条/窗口)→ 人声分离不解决问题, 只是把音乐底噪去掉,呻吟/轻语仍是低概率语音。
2.2 min_silence / threshold 扫描
- 固定 threshold=0.5 只调 min_silence(300→2000ms):真话召回不变(450s 窗口恒 1 条、 546s 窗口恒 1 条)→ 只调 min_silence 无效(它只决定断句,不能把 silero 没标成 语音的弱语音变成语音段);
- 调 threshold(0.3~0.6):覆盖仅 44%→45%,真话也救不回(呻吟/BGM 混叠使 silero 切段能力 天然不足)。
2.3 每片独立 VAD / 精细能量分段 模拟
- "每 60s 块独立调参":24 块中 11 块会落到 bgm 分支(thr0.3),但段切更碎、覆盖不升, 且 NO_VAD 降级反而新增 60s/36s/20s 空洞 + 幻觉(sim_perchunk 318 条,1080-1140s 整段空);
- 精细能量分段(RMS>900 切语音候选段):连真实说话段都定位错(1065-1115s 只找到 3 小段、 解码出幻觉)→ 能量/VAD 前置切段对混叠声学都不可靠。
3. 关键结论修正(重要)
3.1 "能量低=幻觉" 是错的
savr-1174 上精确验证:938s 轻语真话 mean -40dB,VAD 与无VAD 都能稳定识别; 而 120s/140s/210s 真话区 mean 仅 -45~-48dB(整片录音电平低),whisper 仍稳定识别。
3.2 "稳定性(跨配置一致)= 真话" 是相对可靠的判据
- 真话(938s"吸い付かないでよ"、1065s"そういうプレイ好きな人?"):VAD/无VAD/beam1/beam5 多配置稳定复现同一句;
- 幻听(1260s"手ついてたら…"):VAD 配置下变"おやすみなさい"、无VAD 才出该句 → 内容 跨配置不稳定 = 无真实语音锚点。
3.3 置信度字段无法区分真幻
faster-whisper segment 的 avg_logprob / no_speech_prob:真话 60s(avg_logprob -0.42) 比
幻觉 1260s(-0.63) 还高;no_speech_prob 幻觉 330s(0.28) 比真话 1065s(0.30) 还低 → 不可用。
3.4 "decode_full 救回 VAD 漏掉的真话 2.7 倍" —— 被推翻
savr-1174 全片:decode_full(beam1) 463 条 vs 生产 VAD 170 条,早期结论是"救回弱语音"。 逐条 + 分层抽样 VAD 复查后:
- decode_full 新增内容中,大量(抽样 45 条中 20 条 VAD 静默)是 VAD 静默段的幻听, beam1 把噪声/重复碎片劣化转写成"词句"(如"何がやばいんだ"实为"何?何?何?"、2243s beam1/beam5 结果不同=不稳定);
- 真正被救回的低电平真话(120s/140s/210s)VAD 其实也能识别(只是旧自动 VAD 参数 或分块把它们漏了)→ 说明问题在旧自动 VAD 参数选取而非 VAD 机制本身。
3.5 无法用单一信号完美区分真幻
| 信号 | 效果 |
|---|---|
| 能量/RMS | 无效:savr-1174 录音电平低,真话-45dB vs 幻听-51dB 难分;高响度(如-22dB 效果音段)也可能是幻听 |
| avg_logprob/no_speech | 无效(见 3.3) |
| 寒暄词表 | 有效但覆盖面窄(savr-1174 decode_full 后寒暄类已 0 命中,即已被清干净) |
| VAD 复查(decode_full 后逐条用 VAD 复查,VAD 能识别才保留) | 相对最可靠,但会误删 VAD 漏掉的短真语气词(うん/はい/んー),且切窗不准会误删响亮真话 |
4. 代码改动现状(未提交)
以下改动已写入工作区(git status 可见),未经用户确认提交:
| 文件 | 改动 | 状态 |
|---|---|---|
nodes/subtitle_cleanup.py |
幻觉清洗改为整条删除式(remove_hallucination_entries:≥15s 命中寒暄词表 → 序号+时间轴+文本全删、剩余重编号);新增日语词表 JAPANESE_HALLUCINATION_TOKENS |
已改 |
nodes/whisper.py |
新增 decode_full 参数(默认 false):true 时无VAD 整段解码 + 跳过自动VAD + 日语幻觉整条删除 |
已改 |
nodes/llm.py |
clean_srt_text 由替换 - 占位改为整条删除;回滚了临时的 - 跳过逻辑 |
已改 |
workflows/learn-translate.json |
新工作流"学习资料转译+翻译字幕":decode_full=true;每参数 _note_<名> 标注理由+正反例;_node_help 参数手册 |
新增 |
tests/* |
test_hallucination_mask 重写为删除式;whisper decode_full 测试;learn-translate 加载/标注测试;test_seed 计数 3→4 | 已改 |
AGENTS.md |
decode_full 说明、工作流表、参数标注约定 | 已改 |
测试:相关 97 passed(全量 357 passed / 5 个既有环境失败与本次无关:ffmpeg 4.2 不支持
force_divisible_by 滤镜、home 目录解析)。
端到端已验证:savr-1174 前 200s decode_full → 幻觉整条删除(无 0-90s 占位重叠)、 真实内容 60.03s 起时间轴正确、翻译 36 条、ASS 72 Dialogue 0 噪点。
5. 待决问题(新对话继续)
- decode_full 是否值得作为默认增强:savr-1174 显示其对呻吟/BGM 密集视频弊大于利 (新增大量幻听),但对纯对话/低电平场景(120s 真话)有效。可能只适合特定声学;
- "VAD 复查过滤"方案是否落地:可保留 decode_full 救回的真话并剔幻听,但需解决 短真语气词误删与切窗不稳问题;实现成本中等;
- 旧自动 VAD 参数为何漏低电平真话(120s 这类 VAD 单窗能识别但整片 A 漏了)—— 可能是分块边界/自动参数分支误判,值得单独排查;
- 现有代码改动去留:subtitle_cleanup 整条删除式、whisper decode_full、learn-translate 工作流——保留、调整还是回滚待定;
- 如何真正"听"音频验证(本调研最大局限:未实际听音,靠多配置转写交叉推断)。
实验产物(临时文件,可复用)
/tmp/savr1054_2.wav savr-1054 全片 16k 音频
/tmp/savr1054_2_vocals16k.wav demucs 分离 vocals 轨
/tmp/run_A_vad.srt savr-1054 生产VAD 全片 (115条)
/tmp/run_B_novad.srt savr-1054 无VAD 全片 (369条)
/tmp/savr1174_1.wav savr-1174 全片 16k 音频
/tmp/savr1174_A_vad.srt savr-1174 生产VAD 全片 (170条)
/tmp/savr1174_B_decodefull.srt savr-1174 decode_full beam1 (463条)
/tmp/savr1174_D.srt savr-1174 decode_full beam5 (336条)