- 人工智能
- 语音
- 音频
- NLP
- 媒体生成
【免费下载链接】PaddleSpeech
Easy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation and Keyword Spotting. Won NAACL2022 Best Demo Award.
标点恢复(Punctuation Restoration)是自动语音识别(ASR)系统中常见的后处理环节:ASR 输出的纯文本没有标点,直接阅读困难,也会干扰分词、命名实体识别等下游 NLP 任务。本文以 PaddleSpeech 仓库中的 demos/punctuation_restoration 演示为主线,完整介绍如何用一条命令或几行 Python 代码为原始文本恢复标点,并深入 TextExecutor 源码 与 ErnieLinear 模型实现,讲解参数含义、推理调用链、预训练模型选型以及基于 IWSLT2012 数据集的训练流程。读完本文,你将掌握 PaddleSpeech 标点恢复功能的完整使用方案,并能自行扩展模型与数据。
一、为什么需要标点恢复
语音识别系统的输出通常是一串没有标点的连续文本。例如识别结果是:
今天的天气真不错啊你下午有空吗我想约你一起去吃饭这样的文本存在两个问题:
- 可读性差:没有标点,人类阅读时需要自行断句,长句场景尤其费力;
- 阻碍下游 NLP 任务:机器翻译、信息抽取、情感分析等任务依赖句子边界,缺少标点会显著影响效果。
标点恢复就是把标点符号"加回去"的后处理技术,它是 ASR 系统中提升转录文本可读性、衔接下游任务的重要一环。PaddleSpeech 将标点恢复封装为text任务的punc子任务,底层使用基于 ERNIE 预训练模型的序列标注方法,支持直接推理,也支持自定义数据训练。
二、安装与环境准备
在使用标点恢复功能之前,需要先安装 PaddleSpeech。仓库的 安装文档 提供了 easy、medium、hard 三种安装方式:
- easy(推荐):直接通过 pip 安装 PaddleSpeech 及其依赖;
- medium:额外编译安装一些工具;
- hard:从源码编译,适合需要定制底层能力的场景。
同时需要确保环境中已安装 PaddlePaddle,paddlespeech text命令行与 Python API 都会依赖它来完成模型推理(device参数默认取自paddle.get_device())。安装完成后,可通过paddlespeech text --help查看命令帮助,确认安装成功。
三、命令行快速体验
标点恢复的输入是特定语言的原始文本,通过--input参数直接传入,无需准备任何文件。在终端执行:
paddlespeech text --input 今天的天气真不错啊你下午有空吗我想约你一起去吃饭运行成功后输出如下(日志时间因环境而异):
[2021-12-14 19:50:22,200] [ INFO] [log.py] [L57] - Text Result: 今天的天气真不错啊!你下午有空吗?我想约你一起去吃饭。从输出可以看到,模型在"啊"后补充了感叹号、在"吗"后补充了问号、在句尾补充了句号。仓库中的 run.sh 正是这条命令的脚本化封装:
#!/bin/bash paddlespeech text --input 今天的天气真好啊你下午有空吗我想约你一起去吃饭demo 目录下同时提供了中英文 README(README.md 与 README_cn.md),方便不同语言用户查阅。
命令行参数详解
paddlespeech text的参数在 TextExecutor 的 argparse 定义中逐一声明,各参数含义与默认值如下:
| 参数 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|
--input | 必填 | None | 待恢复标点的原始文本 |
--task | 可选 | punc | 子任务类型,目前仅支持punc |
--model | 可选 | ernie_linear_p7_wudao | 文本任务模型类型 |
--lang | 可选 | zh | 模型语言,可选zh/en |
--config | 可选 | None | 模型配置文件,为None时使用预训练模型自带配置 |
--ckpt_path | 可选 | None | 模型 checkpoint 文件,为None时自动下载预训练模型 |
--punc_vocab | 可选 | None | 标点词表文件,为None时使用预训练模型自带词表 |
--device | 可选 | paddle.get_device() | 推理设备,默认取当前环境 paddlepaddle 的默认设备 |
需要注意几点:
--task的可选值在源码中被限定为['punc'](见 infer.py 的 choices 定义),说明当前text子命令聚焦于标点恢复这一个任务;--model的可选值并非写死,而是由self.task_resource.pretrained_models.keys()动态生成,意味着新增预训练模型后无需修改代码即可扩展;- 当
config、ckpt_path、punc_vocab三者均为None时,推理器会根据model-task-lang拼接出的 tag(如ernie_linear_p7_wudao-punc-zh)自动定位并下载对应的预训练资源,这一逻辑在 _init_from_path 中实现。
四、Python API 调用
除命令行外,还可以在 Python 脚本中调用TextExecutor完成标点恢复。demo 中的示例代码如下:
import paddle from paddlespeech.cli.text import TextExecutor text_executor = TextExecutor() result = text_executor( text='今天的天气真不错啊你下午有空吗我想约你一起去吃饭', task='punc', model='ernie_linear_p7_wudao', lang='zh', config=None, ckpt_path=None, punc_vocab=None, device=paddle.get_device()) print('Text Result: \n{}'.format(result))输出:
Text Result: 今天的天气真不错啊!你下午有空吗?我想约你一起去吃饭。Python API 的__call__方法签名与命令行参数一一对应(见 TextExecutor.call),并且对不同代际的模型走了两条推理路径:
- 对于
ernie_linear_p7_wudao、ernie_linear_p3_wudao这类"老版本"模型,走_init_from_path(旧式加载); - 对于其他新模型(如
ernie-3.0-*系列),走_init_from_path_new(新式加载,用paddle.load显式加载 state_dict)。
两种路径最终都会依次执行preprocess → infer → postprocess三段式流水线,返回恢复标点后的完整文本字符串。
五、预训练模型选型
PaddleSpeech 为标点恢复任务发布了多个预训练模型,均可被命令行和 Python API 直接使用:
| 模型 | 语言 | 标点类型数 |
|---|---|---|
ernie_linear_p3_wudao | zh | 3(,。?) |
ernie_linear_p7_wudao | zh | 7(,。!?、:;) |
模型名称中的p3/p7直接对应标点词表的大小:
p3模型只区分逗号、句号、问号三类标点,输出更保守、速度更快,适合标点体系简单的场景;p7模型额外覆盖感叹号、顿号、冒号、分号,共 7 类标点,表达更丰富,是当前--model的默认选择。
需要说明的是,这些预训练模型的具体评测指标并未在该 demo 文档中给出,但仓库的 examples/iwslt2012/punc0/README.md 提供了基于 IWSLT2012-Zh 数据集的完整实验结果表(含 Ernie 1.0、Ernie-tiny、Ernie-3.0 各尺寸变体的 Precision / Recall / F1),可以作为衡量不同骨干模型效果的参考。
六、源码级原理:推理调用链与 ErnieLinear 模型
理解源码能帮你更好地选参数、调模型。标点恢复的完整调用链如下:
paddlespeech text --input ... │ ▼ TextExecutor.execute() # 命令行入口,解析参数 │ ▼ TextExecutor.__call__() # Python API 入口 │ ▼ _init_from_path() / _init_from_path_new() # 加载词表、模型与 tokenizer │ ▼ preprocess() → infer() → postprocess() # 三段式推理流水线1. 模型结构:ErnieLinear
核心模型 ErnieLinear 是一个基于 ERNIE 预训练模型的序列标注分类器:
- 主体是
ErnieForTokenClassification(来自 PaddleNLP),默认加载ernie-1.0预训练权重; - 前向传播时,ERNIE 编码器为每个 token 输出隐藏状态,经
paddle.reshape展平为[-1, num_classes]的 logits,再通过nn.Softmax得到概率分布; - 推理时对 logits 取
argmax,得到每个 token 的标点类别预测(见 infer 方法)。
也就是说,标点恢复被建模为逐 token 的多分类任务:每个汉字/词对应一个输出位置,类别 0 表示"不加标点",其余类别对应不同的标点符号。
2. 预处理:文本清洗与 token 化
在 preprocess 之前,先经过 _clean_text 清洗:
def _clean_text(self, text): text = text.lower() text = re.sub('[^A-Za-z0-9\u4e00-\u9fa5]', '', text) text = re.sub(f'[{"".join([p for p in self._punc_list][1:])}]', '', text) return text清洗规则为:统一小写;只保留英文字母、数字与中文字符,剔除其余字符;再把输入中可能已存在的标点(词表第 1 项之后的所有标点)全部移除。这保证送入模型的永远是"纯净的"无标点文本。
随后使用ErnieTokenizer对字符列表进行切分,产出input_ids、token_type_ids和seq_len三个张量,作为模型输入。
3. 后处理:标点回填
在 postprocess 中,推理得到的预测标签被逐 token 映射回文本:
for t, l in zip(tokens, labels): text += t if l != 0: # Non punc. text += self._punc_list[l]即每个 token 输出后,如果预测类别l != 0,就紧接着拼上词表中对应的标点符号。拼接完成后即得到最终的可读文本。相同的逻辑也出现在独立的 punc_restore.py 测试脚本 中,可以作为理解全流程的对照实现。
七、进阶:自定义数据训练标点恢复模型
demo 聚焦于推理,但仓库同时提供了完整的训练与评测链路。以examples/iwslt2012/punc0为例,可以端到端训练自己的标点恢复模型:
# 数据预处理 ./run.sh --stage 0 --stop-stage 0 # 模型训练 ./run.sh --stage 1 --stop-stage 1 # 测试(指标评估) ./run.sh --stage 2 --stop-stage 2 # 标点恢复(推理验证) ./run.sh --stage 3 --stop-stage 3四个 stage 分别对应数据准备、训练、测试与推理,相关脚本位于 local/ 目录。
训练配置文件解读
训练入口 train.py 通过 yacs 的CfgNode读取配置,default.yaml 中关键配置项如下:
| 配置项 | 示例值 | 说明 |
|---|---|---|
dataset_type | Ernie | 数据集类型,可选Punc/Ernie |
train_path/dev_path/test_path | data/iwslt2012_zh/*.txt | 训练/验证/测试数据路径 |
batch_size | 64 | 批大小 |
data_params.pretrained_token | ernie-1.0 | ERNIE 预训练模型名 |
data_params.punc_path | data/iwslt2012_zh/punc_vocab | 标点词表路径 |
data_params.seq_len | 100 | 序列最大长度 |
model_type | ErnieLinear | 模型类名 |
model.pretrained_token | ernie-1.0 | 模型内部使用的预训练权重 |
model.num_classes | 4 | 分类数(1 个"无标点" + 3 个标点类别) |
optimizer_params.weight_decay | 1.0e-6 | L2 权重衰减系数 |
scheduler_params.learning_rate | 1.0e-5 | 学习率 |
scheduler_params.gamma | 0.9999 | 指数衰减因子(越接近 1.0 越好) |
max_epoch | 20 | 最大训练轮数 |
num_snapshots | 10 | 保留的模型快照数量 |
seed | 42 | 随机种子(保证可复现) |
训练流程使用CrossEntropyLoss作为损失函数、Adam优化器配合ExponentialDecay学习率调度,并挂载了VisualDL可视化与Snapshot快照扩展(对应代码见 train.py 中 Trainer 的构建)。需要注意model.num_classes必须与punc_vocab词表大小一致(1 + 标点种类数)。
选择更大的 ERNIE 骨干
conf/目录下还提供了多个 ERNIE 3.0 系列变体的配置,例如:
- ernie-3.0-base.yaml
- ernie-3.0-medium.yaml
- ernie-3.0-mini.yaml
- ernie-3.0-nano-zh.yaml
- ernie-tiny.yaml
这些配置在骨干模型与num_classes等参数上有所区别。从 examples/iwslt2012/punc0/README.md 的结果表可以推断:不同尺寸的 ERNIE 变体在 Precision、Recall 与 F1 上各有取舍——较大的模型(如 base)通常精度上限更高,较小的模型(如 tiny、nano)更适合资源受限的部署环境,实际选型需结合数据规模与推理延迟综合权衡。训练完成后,将产出 checkpoint 与词表,即可通过--config、--ckpt_path、--punc_vocab三个参数让推理器加载你自己的模型(此时不再自动下载预训练权重)。
八、小结
PaddleSpeech 的标点恢复功能为 ASR 后处理提供了开箱即用的解决方案:
- 一行命令即可体验:
paddlespeech text --input <raw_text>,也支持等价的 Python API; - 预训练模型开箱即用:
ernie_linear_p3_wudao(3 类标点)与ernie_linear_p7_wudao(7 类标点)覆盖常见中文标点体系; - 源码可读可扩展:TextExecutor 的三段式推理流水线、ErnieLinear 的序列标注结构清晰,且可通过
--config、--ckpt_path、--punc_vocab无缝切换到自定义训练模型; - 完整训练链路齐备:基于 examples/iwslt2012/punc0 可复现数据预处理、训练、评测与推理全流程。
无论你是想快速为 ASR 转录文本加上标点,还是希望基于自有语料训练定制化的标点恢复模型,都可以直接以本文与上述仓库文件为起点展开实践。
- 人工智能
- 语音
- 音频
- NLP
- 媒体生成
【免费下载链接】PaddleSpeech
Easy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation and Keyword Spotting. Won NAACL2022 Best Demo Award.
相关推荐
PaddleSpeech 标点恢复(Punctuation Restoration)实战指南:从命令行到源码原理
PaddleSpeech 标点恢复(Punctuation Restoration)实战指南:从命令行到源码原理 标点恢复(Punctuation Restor
人工智能语音音频PaddleSpeech 标点恢复(Punctuation Restoration)实战指南:从命令行到源码级原理
PaddleSpeech 标点恢复(Punctuation Restoration)实战指南:从命令行到源码级原理 标点恢复是语音识别(ASR)系统中提升转录文
人工智能语音音频NLP媒体生成PaddleSpeech 标点恢复(Punctuation Restoration)实战:一行命令为 ASR 文本智能补全标点
PaddleSpeech 标点恢复(Punctuation Restoration)实战:一行命令为 ASR 文本智能补全标点 标点恢复(Punctuation
人工智能语音音频
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考