☰
基于 ESPnet2 的 JTubeSpeech 日语多说话人 TTS Recipe:数据自动下载、CTC 阈值剪枝与模型训练实战
2026/9/25 3:40:46 网站建设 项目流程
  • 人工智能
  • 语音
  • 音频
  • 深度学习
  • NLP

【免费下载链接】espnet

End-to-End Speech Processing Toolkit

项目地址:https://gitcode.com/gh_mirrors/es/espnet
点击查看免费下载

本篇技术指南围绕 ESPnet2 仓库中的 egs2/jtubespeech/tts1/README.md 展开,完整讲解如何基于 JTubeSpeech 语料构建日语多说话人 TTS 系统:从自动下载约 20GB 的单说话人子集、用 CTC-score 阈值对低质量语音进行数据剪枝,到通过 tts.sh 与各模型配置(Tacotron2 / FastSpeech2 + GST + X-vector)完成训练与解码。读者读完即可复现该 recipe 的全流程,并掌握调整数据剪枝阈值、切换文本前端与模型架构的具体方法。

JTubeSpeech 语料与 recipe 概览

egs2/jtubespeech/tts1 是 ESPnet2 中面向 JTubeSpeech 语料库的日语多说话人 TTS recipe。JTubeSpeech 是一个大规模日语语音语料库,其语音来自 YouTube 等渠道,语料中包含多人发音的语音与对应文本。该 recipe 的核心特点是:

  • 自动下载数据:脚本会自动下载并使用一个约20GB 的单说话人子集(single-speaker split),无需手动准备语料;
  • 基于 CTC 分数的数据剪枝:因为 YouTube 自动字幕中可能存在识别错误或噪声,recipe 使用预先计算的 CTC 分数对语音进行过滤,默认阈值为-0.1,可通过local/data.sh的参数调整;
  • 多说话人建模:训练时默认启用 speaker embedding(x-vector),支持 GST + X-vector 等多说话人扩展;
  • 多种模型可切换:默认配置为 Tacotron2,也可通过 tuning 配置切换为 FastSpeech2(Conformer 编码器)等。

该 recipe 的完整运行方式、各模型的训练指南均继承自 ESPnet2 的 TTS 模板文档 egs2/TEMPLATE/tts1/README.md,本文会逐条给出对应的仓库内链接。

数据准备流水线:从下载到 Kaldi 风格数据目录

recipe 的run.sh会依次执行数据下载、预处理、切分、静音去除与数据子集划分。其中数据准备部分由 local/data.sh 驱动,分为 4 个阶段:

阶段说明调用的脚本
stage -1数据下载local/download.sh
stage 0初始数据规范化(切分 + 剪枝)local/data_prep.sh
stage 1静音去除(trim silence)scripts/audio/trim_silence.sh
stage 2训练/开发/测试集划分utils/subset_data_dir.sh

自动下载:download.sh

local/download.sh 使用gdown从 Google Drive 下载jtuberaw.tar.gz(Google Drive 文件 ID 为1X_harC0e1tjMX1FtCldD67XOysQuq_Ib),下载后解压到downloads/jtuberaw目录。若目录已存在则自动跳过,保证脚本可重复执行。依赖db.sh中的JTUBESPEECH变量指定存放位置:

# egs2/jtubespeech/tts1/db.sh JTUBESPEECH=downloads

local/data.sh在启动时会检查该变量:

if [ -z "${JTUBESPEECH}" ]; then log "Fill the value of 'JTUBESPEECH' of db.sh" exit 1 fi db_root=${JTUBESPEECH}

切分与剪枝:split.py + prune.py

下载得到的原始数据为整段 YouTube 音频及其字幕文本,需要先按句子边界切分成句级片段,再用 CTC 分数过滤掉低质量片段。local/data_prep.sh 依次调用两个 Python 脚本:

# 切分 wav 文件 python local/split.py --db_raw ${dbr} --db_split ${dbs} # 基于预计算的 ctcscore 剪枝 python local/prune.py --score_thresh ${scorethresh} --db_raw ${dbr} --db_split ${dbs}

切分(split.py):读取原始目录下的txt/<speaker>/*.txt字幕文件,其中每行是起始时间\t结束时间\t文本格式。脚本按时间段从原始 16kHz 波形中截取片段,输出为jtubesplit/wav16k/<stem>/<stem>_<idx>.wav,同时生成transcript_raw.txt(格式为片段ID 文本)。片段 ID 由原始文件名加 4 位序号组成,如stem_0000。

剪枝(prune.py):JTubeSpeech 提供了预先计算的 CTC 分数文件ctcscore.txt。prune.py 将该文件中每个片段 ID 的 CTC 分数与阈值--score_thresh比较,仅保留分数大于阈值的片段,写出transcript_prune.txt。核心逻辑见 local/prune.py:

d_ctcscore = dict() with open(ctcscore_path, "r") as fr: for line in fr: line_list = line.strip().split(" ", 5) d_ctcscore[line_list[0]] = float(line_list[4]) with open(raw_transcript_path, "r") as fr: for line in fr: line_list = line.strip().split(" ", 1) stem = line_list[0] try: if d_ctcscore[stem] > thresh_ctc: with open(pruned_transcript_path, "a") as fa: fa.write(line) except KeyError: pass

从源码可见:剪枝阈值越高,保留的语音越“干净”(要求更高的 CTC 置信度),保留的数据量也越小;阈值越低则保留更多数据,但可能混入更多识别错误或噪声片段。recipe 默认在local/data.sh中设置ctcscore_pruning_threshold=-0.1:

ctcscore_pruning_threshold=-0.1

调整阈值的方法:直接以参数形式覆盖默认值即可,例如保留更干净的数据:

./local/data.sh --ctcscore_pruning_threshold 0.0

或放宽筛选、保留更多数据:

./local/data.sh --ctcscore_pruning_threshold -0.5

注意该参数通过utils/parse_options.sh解析,而prune.py自身的默认阈值是-0.5,两者以local/data.sh的传入值为准。

生成 Kaldi 风格数据目录

剪枝完成后,local/data_prep.sh 遍历transcript_prune.txt生成标准数据文件:

  • text:片段ID 文本;
  • wav.scp:片段ID 绝对路径(通过find定位 wav16k 目录下的文件);
  • utt2spk:说话人 ID 取自文件名的前 11 个字符(spkr=${filename:0:11});
  • spk2utt:由utils/utt2spk_to_spk2utt.pl从utt2spk反向生成。

随后local/data.sh的 stage 1 调用scripts/audio/trim_silence.sh去除静音(--fs 16000 --win_length 1024 --shift_length 256 --threshold 35,并行度nj=8);stage 2 用utils/subset_data_dir.sh划分出dev(250 条)、test(250 条)验证/测试集,剩余数据构成训练集tr_no_dev,并最终产出data/all、data/devtest、data/dev、data/test、data/tr_no_dev等目录。

run.sh:训练入口与日语文本前端

完成数据准备后,egs2/jtubespeech/tts1/run.sh 调用通用的 tts.sh 执行后续的特征提取、token 列表生成、统计量收集、训练与解码。其关键参数如下:

参数值说明
--lang jp日语语言设置
--feats_type rawraw直接使用 16kHz 波形(fs=16000)
--fs 1600016000采样率;16000 时强制--audio_format wav
--n_fft 10241024FFT 点数
--n_shift 256256帧移
--win_length 10241024窗长
--use_spk_embed truetrue启用说话人嵌入(多说话人建模)
--spk_embed_tool kaldikaldi说话人嵌入工具(需编译 Kaldi,自动使用 xvector)
--spk_embed_tag xvectorxvector嵌入类型
--token_type phnphn音素级 token
--cleaner jaconvjaconv文本清理器(日语假名/汉字转换)
--g2p pyopenjtalkpyopenjtalk文本到音素转换
--train_set tr_no_dev/--valid_set dev/--test_sets "dev test"—数据集划分
--train_config conf/train.yaml—训练配置(默认 Tacotron2)
--inference_config conf/decode.yaml—解码配置

日语文本前端(g2p)是日语 TTS 的关键环节。run.sh 中注释给出了四种可选方案(输入示例こ、こんにちは):

  1. Phoneme + Pause(默认,g2p=pyopenjtalk):k o pau k o N n i ch i w a——音素加停顿符号,适合常规训练;
  2. Kana + Symbol(g2p=pyopenjtalk_kana):コ 、 コ ン ニ チ ワ——假名加标点符号;
  3. Phoneme + Accent(g2p=pyopenjtalk_accent):k 1 0 o 1 0 k 5 -4 ...——音素级声调(accent)标记,可提升韵律;
  4. Phoneme + Accent + Pause(g2p=pyopenjtalk_accent_with_pause):k 1 0 o 1 0 pau k 5 -4 ...——同时包含声调与停顿。

启用声调标注的方案(3、4)需要在训练与解码配置中配套使用use_phone_accent等选项,可根据目标音色表现与韵律质量自行切换。

模型配置解析:Tacotron2 默认配置与 FastSpeech2 调优配置

默认配置:Tacotron2 + GST + X-vector(conf/train.yaml)

conf/train.yaml 中默认训练 Tacotron2,并同时启用GST(Global Style Tokens)与X-vector 说话人嵌入,同时使用 guided attention loss 加速对角注意力学习。文件头注释说明:在 V100 上约需 4 天完成训练。关键配置项:

配置项值说明
tts: tacotron2—模型架构
embed_dim: 512512字符/音素嵌入维度
elayers: 1/eunits: 512—编码器 BLSTM 层数与单元数
econv_layers: 3/econv_chans: 512/econv_filts: 5—编码器卷积层配置
atype: location—location-based attention
adim: 512512注意力维度
dlayers: 2/dunits: 1024—解码器 LSTM 层数与单元数
prenet_layers: 2/prenet_units: 256—prenet 配置
postnet_layers: 5/postnet_chans: 512/postnet_filts: 5—postnet 配置
spk_embed_dim: 512512说话人嵌入维度
spk_embed_integration_type: addadd说话人嵌入融合方式
use_gst: true/gst_heads: 4/gst_tokens: 16—GST 多头注意力与全局风格 token 数
dropout_rate: 0.5/zoneout_rate: 0.1—dropout 与 zoneout
reduction_factor: 11解码 reduction factor
use_guided_attn_loss: true—启用 guided attention loss
guided_attn_loss_sigma: 0.4/lambda: 1.0—guided attention loss 参数
optim: adam/lr: 1.0e-03—优化器与学习率
num_iters_per_epoch: 500/max_epoch: 500—每轮迭代数与最大轮数
batch_bins: 3750000/batch_type: numel—按元素数打包 batch(feats_type=raw)
keep_nbest_models: 55保留的最优模型数

调优配置:Conformer FastSpeech2 + GST + X-vector

tuning/train_gst+xvector_conformer_fastspeech2.yaml 提供了 FastSpeech2 方案:Conformer 编码器/解码器 + GST + X-vector,注释说明需要 4 张 32GB 显存的 GPU,在 V100 上约 3 天完成训练。与原始 FastSpeech2 论文相比,该配置使用 token 平均的 pitch 与 energy(与 FastPitch 一致),且不做量化。由于 FastSpeech2 需要显式提取 pitch 与 energy,必须配合feats_type=raw使用。核心差异点:

配置项值说明
tts: fastspeech2—非自回归模型
adim: 384/aheads: 2—注意力维度与头数
elayers: 4/eunits: 1536/dlayers: 4/dunits: 1536—编解码器层数与 FFN 单元数
encoder_type: conformer/decoder_type: conformer—Conformer 编解码器
positionwise_layer_type: conv1d/kernel_size: 3—位置前馈层
duration_predictor_layers: 2/chans: 256/kernel_size: 3—时长预测器
pitch_predictor_layers: 5/energy_predictor_layers: 2—韵律预测器
pitch_extract: dio/pitch_normalize: global_mvn—基频提取与归一化
energy_extract: energy/energy_normalize: global_mvn—能量提取与归一化
scheduler: noamlr/warmup_steps: 4000—Noam 学习率调度
batch_bins: 18000000—更大的 batch 容量(raw 特征)

该目录下还提供了其他组合配置,如train_gst_fastspeech2.yaml、train_xvector_tacotron2.yaml、train_gst+xvector_transformer.yaml等,可通过--train_config参数自由切换:

./run.sh --train_config conf/tuning/train_gst+xvector_conformer_fastspeech2.yaml

训练、解码与评估:继承模板文档的完整流程

recipe 的执行方式、训练各类模型的具体命令、解码与评估等,均以 ESPnet2 TTS 模板文档 egs2/TEMPLATE/tts1/README.md 为准。该文档按 11 个 stage 组织流程:数据准备 → wav dump / 嵌入提取 → 说话人嵌入提取 → 长/短数据过滤(--min_wav_duration/--max_wav_duration)→ token 列表生成(--token_type char|phn)→ TTS 统计量收集 → 训练(--train_config/--train_args)→ 解码(--inference_config/--inference_args)→ 基于 VERSA 的评估 → 打包 → 上传 Hugging Face。

与本 recipe 直接相关的训练/使用入口如下(均为仓库内相对链接):

  • 如何运行 recipe:cd进入 recipe 目录、按需修改db.sh与cmd.sh、直接执行./run.sh完成全部阶段;也推荐首次运行时用--stage/--stop-stage逐步执行以理解各阶段产物。
  • FastSpeech 训练:需先训练教师模型(Tacotron2 / Transformer-TTS),用--tts_exp指定教师模型并以--test_sets "tr_no_dev dev eval1"对所有数据解码生成durations,再通过--teacher_dumpdir训练 FastSpeech。
  • FastSpeech2 训练:FastSpeech2 是自回归无关的非自回归模型,可直接使用上文 tuning 配置训练。
  • 多说话人模型(X-vector)训练:本 recipe 的run.sh已默认开启--use_spk_embed true --spk_embed_tool kaldi,训练时会自动提取 x-vector 作为说话人嵌入。
  • 多说话人模型(Speaker ID)训练:若希望改用说话人 ID 嵌入,需在数据准备阶段保证utt2spk正确,并切换--use_sid true等相关选项。
  • VITS 训练:VITS 为端到端 text2wav 模型,可直接生成波形,无需额外声码器。
  • 联合 text2wav 训练:训练可同时输出声学特征与波形的联合模型。
  • FAQ:涵盖 ESPnet1 模型兼容性、minibatch 调整、新 recipe 创建、g2p/cleaner 扩展、预训练模型加载与微调、任意文本测试、vocoder 训练等常见问题。

运行./run.sh后,recipe 目录会生成data/(Kaldi 风格数据目录)、dump/(特征与 token_list)、exp/(tts_stats_*统计量、tts_train_*模型与decode_*解码结果,其中wav/为通过 Griffin-Lim 重建的波形)。解码阶段默认使用 Griffin-Lim 生成波形;如需更高质量的神经声码器,可参照模板文档通过--inference_args "--vocoder_tag ..."或--vocoder_file接入 ParallelWaveGAN 等模型。

结语

JTubeSpeech TTS recipe 是 ESPnet2 中一个典型的大规模互联网语料 + 自动质量筛选的实战范例:约 20GB 的原始语音只需一次命令即可自动下载,配合预计算的 CTC 分数完成数据剪枝,再经由标准的 tts.sh 流水线训练出带 X-vector 说话人嵌入的日语多说话人 TTS 模型。其数据剪枝阈值(ctcscore_pruning_threshold)、文本前端(pyopenjtalk 系列 g2p)与模型配置(Tacotron2 / FastSpeech2 + GST + X-vector)均可灵活调整,为研究者在自有日语语料上构建多说话人 TTS 提供了可直接复用的完整流程。

  • 人工智能
  • 语音
  • 音频
  • 深度学习
  • NLP

【免费下载链接】espnet

End-to-End Speech Processing Toolkit

项目地址:https://gitcode.com/gh_mirrors/es/espnet
点击查看免费下载

相关推荐

上一篇:ActionBarSherlock的启动器图标适配:自适应图标实现
下一篇:DLSS-Enabler:打破硬件壁垒,让所有GPU都能享受DLSS黑科技的终极解决方案

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

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

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

立即咨询