PaddleSpeech 标点恢复(Punctuation Restoration)实战指南:从命令行推理到 ErnieLinear 模型原理
2026/9/24 1:20:10 网站建设 项目流程
  • 人工智能
  • 语音
  • 音频
  • 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.

项目地址:https://gitcode.com/paddlepaddle/PaddleSpeech
点击查看免费下载

标点恢复(Punctuation Restoration)是自动语音识别(ASR)系统中常见的后处理环节:ASR 输出的纯文本没有标点,直接阅读困难,也会干扰分词、命名实体识别等下游 NLP 任务。本文以 PaddleSpeech 仓库中的 demos/punctuation_restoration 演示为主线,完整介绍如何用一条命令或几行 Python 代码为原始文本恢复标点,并深入 TextExecutor 源码 与 ErnieLinear 模型实现,讲解参数含义、推理调用链、预训练模型选型以及基于 IWSLT2012 数据集的训练流程。读完本文,你将掌握 PaddleSpeech 标点恢复功能的完整使用方案,并能自行扩展模型与数据。

一、为什么需要标点恢复

语音识别系统的输出通常是一串没有标点的连续文本。例如识别结果是:

今天的天气真不错啊你下午有空吗我想约你一起去吃饭

这样的文本存在两个问题:

  1. 可读性差:没有标点,人类阅读时需要自行断句,长句场景尤其费力;
  2. 阻碍下游 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()动态生成,意味着新增预训练模型后无需修改代码即可扩展;
  • configckpt_pathpunc_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_wudaoernie_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_wudaozh3(,。?)
ernie_linear_p7_wudaozh7(,。!?、:;)

模型名称中的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_idstoken_type_idsseq_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_typeErnie数据集类型,可选Punc/Ernie
train_path/dev_path/test_pathdata/iwslt2012_zh/*.txt训练/验证/测试数据路径
batch_size64批大小
data_params.pretrained_tokenernie-1.0ERNIE 预训练模型名
data_params.punc_pathdata/iwslt2012_zh/punc_vocab标点词表路径
data_params.seq_len100序列最大长度
model_typeErnieLinear模型类名
model.pretrained_tokenernie-1.0模型内部使用的预训练权重
model.num_classes4分类数(1 个"无标点" + 3 个标点类别)
optimizer_params.weight_decay1.0e-6L2 权重衰减系数
scheduler_params.learning_rate1.0e-5学习率
scheduler_params.gamma0.9999指数衰减因子(越接近 1.0 越好)
max_epoch20最大训练轮数
num_snapshots10保留的模型快照数量
seed42随机种子(保证可复现)

训练流程使用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.

项目地址:https://gitcode.com/paddlepaddle/PaddleSpeech
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询