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