☰
PaddleSpeech 8k 呼叫中心 ASR 实战指南:基于 Conformer/U2 的离线与流式语音识别
2026/9/25 2:27:59 网站建设 项目流程
  • 人工智能
  • 语音
  • 音频

【免费下载链接】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/gh_mirrors/pa/PaddleSpeech
点击查看免费下载

本文以 PaddleSpeech 仓库中的 callcenter 示例 为核心,系统讲解面向呼叫中心、客服电话等 8k 采样率语音场景的 ASR 全流程:如何自备数据生成 manifest、如何配置离线 Conformer 与流式 Chunk Conformer、如何使用四种解码方式评估模型、以及如何做 CTC 对齐与 JIT 模型导出。读完本文,你将能够独立跑通一套 8k 电话语音识别(Mandarin 8k)的训练、评测、对齐与部署链路。

一、Recipe 定位:一个只含配置、不含数据的 8k ASR 示例

在 PaddleSpeech 中,examples/callcenter是一个特殊的示例:它不像 aishell 或 librispeech 那样自带数据下载逻辑,而是只提供面向 8k 采样率的模型配置与数据配置。正如其在 examples/callcenter/README.md 中明确说明的:

This recipe only has model/data config for 8k ASR, user need to prepare data and generate manifest metafile. You can see Aishell or Libripseeth.

也就是说:用户需要自行准备 8k 电话语音数据(如呼叫中心录音),并参照 Aishell/Librispeech 的流程生成 manifest 元数据文件,然后复用本 recipe 的配置与脚本完成训练和评测。呼叫中心语音与常规 16k 朗读语音差异明显:采样率低(8k)、信道特性复杂、口语化与噪声较多,因此单独维护一套 8k 配置是必要的。

该示例的实际目录结构如下:

examples/callcenter/ ├── README.md └── asr1/ ├── RESULTS.md # MandarinK8 实验结果(CER) ├── path.sh # 环境变量与 BIN_DIR(MODEL=u2) ├── run.sh # 主入口,按 stage 驱动全流程 ├── conf/ │ ├── conformer.yaml # 离线 Conformer 训练/推理配置 │ ├── chunk_conformer.yaml # 流式(分块)Conformer 配置 │ ├── preprocess.yaml # fbank 特征 + SpecAugment 预处理 │ ├── augmentation.json # 在线数据增强(speed/shift/specaug) │ └── tuning/ │ ├── decode.yaml # 离线解码配置 │ └── chunk_decode.yaml # 流式模拟解码配置 └── local/ ├── data.sh # 数据准备(CMVN、词表、格式化 manifest) ├── train.sh # 单机多卡训练 ├── test.sh # 四种解码方式评测 ├── align.sh # CTC 强制对齐 ├── export.sh # 导出 JIT 推理模型 └── download_lm_ch.sh # 下载中文语言模型(可选)

从 path.sh 可以看出,该 recipe 使用的模型框架是MODEL=u2,训练与推理脚本位于paddlespeech/s2t/exps/u2/bin/(包括train.py、test.py、alignment.py、export.py、test_wav.py等)。U2 即论文Unified Streaming and Non-streaming Two-pass End-to-end Model for Speech Recognition(arXiv:2012.05481)所描述的两遍式模型,这也是本 recipe 既能跑离线识别、又能跑流式识别的原因。

二、数据准备:自备 8k 数据并生成 manifest

2.1 原始 manifest 的字段格式

callcenter 的data.sh假定用户已经准备好了data/manifest.train、data/manifest.dev、data/manifest.test三个原始 manifest 文件(jsonline 格式,每行一个 JSON 对象)。生成这种格式的参考实现是 paddlespeech/dataset/aishell/aishell.py,每个条目包含如下字段:

{ "utt": "音频ID(如 BAC009S0002W0123)", "utt2spk": "说话人ID", "feat": "/绝对路径/到/音频.wav", "feat_shape": [3.2], "text": "对应的中文转写文本" }

其中feat_shape是音频时长(秒),feat直接指向 wav 文件路径(format_data.py会识别其为sound类型的输入)。如果你的数据是 Kaldi 风格的 ark 特征,format_data.py 会直接抛出NotImplementedError——当前 recipe 只支持直接读 wav。务必保证音频为 8k 采样率,这关系到后续 CMVN 与 fbank 参数的正确性。

2.2 三步数据流水线

local/data.sh 在拿到上述三个原始 manifest 后,分三步加工:

Step -1:备份原始文件。将data/manifest.{train,dev,test}重命名为.raw后缀,供后续步骤读取。

Step 0:计算 CMVN 统计量。调用 utils/compute_mean_std.py 生成data/mean_std.json,关键参数体现了 8k 场景的设定:

python3 ${MAIN_ROOT}/utils/compute_mean_std.py \ --manifest_path="data/manifest.train.raw" \ --spectrum_type="fbank" \ --feat_dim=80 \ --delta_delta=false \ --stride_ms=10 \ --window_ms=25 \ --sample_rate=8000 \ --use_dB_normalization=False \ --num_samples=-1 \ --num_workers=${num_workers} \ --output_path="data/mean_std.json"

对比 Aishell 的同一脚本(--sample_rate=16000),callcenter 将sample_rate显式设为8000,这是整个 recipe 最核心的差异点;feat_dim=80的 fbank、stride_ms=10、window_ms=25则与标准配置保持一致。

Step 1:构建字符词表。调用 utils/build_vocab.py,以--unit_type="char"从训练集转写文本生成data/lang_char/vocab.txt(count_threshold=0表示不过滤低频字符)。

Step 2:格式化 manifest。对 train/dev/test 三个数据集并行调用 utils/format_data.py,把原始 manifest 转换为带 tokenid 的训练/评测格式(输出到data/manifest.{train,dev,test})。从 paddlespeech/dataset/s2t/format_data.py 的源码可以看到,转换后的条目形如:

{ "input": [{"name": "input1", "shape": [...], "feat": "/path/to/audio.wav", "filetype": "sound"}], "output": [{"name": "target1", "shape": [...], "text": "转写文本", "token": "...", "tokenid": "..."}], "utt": "...", "utt2spk": "..." }

完成后,data/目录下应有manifest.train(.raw)、manifest.dev(.raw)、manifest.test(.raw)、mean_std.json以及lang_char/vocab.txt,与 conf/conformer.yaml 中train_manifest、dev_manifest、test_manifest、vocab_filepath的默认路径一一对应。

三、模型配置:离线 Conformer 与流式 Chunk Conformer

3.1 离线版 conf/conformer.yaml

conf/conformer.yaml 是默认训练配置,采用Conformer 编码器 + Transformer 解码器 + 混合 CTC/Attention的 U2 结构:

  • 数据加载:unit_type: 'char'、feat_dim: 80、sortagrad: 0(关闭按时长排序)、batch_size: 64、maxlen_in: 512/maxlen_out: 150(超长样本自动缩减 batch)、num_workers: 0;
  • 编码器 encoder_conf:output_size: 256、attention_heads: 4、linear_units: 2048、num_blocks: 12、dropout_rate: 0.1、input_layer: conv2d、cnn_module_kernel: 15、activation_type: 'swish'、位置编码rel_pos、注意力rel_selfattn;
  • 解码器 decoder_conf:attention_heads: 4、linear_units: 2048、num_blocks: 6;
  • 模型目标 model_conf:ctc_weight: 0.3(CTC 与 attention 的混合权重)、lsm_weight: 0.1(标签平滑)、length_normalized_loss: false;
  • 训练策略:n_epoch: 100、accum_grad: 4(梯度累积)、global_grad_clip: 5.0、优化器adam(lr: 0.002、weight_decay: 1e-6)、调度器warmuplr(warmup_steps: 25000)、checkpoint.kbest_n: 50/latest_n: 5。

3.2 流式版 conf/chunk_conformer.yaml

conf/chunk_conformer.yaml 用于训练支持流式推理的分块模型,与离线版的关键差异包括:

  • 数据加载:batch_size: 32、raw_wav: True(直接读原始 wav)、spectrum_type: fbank、target_sample_rate: 8000、dither: 1.0、use_dB_normalization: True(target_dB: -20)、sortagrad: True、shuffle_method: batch_shuffle、num_workers: 2;
  • 编码器新增流式相关字段:causal: true(因果卷积)、use_dynamic_chunk: true(动态分块训练)、cnn_module_norm: 'layer_norm'(注释说明使用 LayerNorm 收敛更快)、use_dynamic_left_chunk: false;
  • 训练策略:n_epoch: 240、lr: 0.001,其余结构(编码器 12 层、解码器 6 层、ctc_weight 0.3 等)与离线版保持一致。

从 paddlespeech/s2t/models/u2/u2.py 的源码看,推理时 U2 模型会依据decoding_chunk_size与num_decoding_left_chunks决定是否调用encoder.forward_chunk_by_chunk做逐块前向,这正是流式解码的底层机制。

3.3 特征预处理与数据增强

conf/preprocess.yaml 定义了特征提取与在线增强管线:

process: - type: fbank_kaldi fs: 8000 # 8k 采样率 n_mels: 80 n_shift: 160 # 10ms win_length: 400 # 25ms dither: 0.1 - type: cmvn_json cmvn_path: data/mean_std.json # SpecAugment 三件套 - type: time_warp max_time_warp: 5 inplace: true mode: PIL - type: freq_mask F: 30 n_mask: 2 inplace: true replace_with_zero: false - type: time_mask T: 40 n_mask: 2 inplace: true replace_with_zero: false

注意fs: 8000、n_shift: 160(= 8000 × 0.01s)、win_length: 400(= 8000 × 0.025s)与 8k 采样率严格对应。

conf/augmentation.json 则提供了另一套在线增强:变速speed(0.9~1.1,prob 0.0 默认关闭)、时间平移shift(±5ms,prob 1.0)、SpecAugmentspecaug(F: 10、T: 50、各 2 个 mask、replace_with_zero: true,prob 1.0)。RESULTS.md 中标注的实验增强组合为spec_aug + shift。

四、解码配置与四种解码方式

4.1 离线解码 conf/tuning/decode.yaml

conf/tuning/decode.yaml 的完整参数如下:

decode_batch_size: 128 error_rate_type: cer decoding_method: attention # 'attention', 'ctc_greedy_search', 'ctc_prefix_beam_search', 'attention_rescoring' beam_size: 10 ctc_weight: 0.5 # ctc weight for attention rescoring decode mode. decoding_chunk_size: -1 # <0: 全序列解码; >0: 固定块大小; 0: 仅训练用,禁止 num_decoding_left_chunks: -1 # 左侧历史块数,-1 表示不限制 simulate_streaming: False # 是否模拟流式推理

4.2 流式模拟解码 conf/tuning/chunk_decode.yaml

conf/tuning/chunk_decode.yaml 与离线版参数完全相同,唯一的区别是simulate_streaming: true——配合 chunk 模型(如decoding_chunk_size: 16)即可模拟流式推理的评测。RESULTS.md中 Chunk Conformer 的实验即采用Chunk Size & Left Chunks = 16, -1。

4.3 四种解码方法

local/test.sh 会遍历四种解码方式并分别输出结果文件({ckpt_prefix}/{method}.rsl):

解码方式说明
attention纯 attention 解码(自回归)
ctc_greedy_searchCTC 贪心搜索,速度最快
ctc_prefix_beam_searchCTC prefix beam search
attention_rescoring两遍式:先用 CTC beam search 生成候选,再用 attention 重打分,通常效果最好

测试时通过--opts decode.decoding_method ${type} --opts decode.decode_batch_size 1逐项覆盖默认配置。如果需要使用中文语言模型参与 CTC 解码,可执行 local/download_lm_ch.sh 下载zh_giga.no_cna_cmn.prune01244.klm(脚本中已给出 URL 与 MD5 校验值),不过 local/test.sh 中该步骤默认处于注释状态。

五、端到端流水线:run.sh 的 stage 设计

run.sh 采用 PaddleSpeech 通用的 stage 驱动模式(配合 utils/parse_options.sh 支持--stage N --stop_stage M形式的命令行覆盖),顶部的关键变量:

gpus=0,1,2,3 stage=0 stop_stage=50 conf_path=conf/conformer.yaml ips= # 多机训练时填写节点 IP 列表 decode_conf_path=conf/tuning/decode.yaml avg_num=20

各 stage 功能如下:

Stage功能调用脚本
0数据准备(CMVN、词表、格式化 manifest)local/data.sh
1模型训练(多卡)local/train.sh
2平均 top-k 模型得到最终模型avg.sh best exp/${ckpt}/checkpoints ${avg_num}
3测试 avg_n 模型(四种解码方式)local/test.sh
4测试集 CTC 强制对齐local/align.sh
51导出 JIT 推理模型local/export.sh

例如只做数据准备:bash run.sh --stage 0 --stop_stage 0;完整跑训练到评测:bash run.sh --stage 0 --stop_stage 3。

训练(stage 1):local/train.sh 根据CUDA_VISIBLE_DEVICES中的 GPU 数量自动选择单卡或分布式模式。多卡时使用python3 -m paddle.distributed.launch --gpus=... [--ips=...] ${BIN_DIR}/train.py,其中ips用于多机训练。脚本还支持seed控制(非 0 时设置FLAGS_cudnn_deterministic=True保证可复现,但注释提示"seed may break model convergence")。

模型平均(stage 2):utils/avg.sh 调用avg_model.py,支持best(按验证损失选 top-k)与latest(取最近 k 个)两种模式,输出exp/${ckpt}/checkpoints/avg_${avg_num}.pdparams,这也是后续测试、对齐、导出所共用的 checkpoint 前缀。

六、CTC 对齐与模型导出

CTC 对齐(stage 4):local/align.sh 调用${BIN_DIR}/alignment.py,基于最终模型对测试集做 CTC 强制对齐,将对齐结果写入result_file(.align),并在结果文件所在目录生成.tier与.TextGrid格式的对齐文件——这些输出可直接用于音素级/字级边界分析或后续强制对齐工具链。

模型导出(stage 51):local/export.sh 调用${BIN_DIR}/export.py,把训练好的 checkpoint 转换为可部署的 JIT 模型:

CUDA_VISIBLE_DEVICES= ./local/export.sh ${conf_path} \ exp/${ckpt}/checkpoints/${avg_ckpt} \ exp/${ckpt}/checkpoints/${avg_ckpt}.jit

导出的.jit模型可进一步配合 PaddleSpeech 的服务端(如paddlespeech/server)或 runtime 部署方案 使用。

七、MandarinK8 实验结果参考

RESULTS.md 记录了在MandarinK8(中文 8k)测试集上的官方复现结果。两个模型参数量均为45.73 M,增强方式均为spec_aug + shift:

Conformer(离线,conf/conformer.yaml,Loss 2.1795):

解码方式CER
attention0.102304
ctc_greedy_search0.084295
ctc_prefix_beam_search0.084340
attention_rescoring0.081675

Chunk Conformer(流式,conf/chunk_conformer.yaml,Chunk=16 / Left=-1,Loss 2.2329):

解码方式CER
attention0.087982
ctc_greedy_search0.086962
ctc_prefix_beam_search0.086741
attention_rescoring0.083495

这两组数据可以为你评估自备数据的训练效果提供对照基线:离线两遍式解码(attention_rescoring)在该任务上 CER 最低;流式模型在 16 帧分块约束下与离线模型差距约 0.2 个百分点,体现了 U2 两遍式架构在"低延迟"与"高精度"之间的折中能力。

八、从源码看 U2 的流式/非流式统一机制

本 recipe 之所以能同时覆盖离线与流式两种形态,根源在于 paddlespeech/s2t/models/u2/u2.py 实现的统一模型:训练时使用动态分块(dynamic chunk)策略让编码器适应分块输入;推理时根据simulate_streaming与decoding_chunk_size决定是否走forward_chunk_by_chunk逐块计算编码器输出(u2.py),再配合ctc_prefix_beam_search生成候选、attention_rescoring二次打分,形成完整的流式两遍解码。

对应地,训练与推理的完整实现位于 paddlespeech/s2t/exps/u2/model.py(U2Trainer/U2Tester的train_batch、test、export等),命令行入口则在 paddlespeech/s2t/exps/u2/bin/ 下。理解这层调用链,有助于你在修改conf/下任一配置后快速定位其生效的代码路径。

结语

examples/callcenter是一个"轻文档、重配置"的典型 recipe:文档虽短,但仓库内的两份 YAML、预处理与增强配置、stage 流水线脚本以及 MandarinK8 基线结果,共同构成了一套完整的 8k 电话语音识别落地模板。对于需要处理客服录音、电话会议等低采样率语音场景的开发者,直接复用本 recipe 的配置,替换为自己的数据并生成对应 manifest,即可复现出接近上表基线的离线与流式 ASR 系统。

  • 人工智能
  • 语音
  • 音频

【免费下载链接】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/gh_mirrors/pa/PaddleSpeech
点击查看免费下载
上一篇:ADB在浏览器中的革命:ya-webadb项目解析及新手指南
下一篇:cppimport:简化C++与Python集成的开源项目

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

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

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

立即咨询