news 2026/9/14 5:16:57

VCTK 多说话人语音合成实战:基于 fairseq S² 工具包的 Transformer TTS 全流程指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VCTK 多说话人语音合成实战:基于 fairseq S² 工具包的 Transformer TTS 全流程指南

VCTK 多说话人语音合成实战:基于 fairseq S² 工具包的 Transformer TTS 全流程指南

【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm

VCTK 是 open 的多说话人英语语音语料库,本指南基于 fairseq S²(Speech Synthesis)工具包,完整讲解从 VCTK 原始音频到 Transformer TTS 模型训练、推理与自动评估的端到端流程。读完本文你将掌握:音频 manifest 生成、基于信号处理的去噪与 VAD 清洗、基于 ASR 的 CER 样本过滤、log-Mel 特征提取与配置生成,以及 MCD/CER 等指标驱动的模型开发闭环。本文是 VCTK 示例文档 的深度扩展,与之配套的 LJSpeech 单说话人示例 与 Common Voice 示例 分别覆盖了单说话人与其他多说话人场景,可相互参照。

1. 任务概览:在 VCTK 上构建多说话人 TTS

VCTK(CSTR VCTK Corpus)是爱丁堡大学发布的 open 英语语音语料库,包含超过 100 位不同口音说话人的朗读语音,因此天然适合训练多说话人语音合成模型。fairseq S² 工具包(论文 arXiv:2109.06912,参见 speech_synthesis 总览)提供了完整的语音合成流水线:

  • 自回归(Transformer TTS)与非自回归(FastSpeech 2)模型;
  • 面向多说话人合成的 speaker embedding 支持;
  • 面向低质量控制数据(如众包语料)的去噪、VAD 等音频预处理;
  • 用于模型迭代的自动评估指标(ASR 的 WER/CER、信号级的 MCD/MSD、韵律相关的 F0 指标);
  • 与 S2T(语音到文本)一致的轻量数据配置格式(config.yaml+ TSV manifest)。

VCTK 示例的整体流水线如下,本文按此顺序展开:

VCTK 原始音频 │ get_vctk_audio_manifest ▼ 音频 manifest(train/dev/test 切分) │ denoise_and_vad_audio(可选清洗) ▼ 处理后的音频 manifest(含 SNR 列) │ ASR CER 过滤(可选,eval_asr) ▼ 保留的低 CER 样本 │ get_feature_manifest(--ipa-vocab --use-g2p) ▼ 特征 manifest + config.yaml + vocab.txt + speakers.txt │ fairseq-train --task text_to_speech ▼ Transformer TTS 模型 → 推理波形 → 自动评估(MCD / CER / F0)

2. 数据准备

2.1 下载数据、切分并生成音频 manifest

首先下载 VCTK 数据集,创建数据切分并生成音频 manifest:

python -m examples.speech_synthesis.preprocessing.get_vctk_audio_manifest \ --output-data-root ${AUDIO_DATA_ROOT} \ --output-manifest-root ${AUDIO_MANIFEST_ROOT}

这一步由 get_vctk_audio_manifest.py 实现,其内部逻辑可以从源码确认:

  • 基于torchaudio.datasets.VCTK读取数据集,--output-data-root(即-d)指向数据存放目录,--output-manifest-root(即-m)指向 manifest 输出目录;
  • 固定切分策略:全部样本先以--seed 1234(默认)打乱,然后划出--n-dev 50个 dev 样本与--n-test 100个 test 样本,其余全部归入 train,三个切分分别输出${split}.audio.tsvSPLITS = ["train", "dev", "test"]);
  • 每个样本的 manifest 记录五列:idaudio(wav 绝对路径,按说话人目录组织)、n_framestgt_textspeakersrc_text
  • 文本会经过normalize_text清洗:re.sub(r"[^a-zA-Z.?!,'\- ]", '', text),即仅保留英文字母、空格与常见标点,剔除多余字符。

提示:若需自定义切分规模,可调整--n-dev--n-test--seed;默认的 50/100 划分与文档中的结果表(Test MCD 3.4)对应。

2.2 使用信号处理去噪与 VAD 清洗音频

VCTK 作为多说话人语料,部分录音可能存在环境噪声或首尾静音。fairseq S² 提供基于信号处理(而非深度学习语音增强)的去噪 + VAD(语音活动检测)预处理脚本:

for SPLIT in dev test train; do python -m examples.speech_synthesis.preprocessing.denoise_and_vad_audio \ --audio-manifest ${AUDIO_MANIFEST_ROOT}/${SPLIT}.audio.tsv \ --output-dir ${PROCESSED_DATA_ROOT} \ --denoise --vad --vad-agg-level 3 done

该命令对应 denoise_and_vad_audio.py,运行后会:

  • ${PROCESSED_DATA_ROOT}下新建after_denoise/after_vad/两个子目录分别存放两阶段的产物;
  • 加载预训练语音增强模型master64()(来自preprocessing/denoiser,即 Demucs 系列模型)对音频去噪,并通过--dry-wet 0.01(默认)控制干湿信号线性插值比例,即保留 1% 原始信号以防止过度增强;
  • 使用 WebRTC VAD(依赖webrtcvad,需要pip install webrtcvad)裁剪首尾与长段静音,--vad-agg-level取值范围为 0–3,数值越大过滤越激进(文档示例用 3);
  • VAD 后会重新计算n_frames,并计算增强前后信号的 SNR 写入 manifest 新增的snr列;如果某样本 VAD 后长度小于MIN_T = 0.05秒(即不足 50ms 有效语音),会被直接跳过并打印 WARNING——这类"几乎无语音"的样本不应进入训练集;
  • 最终在${PROCESSED_DATA_ROOT}下生成与输入同名的新音频 TSV,其audio列指向处理后的文件路径,并新增一列 SNR(未做 VAD 处理的样本为 -1)。

需要说明的是,--device默认是cpu,去噪模型支持cpu | cuda;如果样本量较大,建议显式传--device cuda加速。

2.3 使用 CER 进行样本过滤

VCTK 语料中个别样本可能发音与标注文本不一致(噪声、口误、字幕错误等),会显著拉低 TTS 质量。文档给出的策略是用 ASR 的字符错误率(CER)做过滤,具体做法复用 LJSpeech 示例 的自动评估流程:

  1. 对参考(reference)音频跑 wav2vec 2.0 ASR,需要在get_eval_manifest中加--eval-target,使其评估对象是参考音频而非模型合成音频;
  2. eval_asr中加--err-unit char,把默认的 WER(词错误率)换成 CER(字符错误率)——由 eval_asr.py 源码可见,--err-unit支持wordchar两种单位,char模式下逐字符计算编辑距离;
  3. 示例级 CER 会保存为${EVAL_OUTPUT_ROOT}/uer_cer.${SPLIT}.tsv——从源码看该文件含三列idaudiouer,其中uer即 utterance error rate,取值保留 4 位小数。
# 先按 ljspeech_example.md 生成评估 manifest(eval-target 指向参考音频) python -m examples.speech_synthesis.evaluation.get_eval_manifest \ --generation-root ... --audio-manifest ${AUDIO_MANIFEST_ROOT}/${SPLIT}.audio.tsv \ --output-path ${EVAL_OUTPUT_ROOT}/eval_cer_${SPLIT}.tsv \ --eval-target --vocoder griffin_lim --sample-rate 22050 --audio-format flac # 计算字符级错误率 python -m examples.speech_synthesis.evaluation.eval_asr \ --audio-header syn --text-header text --err-unit char --split ${SPLIT} \ --w2v-ckpt ${WAV2VEC2_CHECKPOINT_PATH} --w2v-dict-dir ${WAV2VEC2_DICT_DIR} \ --raw-manifest ${EVAL_OUTPUT_ROOT}/eval_cer_${SPLIT}.tsv \ --asr-dir ${EVAL_OUTPUT_ROOT}/asr_cer

注意:ASR 模型通常在 16kHz 下工作,若原音频采样率不是 16kHz,需先在特征/波形阶段重采样(参见下文推理与评估章节的 16kHz 说明),否则eval_asr会在prepare_w2v_data中断言sr == sample_rate

2.4 提取 log-Mel 特征并生成数据配置

完成清洗与过滤后,提取 log-Mel 频谱特征、生成特征 manifest 与数据配置 YAML:

python -m examples.speech_synthesis.preprocessing.get_feature_manifest \ --audio-manifest-root ${PROCESSED_DATA_ROOT} \ --output-root ${FEATURE_MANIFEST_ROOT} \ --ipa-vocab --use-g2p \ --snr-threshold 15 \ --cer-threshold 0.1 --cer-tsv-path ${EVAL_OUTPUT_ROOT}/uer_cer.${SPLIT}.tsv

其中使用了音素输入--ipa-vocab --use-g2p),即先把文本转成 IPA 音素序列再进入模型;同时按文档设定进行样本过滤:SNR 阈值 15、CER 阈值 10%。这条命令对应 get_feature_manifest.py,其内部行为可从源码确认:

  • 特征提取:对每个样本做convert_waveform重采样(默认--sample-rate 22050,可加--normalize-volume做响度归一),然后提取 80 维 log-Mel 谱(logmelspec80),默认--win-length 1024--hop-length 256--n-fft 1024--n-mels 80--f-min 20--f-max 8000;特征打包为logmelspec80.zip,同时计算全局 CMVN 统计量gcmvn_stats.npz用于特征归一化;
  • 样本过滤--snr-threshold 15表示丢弃snr低于 15 的样本;--cer-threshold 0.1结合--cer-tsv-path丢弃 CER 高于 10% 的样本(源码会从 CER TSV 读入每个样本的uer并与阈值比较);
  • 文本归一化:在 IPA 模式下,normalized_utt = ipa_phonemize(normalized_utt, lang="en-us", use_g2p=True),即通过 g2p 工具把英文文本转成 IPA 音素串(默认--lang en-us);
  • 产物:为每个 split 生成${split}.tsv特征 manifest(含id/audio/n_frames/tgt_text/speaker/src_text列)、vocab.txt(按词频排序的音素词典)、speakers.txt(说话人列表,多说话人时 config 中自动写入speaker_set_filename)、以及config.yaml(内含sample_ratefeatures块的完整声学参数,如n_melsn_fftwindow_fn: hannwin_len_t/hop_len_t等,CMVN 类型为global)。

说明:--cer-threshold仅在--cer-tsv-path存在且文件有效时才生效;若无需 CER 过滤可省略这两个参数。另外,若样本不足导致过滤后 train split 为空,get_feature_manifest会断言失败(assert "train" in args.splits与后续基于 train 生成词典的逻辑),因此阈值不宜过严。

3. 训练 Transformer TTS 模型

VCTK 示例的训练、推理与自动评估步骤与 LJSpeech 示例 完全一致,仅数据目录与特征配置不同。以自回归 Transformer TTS 为例:

fairseq-train ${FEATURE_MANIFEST_ROOT} --save-dir ${SAVE_DIR} \ --config-yaml config.yaml --train-subset train --valid-subset dev \ --num-workers 4 --max-tokens 30000 --max-update 200000 \ --task text_to_speech --criterion tacotron2 --arch tts_transformer \ --clip-norm 5.0 --n-frames-per-step 4 --bce-pos-weight 5.0 \ --dropout 0.1 --attention-dropout 0.1 --activation-dropout 0.1 \ --encoder-normalize-before --decoder-normalize-before \ --optimizer adam --lr 2e-3 --lr-scheduler inverse_sqrt --warmup-updates 4000 \ --seed 1 --update-freq 8 --eval-inference --best-checkpoint-metric mcd_loss

关键点解读:

  • --task text_to_speech是 S² 工具包的核心 TTS 任务,数据格式与 S2T 保持一致(config.yaml+ TSV manifest),训练时读config.yaml获取声学特征参数与说话人列表;
  • --criterion tacotron2+--arch tts_transformer组合对应 VCTK 结果表中的tts_transformer架构(54M 参数);--n-frames-per-step 4表示解码器每步预测 4 帧,--bce-pos-weight 5.0是停止符位置的 BCE 权重,二者是 Tacotron2 风格自回归解码的典型配置;
  • --update-freq 8表示以 8 个 mini-batch 累积一次梯度更新,用于在单卡上模拟 8 卡训练;文档明确提示多卡时需相应调整该值;
  • --eval-inference在验证时额外执行解码推理,--best-checkpoint-metric mcd_loss指定以验证集 MCD 损失作为选优指标,说明从训练一开始就按"合成质量"(而非单纯 loss)选 checkpoint。

训练收敛后,${SAVE_DIR}下会保存一系列checkpoint_*.pt,供下一步平均与推理使用。

4. 推理:平均 checkpoint 并合成波形

自回归 TTS 在解码质量上对 checkpoint 选择较敏感,官方推荐先平均最后 5 个 epoch 的 checkpoint,再用默认的 Griffin-Lim 声码器合成波形:

SPLIT=test CHECKPOINT_NAME=avg_last_5 CHECKPOINT_PATH=${SAVE_DIR}/checkpoint_${CHECKPOINT_NAME}.pt python scripts/average_checkpoints.py --inputs ${SAVE_DIR} \ --num-epoch-checkpoints 5 \ --output ${CHECKPOINT_PATH} python -m examples.speech_synthesis.generate_waveform ${FEATURE_MANIFEST_ROOT} \ --config-yaml config.yaml --gen-subset ${SPLIT} --task text_to_speech \ --path ${CHECKPOINT_PATH} --max-tokens 50000 --spec-bwd-max-iter 32 \ --dump-waveforms

运行细节(对应 generate_waveform.py 与 LJSpeech 文档说明):

  • 推理入口直接以特征 manifest 根目录为数据目录,--gen-subset test指定合成测试集;
  • --spec-bwd-max-iter 32控制 Griffin-Lim 相位恢复的最大迭代次数,32 是文档示例值,可视为合成质量与速度的折中;
  • --dump-waveforms会导出波形文件,同时输出特征、注意力图(attention plot)等可视化产物,全部落在${SAVE_DIR}/generate-${CHECKPOINT_NAME}-${SPLIT}目录下;
  • 若需要为自动评估重合成目标音频(即把参考音频也过一遍 vocoder,消除声码器带来的系统性失真),需加--dump-target
  • 当后续 WER/CER 评估使用 16kHz 的 ASR 模型时,可在generate_waveform.py上增加--output-sample-rate 16000直接输出 16kHz 波形,避免评估前再次重采样。

5. 自动评估

合成完成后,通过 S² 的评估子模块得到客观指标。评估的第一步是生成统一格式的评估清单(eval spec)——由 get_eval_manifest.py 实现,其输出的 TSV 包含id/syn/ref/text/speaker五列,其中syn指向合成音频,ref指向参考音频,后续所有指标脚本都消费这一文件:

python -m examples.speech_synthesis.evaluation.get_eval_manifest \ --generation-root ${SAVE_DIR}/generate-${CHECKPOINT_NAME}-${SPLIT} \ --audio-manifest ${AUDIO_MANIFEST_ROOT}/${SPLIT}.audio.tsv \ --output-path ${EVAL_OUTPUT_ROOT}/eval.tsv \ --vocoder griffin_lim --sample-rate 22050 --audio-format flac \ --use-resynthesized-target

参数含义(可从源码确认):--generation-root指向推理输出目录;--audio-manifest提供样本 id 与文本;--use-resynthesized-target表示用重合成的参考音频(*_tgt目录)作为 ref,而非原始录音,从而隔离声码器影响、纯粹衡量模型本身的声学预测误差;--vocoder griffin_lim--sample-rate 22050--audio-format flac决定目录命名flac_22050hz_griffin_lim下的文件查找路径。若使用 16kHz 的 ASR 模型做 WER/CER,这里应传--sample-rate 16000并对 eval 清单另存(如eval_16khz.tsv)。

5.1 WER/CER 指标(ASR 方案)

以 wav2vec 2.0 ASR 模型为例(模型与词典需按 wav2vec 示例自行准备):

python -m examples.speech_synthesis.evaluation.eval_asr \ --audio-header syn --text-header text --err-unit char --split ${SPLIT} \ --w2v-ckpt ${WAV2VEC2_CHECKPOINT_PATH} --w2v-dict-dir ${WAV2VEC2_DICT_DIR} \ --raw-manifest ${EVAL_OUTPUT_ROOT}/eval_16khz.tsv --asr-dir ${EVAL_OUTPUT_ROOT}/asr

该脚本(eval_asr.py)的工作流程:把 eval 清单转成 wav2vec 2.0 微调(audio_finetuning+ CTC)所需的 data 目录(含dict.ltr.txt${split}.tsv${split}.ltr),调用examples.speech_recognition.infer做识别,最后基于编辑距离计算逐样本错误率并输出uer_${err_unit}.${split}.tsv。文档在 VCTK 流程中使用--err-unit char(CER);若想按词评估可省略或显式传--err-unit word(WER)。需要留意:--audio-header syn--text-header text对应 eval 清单中的合成音频与文本列,而 CER 过滤流程中评估的是参考音频--eval-targetsyn列被替换为参考音频路径,参见 get_eval_manifest 源码)。

5.2 MCD / MSD 指标(信号级)

python -m examples.speech_synthesis.evaluation.eval_sp \ ${EVAL_OUTPUT_ROOT}/eval.tsv --mcd --msd

eval_sp.py 基于波形做动态时间规整(DTW)对齐后计算 Mel 倒谱失真(MCD)与 Mel 谱失真(MSD),并额外报告插入/删除帧比例;--show-bin可按参考时长分段(0–200/200–400/.../2000–4000 帧)输出分桶统计,便于定位长句短句的质量差异。VCTK 结果表中的 Test MCD 3.4 即来自该脚本。

5.3 F0 韵律指标

python -m examples.speech_synthesis.evaluation.eval_f0 \ ${EVAL_OUTPUT_ROOT}/eval.tsv --gpe --vde --ffe

eval_f0.py 提供基频(F0)层面的韵律评估:--gpe(基频生成错误率)、--vde(浊音判定错误率)、--ffe(F0 帧错误率),用于衡量合成语音的音高曲线与参考的吻合程度。

6. 复现结果与调参建议

VCTK 示例文档给出的官方复现结果为:

--archParamsTest MCDModel
tts_transformer54M3.4见原文档结果表下载链接

对比 LJSpeech 结果表(同架构 54M、Test MCD 3.8),VCTK 多说话人设置下 MCD 反而更低(3.4),说明该 Transformer TTS 对多说话人语料的声学拟合同样有效。若要复现该数字,需完整执行本文的流水线:

  1. 按 2.1 生成默认切分(50 dev / 100 test)的 manifest;
  2. 按 2.2 做去噪 + VAD(--vad-agg-level 3);
  3. 按 2.3 用 ASR 计算 CER 并保存uer_cer.*.tsv
  4. 按 2.4 以--ipa-vocab --use-g2p --snr-threshold 15 --cer-threshold 0.1提取特征(这组过滤阈值与结果表严格对应);
  5. 按第 3 节训练至 20 万步(单卡配--update-freq 8),按第 4 节平均最后 5 个 checkpoint 并合成 test 集;
  6. 按第 5 节用--use-resynthesized-target的 eval 清单计算 MCD。

实际复现时的常见调参点:VAD 激进等级(0–3)决定清洗强度,过高会裁掉短样本(触发MIN_T跳过警告),过低则残留静音;SNR/CER 阈值需结合语料质量权衡,阈值过严会显著减少训练样本;--update-freq需按 GPU 数量反比调整以保持等效 batch size;多说话人场景下确保config.yamlspeaker_set_filename(特征提取脚本在说话人数量 >1 时自动写入),训练与推理阶段均会据此区分说话人。

7. 小结

围绕 VCTK 多说话人 TTS,fairseq S² 提供了一条完整、可复现且指标可追踪的开发链路:get_vctk_audio_manifest负责数据切分,denoise_and_vad_audio负责粗质量音频清洗,eval_asr提供 CER 级样本过滤,get_feature_manifest输出音素 + log-Mel 特征及配置,fairseq-train训练 Transformer TTS,generate_waveform完成推理,eval_asr/eval_sp/eval_f0从 ASR、信号、韵律三个维度量化合成质量。对于想迁移到其他多说话人语料的读者,Common Voice 示例 提供了面向更大规模、更低质量众包语料的扩展思路,可直接对照本文流水线复用。

【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 5:16:34

锥形光纤COMSOL建模与模式传输优化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 5:16:28

Hadoop生态组件选型与集群搭建实战:从HDFS到Hive的全流程指南

距今为止,我经手搭建过的大数据平台不说上百套,也差不多覆盖了从传统制造业到互联网电商的多个行业场景。这个标题里最值得玩的其实是“排行榜”三个字——市面上讲Hadoop搭建的教程一抓一大把,但真正从企业级落地视角去捋清楚“该选哪些组件…

作者头像 李华
网站建设 2026/9/14 5:16:13

医院问诊微信小程序模板源码改造:前端开发完整指南

简介:面向开发者的医院问诊微信小程序前端模板源码,可用于快速搭建在线医疗咨询平台,覆盖预约挂号、即时问诊、健康资讯与个人中心等业务模块,适合前端工程师或小程序初学者借鉴实践。zip压缩包共508个文件、约894KB,主…

作者头像 李华
网站建设 2026/9/14 5:14:23

工单状态设计实战:状态定义、流转规则与踩坑全解析

工单状态这个东西,听起来就是四个字,好像谁都知道怎么回事,但你真去把一个工单系统的状态字段理清楚,会发现里面全是坑。不同部门对“处理中”的理解可能完全不一样,运营说的“待处理”和技术说的“待处理”根本是两码…

作者头像 李华
网站建设 2026/9/14 5:13:57

DeepSeek V4.1 Flash 部署实战:显存估算与 vLLM/SGLang 启动指南

这几天社区里关于 DeepSeek V4.1 Flash 的讨论明显多起来了,很多人已经在问同一件事:这个模型到底需要多大的显存,手里现有的卡能不能跑起来。我按 DeepSeek 近几代模型的发布规律和推理引擎的更新节奏判断,Flash 这种主打低延迟、…

作者头像 李华
网站建设 2026/9/14 5:13:26

BYOD安全治理实战:从设备合规到企业数据防泄漏

这几年只要在搞IT运维或者企业安全的同行,多多少少都被同一个问题追着跑过:员工拿着自己的手机、平板、笔记本电脑上班,用个人设备登企业邮箱、开在线文档、回客户消息,甚至高峰期还要连内网系统处理工单。大家管这种状态叫BYOD&a…

作者头像 李华