3.9 KiB
3.9 KiB
文本拼接算法详解
概述
merge_by_text 是 CapsWriter-Offline 中用于解决语音切片重叠去重的核心算法,采用模糊文本匹配策略,具有高鲁棒性和抗噪音能力。
问题背景
在流式语音识别中,音频被切片处理(如 25 秒一段,2 秒重叠),导致同一内容在相邻片段中重复出现:
片段 1: "...今天天气真"
片段 2: "天气真好啊..."
↑ ↑
重叠部分(需要去重)
核心思想
算法在前一段文本的末尾和新文本的开头之间寻找最长公共部分,以此为界进行智能拼接。不同于简单的尾部匹配,该算法采用窗口搜索策略,能够在末尾区域内灵活定位最佳拼接点。
三大设计原则
- 从长到短匹配: 优先匹配更长的文本片段,因为长匹配更可靠
- 允许噪音跳过: 新文本开头可能有截断噪音(如口语"嗯"、"啊"),允许跳过这些字符
- 精确→模糊→兜底: 三层容错机制,确保在各种情况下都能找到合理拼接点
算法流程
输入: prev_text = "今天天气真" + new_text = "嗯天气真好啊"
步骤 1: 预处理
└─> 去掉两端标点符号,保留有效文本
步骤 2: 确定搜索窗口
└─> 在 prev_text 末尾 20 字内查找(非全文本搜索)
步骤 3: 智能匹配(两阶段)
├─> 阶段一:精确匹配
│ ├─ 从长到短尝试匹配
│ ├─ 允许跳过 new_text 开头噪音
│ └─ 反向查找(优先靠近尾部的匹配)
│
└─> 阶段二:模糊匹配(容错 3 字)
├─ 处理同音字、识别错误
└─ 匹配长度必须 > 容错数(避免误匹配)
步骤 4: 执行拼接
├─> 找到重叠 "天气"
├─> 丢弃 prev_text 尾部可能的漂移噪音
├─> 跳过 new_text 开头的噪音
└─> 结果: "今天天气真好啊"
步骤 5: 兜底逻辑
└─> 未找到匹配时,直接拼接
典型场景与效果
场景 1: 完美重叠
输入: "今天天气真" + "天气真好啊"
匹配: "天气"(精确匹配)
结果: "今天天气真好啊"
场景 2: 开头有口语噪音
输入: "今天天气真" + "嗯天气真好啊"
匹配: 跳过 1 字噪音,匹配 "天气"
结果: "今天天气真好啊"
场景 3: 识别错误(同音字)
输入: "今天天气真" + "天起真好啊" ("气"识别成"起")
匹配: 模糊匹配,容错 1 字
结果: "今天天真好啊"(可能残留,交给下游 LLM 润色)
场景 4: 尾部漂移
输入: "今天天气真的" + "好的天气真好啊"
匹配: "天气"(丢弃 prev 的 "真的",丢弃 new 的 "好的")
结果: "今天天气真好啊"
核心优势
- 鲁棒性强: 精确→模糊→兜底三层容错,应对各种识别异常
- 抗噪音能力: 处理开头截断、尾部漂移、口语噪音、识别错误
- 高性能: 窗口搜索 + 反向查找,避免全文本扫描
- 智能拼接: 不强制必须在绝对末尾匹配,灵活定位最佳拼接点
配置参数
在 util/constants.py 中定义:
OVERLAP_CHARS = 20: 搜索窗口大小(prev_text 末尾字符数)ERROR_TOLERANCE = 3: 容错字符数(模糊匹配时允许的最大误差)
实际应用
该算法用于生成 text 字段(简单文本拼接),相比基于时间戳的精确拼接,具有更强的容错能力,适合作为鲁棒输出使用。
总结
merge_by_text 通过窗口搜索、分层匹配、智能去重的设计,有效解决了语音切片重叠问题。在实际使用中,能够处理大部分常见的识别异常,是 CapsWriter-Offline 实现流畅语音识别体验的关键技术之一。