feat: 转写支持静音段幻觉抑制参数(HST)

无 VAD 的 decode_full 会在无语音段"编"出字幕(`こんにちは`/`おはようございます`/
`東京都交通局8800形電車`)。实测这类幻觉与"呻吟间隙里的真实短台词"在
`no_speech_prob`、`avg_logprob`、silero VAD 与音频能量四个维度上都不可分,
只能用 faster-whisper 自带的 `hallucination_silence_threshold`(HST)抑制:
怀疑幻觉时跳过超过阈值的静音部分(需 `word_timestamps=True`)。

- `nodes/whisper.py` 透传 `word_timestamps` / `hallucination_silence_threshold` /
  `no_speech_threshold` / `log_prob_threshold` / `compression_ratio_threshold`,
  未配置的键不传,保持 faster-whisper 默认值与改造前行为。
- `learn-translate` 默认 HST=2.0 + word_timestamps:同一片头 120 秒无对话段由 15 条
  字幕降到 4 条且无套话幻觉残留,呻吟段基本保留;代价转写约慢 1.8×。
- 实测数据与取舍记录见 docs/workflows.md#decode_full-与幻觉呻吟清洗。
This commit is contained in:
2026-09-18 23:41:32 +08:00
parent 4d2823c005
commit 2c8bbb6469
4 changed files with 86 additions and 0 deletions
+20
View File
@@ -170,6 +170,24 @@ def _wav_duration_seconds(path: Path, fallback: float) -> float:
return fallback
# 静音段幻觉抑制参数:无 VAD 的整段解码会在无语音处"编"出字幕,这些参数直接
# 交给 faster-whisper(不传时保持其内置默认值,行为与改造前一致)。其中
# `hallucination_silence_threshold` 需要 `word_timestamps=True` 才生效:它按词级
# 时间戳跳过幻觉段里的静音部分,是"无语音段别写字幕"的主要开关。
_GUARD_PARAM_KEYS = (
"word_timestamps",
"hallucination_silence_threshold",
"no_speech_threshold",
"log_prob_threshold",
"compression_ratio_threshold",
)
def _guard_transcribe_params(params: dict) -> dict:
"""挑出工作流显式传入的幻觉抑制参数,未传的键交给 faster-whisper 默认值。"""
return {key: params[key] for key in _GUARD_PARAM_KEYS if params.get(key) is not None}
def _append_srt_lines(lines: list[str], segments, offset: float, start_index: int) -> int:
"""把一段转写结果按 SRT 格式追加到 lines,时间加上 offset 偏移。
@@ -287,6 +305,8 @@ def invoke(request: InvokeRequest) -> InvokeResponse:
condition_on_previous_text=bool(
request.params.get("condition_on_previous_text", False)
),
# 静音段幻觉抑制(未配置时不传,保持默认行为)。
**_guard_transcribe_params(request.params),
)
# 进度日志:块序号/总数、单块耗时、实时倍率(块音频时长/墙钟耗时)
# 与转写累计耗时,直观反映数据处理速度。