news 2026/9/25 10:28:06

基于 PaddleSpeech 的 FastSpeech2 + AISHELL-3 语音克隆(Voice Cloning)全流程实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于 PaddleSpeech 的 FastSpeech2 + AISHELL-3 语音克隆(Voice Cloning)全流程实战指南
  • 人工智能
  • 语音
  • 音频
  • 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
点击查看免费下载

本篇技术指南以 PaddleSpeech 仓库中 examples/aishell3/vc1 的官方示例为主线,系统讲解如何基于FastSpeech2 声学模型 + AISHELL-3 中文多说话人数据集搭建一套可复现的语音克隆(Voice Cloning)流水线。读完本文,你将掌握 GE2E 说话人编码器、FastSpeech2 合成器、Parallel WaveGAN 声码器三阶段级联的完整技术原理,能够独立完成数据集准备、说话人 Embedding 生成、预处理、模型训练、批量合成与零样本(zero-shot)语音克隆推理的全部命令行操作,并深入理解conf/default.yaml中每个关键配置项的物理含义。

任务背景:从说话人验证迁移到多说话人 TTS

语音克隆的目标是:仅凭一段参考音频(Reference Audio),即可让 TTS 系统"模仿"该说话人的音色生成任意文本的语音。vc1 示例采用了 《Transfer Learning from Speaker Verification to Multispeaker Text-To-Speech Synthesis》 论文提出的经典方案,将任务拆解为三个独立训练、再级联推理的模块:

  1. Speaker Encoder(说话人编码器):以说话人验证(Speaker Verification)为训练任务,用 GE2E(Generalized End-to-End Loss)损失训练一个编码器,把任意一段语音映射为一个固定维度的说话人 Embedding。训练该编码器不需要文本标注,因此可以无限制地堆叠大量多说话人数据集,例如 examples/other/ge2e 示例中使用的 Librispeech-other-500、VoxCeleb、VoxCeleb2、aidatatang-200zh、magicdata 等。
  2. Synthesizer(合成器):使用训练好的说话人编码器为 AISHELL-3 中的每个句子生成说话人 Embedding,并将其作为 FastSpeech2 的额外输入,与编码器输出拼接(concat)后送入解码器,从而让声学模型感知"是谁在说话"。
  3. Vocoder(声码器):使用 Parallel WaveGAN(PWG)将 FastSpeech2 输出的梅尔频谱还原为可听的波形,其训练与推理流程见 examples/aishell3/voc1。

三阶段中,说话人编码器与声码器均使用预训练权重(可直接下载),本示例真正需要训练的部分只有 FastSpeech2 合成器本身。

环境与数据集准备

AISHELL-3 数据集下载与解压

从 AISHELL-3 官网下载数据集后解压到~/datasets,得到目录~/datasets/data_aishell3,其中包含train、dev、test三个子集的 wav 音频与对应文本标注。AISHELL-3 是一个约 880 名中文说话人、88000+ 条话语的多说话人中文语料库,是本示例的训练数据来源。

MFA 强制对齐结果

FastSpeech2 属于时长预测型(duration-based)非自回归 TTS,训练需要每个音素(phone)的时长标注。vc1 使用 Montreal Forced Aligner(MFA)完成音素级别的强制对齐,两种获取方式任选其一:

  • 直接下载官方提供的对齐结果aishell3_alignment_tone.tar.gz(MFA 2.x 产物,含声调信息),解压后目录名为aishell3_alignment_tone;
  • 参考 examples/other/mfa 示例自行训练 MFA 模型(当前使用 MFA 1.x)生成对齐结果。

注意:run.sh、preprocess.sh中均硬编码了./aishell3_alignment_tone这一相对路径,请将对齐结果解压到 vc1 示例目录下,保持与脚本约定一致。

预训练 GE2E 说话人编码器

下载官方预训练的 GE2E 模型压缩包ge2e_ckpt_0.3.zip并解压。该模型即 examples/other/ge2e 示例的训练产物。在 run.sh 中默认约定:

# 不含 ".pdparams" 后缀,用于生成 speaker embedding ge2e_ckpt_path=./ge2e_ckpt_0.3/step-3000000 # 包含 ".pdparams" 后缀,用于 voice cloning 推理 ge2e_params_path=${ge2e_ckpt_path}.pdparams

从 ge2e 推理源码 可以看到,paddle.load(weights_fpath + ".pdparams")加载权重后,使用LSTMSpeakerEncoder对每个 utterance 输出256 维说话人 Embedding(模型配置为n_mels=40、num_layers=3、hidden_size=256、output_size=256)。

预训练 Parallel WaveGAN 声码器

下载pwg_aishell3_ckpt_0.5.zip并解压,得到以下文件:

pwg_aishell3_ckpt_0.5 ├── default.yaml # 训练 parallel wavegan 时的默认配置 ├── feats_stats.npy # 训练时用于归一化频谱的统计量 └── snapshot_iter_1000000.pdz # parallel wavegan 生成器参数

该声码器用于最终的波形合成阶段,全程无需再训练。

快速开始:一条命令跑通全流程

run.sh是 vc1 示例的总入口,它通过source ${MAIN_ROOT}/utils/parse_options.sh支持--stage/--stop-stage参数控制执行阶段。四个阶段的划分与默认参数如下(见 run.sh):

阶段内容默认命令
stage 0数据预处理(生成说话人 Embedding、时长、特征、归一化)./local/preprocess.sh ${conf_path} ${ge2e_ckpt_path}
stage 1训练 FastSpeech2./local/train.sh ${conf_path} ${train_output_path}
stage 2基于metadata.jsonl批量合成测试集波形./local/synthesize.sh ${conf_path} ${train_output_path} ${ckpt_name}
stage 3语音克隆推理(输入参考音频目录,输出克隆语音)./local/voice_cloning.sh ${conf_path} ${train_output_path} ${ckpt_name} ${ge2e_params_path} ${ref_audio_dir}

整体运行:

./run.sh

只跑数据预处理阶段:

./run.sh --stage 0 --stop-stage 0

脚本默认变量还包括:gpus=0,1(双卡)、conf_path=conf/default.yaml、train_output_path=exp/default、ckpt_name=snapshot_iter_482.pdz(在 stage 2/3 前请替换为你实际训练得到的 checkpoint 文件名)。

数据预处理详解:五步流水线与 dump 目录

./local/preprocess.sh(见 preprocess.sh)内部实际由 5 个子阶段组成,比普通 TTS(如 tts3)多了一步 GE2E 说话人 Embedding 生成,这也是语音克隆任务的核心差异所在:

① 生成说话人 Embedding(stage 0)

python3 ${MAIN_ROOT}/paddlespeech/vector/exps/ge2e/inference.py \ --input=~/datasets/data_aishell3/train/wav/ \ --output=dump/embed \ --checkpoint_path=${ge2e_ckpt_path}

该命令遍历输入目录下所有.wav(--pattern默认*.wav),对每个音频先做 VAD 切分、梅尔频谱提取(40 维 mel),再经LSTMSpeakerEncoder.embed_utterance输出 256 维向量,以.npy格式保存到dump/embed,目录层级与 wav 文件完全一致。官方示例中仅对train集生成 embedding,dev/test集在后续训练与合成阶段会实时从前端提取。

② 由 MFA 结果生成音素时长(stage 1)

python3 ${MAIN_ROOT}/utils/gen_duration_from_textgrid.py \ --inputdir=./aishell3_alignment_tone \ --output durations.txt \ --config=${config_path}

将 MFA 的 TextGrid 对齐结果转换为durations.txt,作为 FastSpeech2 时长预测器的监督信号。

③ 特征提取(stage 2)

python3 ${BIN_DIR}/preprocess.py \ --dataset=aishell3 \ --rootdir=~/datasets/data_aishell3/ \ --dumpdir=dump \ --dur-file=durations.txt \ --config=${config_path} \ --num-cpu=20 \ --cut-sil=True \ --spk_emb_dir=dump/embed

关键参数:--cut-sil=True会切除句首句尾静音;--spk_emb_dir=dump/embed指定上一步生成的说话人 Embedding 目录,使其与频谱、基频(pitch)、能量(energy)特征一同进入数据管线。

④ 统计量计算(stage 3)

python3 ${MAIN_ROOT}/utils/compute_statistics.py \ --metadata=dump/train/raw/metadata.jsonl \ --field-name="speech" # 同理对 "pitch"、"energy" 字段各执行一次

仅基于train集计算三个特征的均值/标准差,分别输出dump/train/speech_stats.npy、pitch_stats.npy、energy_stats.npy,供后续归一化使用(dev/test集也复用 train 的统计量,避免信息泄漏)。

⑤ 归一化与词典构建(stage 4)

对train、dev、test三个子集分别调用${BIN_DIR}/normalize.py,使用 train 的统计量完成特征归一化,同时生成dump/phone_id_map.txt(音素词典)与dump/speaker_id_map.txt(说话人词典)。

预处理完成后,当前目录下生成完整的dump文件夹,结构如下:

dump ├── dev │ ├── norm # 归一化后的特征 │ └── raw # 原始 speech/pitch/energy 特征 ├── embed # 每个句子的说话人 embedding(.npy) │ ├── SSB0005 │ ├── SSB0009 │ └── ... ├── phone_id_map.txt # 音素 -> id 映射 ├── speaker_id_map.txt# 说话人 -> id 映射 ├── test │ ├── norm │ └── raw └── train ├── energy_stats.npy ├── norm ├── pitch_stats.npy ├── raw └── speech_stats.npy

每个子目录(train/dev/test)下都有一份表格式文件metadata.jsonl,每一行记录一条话语的:phones(音素序列)、text_lengths、speech_lengths、durations(时长)、speech 特征路径、pitch 特征路径、energy 特征路径、speaker、id,是后续训练与合成的数据索引。

FastSpeech2 模型训练

训练入口与语音克隆开关

./local/train.sh调用${BIN_DIR}/train.py(即paddlespeech/t2s/exps/fastspeech2/train.py):

CUDA_VISIBLE_DEVICES=${gpus} ./local/train.sh ${conf_path} ${train_output_path}

脚本内容(见 train.sh)关键在最后两个参数:

python3 ${BIN_DIR}/train.py \ --train-metadata=dump/train/norm/metadata.jsonl \ --dev-metadata=dump/dev/norm/metadata.jsonl \ --config=${config_path} \ --output-dir=${train_output_path} \ --ngpu=2 \ --phones-dict=dump/phone_id_map.txt \ --voice-cloning=True

与普通多说话人 TTS(tts3)相比,唯一区别是设置--voice-cloning=True。从 train.py 源码 可以看到:开启该开关后,collate 函数切换为fastspeech2_multi_spk_batch_fn,模型将把说话人 Embedding(而非稀疏的 speaker id)作为条件输入,这正是"零样本/任意新说话人"能力的来源——推理时任何人的 Embedding 都可以直接送入模型。

配置详解:conf/default.yaml

训练与特征提取共用一份配置(见 conf/default.yaml),各区块含义如下:

特征提取设置(FEATURE EXTRACTION SETTING)

参数默认值含义
fs24000采样率(Hz),PWG 声码器输出也以此为采样率
n_fft2048FFT 大小(采样点数)
n_shift300帧移(采样点数),约 12.5ms
win_length1200窗长(采样点数),约 50ms
window"hann"窗函数类型
fmin/fmax80 / 7600Mel 滤波器组最小/最大频率(Hz)
n_mels80Mel 滤波器组个数
f0min/f0max80 / 400基频(pitch)提取的上下限(Hz)

数据与模型设置

  • 数据:batch_size: 64、num_workers: 2。
  • 模型(model区块)核心结构参数:adim: 384(注意力维度)、aheads: 2(注意力头数)、elayers: 4 / eunits: 1536(编码器层数与 FFN 单元数)、dlayers: 4 / dunits: 1536(解码器层数与 FFN 单元数)、positionwise_layer_type: conv1d(位置前馈层为卷积)及positionwise_conv_kernel_size: 3。
  • 预测器参数:时长预测器duration_predictor_layers: 2 / chans: 256 / kernel_size: 3;基频预测器pitch_predictor_layers: 5 / chans: 256 / kernel_size: 5 / dropout: 0.5;能量预测器energy_predictor_layers: 2 / chans: 256 / kernel_size: 3 / dropout: 0.5。FastSpeech2 通过这三个预测器在非自回归解码时对齐文本与频谱长度。
  • PostNet:postnet_layers: 5、postnet_filts: 5、postnet_chans: 256,对解码输出做残差精修。
  • 语音克隆关键参数:spk_embed_dim: 256(与 GE2E 输出维度一致)、spk_embed_integration_type: concat(说话人 Embedding 以拼接方式与编码器输出融合),对应源码中voice_cloning.py将 256 维spk_emb直接传入声学模型推理。
  • 正则化:Transformer 编码器/解码器的 dropout 均为 0.2;encoder_normalize_before/decoder_normalize_before为 True(层归一化置于子层之前);初始化方式init_type: xavier_uniform。

优化器与训练设置

  • optimizer: optim: adam, learning_rate: 0.001;
  • updater.use_masking: True(损失计算对 padding 部分做掩码);
  • max_epoch: 200、num_snapshots: 5(最多保留 5 个快照);
  • seed: 10086(随机种子,保证可复现)。

训练完成后,checkpoint 保存在${train_output_path}/checkpoints/目录下,run.sh中的ckpt_name即指向其中的某个snapshot_iter_*.pdz文件。

批量合成:从 metadata.jsonl 到波形

./local/synthesize.sh调用${BIN_DIR}/../synthesize.py(即paddlespeech/t2s/exps/synthesize.py),作用是根据测试集的metadata.jsonl批量合成语音:

CUDA_VISIBLE_DEVICES=${gpus} ./local/synthesize.sh ${conf_path} ${train_output_path} ${ckpt_name}

脚本内容(见 synthesize.sh):

python3 ${BIN_DIR}/../synthesize.py \ --am=fastspeech2_aishell3 \ --am_config=${config_path} \ --am_ckpt=${train_output_path}/checkpoints/${ckpt_name} \ --am_stat=dump/train/speech_stats.npy \ --voc=pwgan_aishell3 \ --voc_config=pwg_aishell3_ckpt_0.5/default.yaml \ --voc_ckpt=pwg_aishell3_ckpt_0.5/snapshot_iter_1000000.pdz \ --voc_stat=pwg_aishell3_ckpt_0.5/feats_stats.npy \ --test_metadata=dump/test/norm/metadata.jsonl \ --output_dir=${train_output_path}/test \ --phones_dict=dump/phone_id_map.txt \ --speaker_dict=dump/speaker_id_map.txt \ --voice-cloning=True

该步骤同样需要--voice-cloning=True:合成时模型从测试集音频实时提取说话人 Embedding 作为条件,输出波形保存到${train_output_path}/test/。--am_ckpt指向训练得到的 FastSpeech2 快照,--voc_*指向预训练的 PWG 声码器及其频谱归一化统计量。

语音克隆推理:用参考音频克隆任意说话人

推理入口

语音克隆是 vc1 的最终目的:给定若干参考音频(./ref_audio),模型提取其中的音色并合成指定文本。假设参考音频目录结构为:

ref_audio ├── 001238.wav ├── LJ015-0254.wav └── audio_self_test.mp3

执行:

CUDA_VISIBLE_DEVICES=${gpus} ./local/voice_cloning.sh ${conf_path} ${train_output_path} ${ckpt_name} ${ge2e_params_path} ${ref_audio_dir}

脚本内容(见 voice_cloning.sh)默认合成文本为"凯莫瑞安联合体的经济崩溃迫在眉睫。",输出到${train_output_path}/vc_syn/,每个参考音频对应一个${utt_id}.wav。

底层实现剖析

voice_cloning.sh调用paddlespeech/t2s/exps/voice_cloning.py(见 voice_cloning.py),其推理链路可拆解为四步:

  1. 说话人 Embedding 提取:默认使用 GE2E 编码器——SpeakerVerificationPreprocessor对参考音频做 16kHz 重采样、VAD 预处理与 40 维 mel 部分片段提取,再由LSTMSpeakerEncoder.embed_utterance得到 256 维spk_emb(对应--ge2e_params_path加载的参数)。源码同时预留了--use_ecapa开关,可切换为 ECAPA-TDNN 说话人编码器(经VectorExecutor调用)。
  2. 文本前端:Frontend(phone_vocab_path=args.phones_dict)将输入文本转为音素 id 序列(phone_ids),支持中文 g2p。
  3. 声学模型推理:get_am_inference(am="fastspeech2_aishell3", ...)加载 FastSpeech2,am_inference(phone_ids, spk_emb=spk_emb)以"音素序列 + 说话人 Embedding"为输入,输出梅尔频谱。
  4. 声码器推理:voc_inference(...)用 PWG 将频谱还原为波形,以am_config.fs(24000Hz)为采样率写出 wav。

推理时声学模型对 Embedding 完全开放——无论参考音频来自哪个说话人(甚至训练集之外的说话人),模型都能依据该 Embedding 合成对应音色的语音,这正是零样本语音克隆的核心机制。

预训练模型与效果

官方提供了 vc1 任务的预训练 FastSpeech2 模型fastspeech2_nosil_aishell3_vc1_ckpt_0.5.zip,解压后包含:

fastspeech2_nosil_aishell3_ckpt_vc1_0.5 ├── default.yaml # 训练 fastspeech2 的默认配置 ├── phone_id_map.txt # 音素词典(训练时生成) ├── snapshot_iter_96400.pdz # 模型参数与优化器状态 └── speech_stats.npy # 频谱归一化统计量

注意:语音克隆模式下不需要speaker_id_map.txt(说话人词典),因为说话人信息由 GE2E 的连续 Embedding 承载,而非离散 id。

官方给出的参考训练结果如下(来自 README):

ModelStepeval/losseval/l1_losseval/duration_losseval/pitch_losseval/energy_loss
default2(gpu) x 964000.996990.620130.0530570.119540.20426

其中duration_loss、pitch_loss、energy_loss分别对应 FastSpeech2 三个预测器的监督损失,l1_loss为频谱重构损失,可在训练日志中对照监控训练是否收敛。

小结与延伸

vc1 示例完整呈现了"说话人验证迁移到 TTS"的工程化实现:GE2E 提供可迁移的说话人表征,FastSpeech2 借助spk_embed条件输入实现多说话人乃至零样本合成,PWG 负责高质量波形还原。若需继续深入,可依次阅读:

  • 说话人编码器训练:examples/other/ge2e
  • 标准多说话人 TTS(无语音克隆):examples/aishell3/tts3
  • 声码器训练:examples/aishell3/voc1
  • 语音克隆推理核心代码:voice_cloning.py

  • 人工智能
  • 语音
  • 音频
  • 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
点击查看免费下载
上一篇:如何用茉莉花插件实现Zotero中文文献管理效率翻倍:终极解决方案
下一篇:GTA5线上小助手终极指南:免费开源工具轻松称霸洛圣都

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

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

Suricata入侵检测毕设全解析:从架构原理到iptables联动封禁

简介:网络入侵检测系统(IDS)是安全防御的基础组件,其核心价值不止于被动告警,更在于形成从检测到响应的闭环。Suricata作为高性能IDS引擎,通过多线程抓包、协议解析与规则匹配,将原始流量转化为…

作者头像 李华
网站建设 2026/9/25 10:26:18

深入解析AX88179A免驱USB千兆网卡芯片:从原理到量产

几年前我做了一批USB 3.0转千兆网卡的模块,最初选型时第一个想到的芯片就是AX88181A的后续型号AX88179A,原因只有一个:它能让我少接无数通“为什么插上没反应”的售后电话。说实话,做硬件的人都知道,一颗芯片只要能做到…

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

Robomongo 内置 Google Test 1.8.1:C++ 单元测试框架集成与实战指南

数据库客户端桌面应用 【免费下载链接】robomongo Native cross-platform MongoDB management tool 项目地址: https://gitcode.com/gh_mirrors/ro/robomongo 点击查看 免费下载 Google Test(googletest)是 Google 开源的 C 测试框架&#x…

作者头像 李华
网站建设 2026/9/25 10:16:41

313MB加密包分析:揪出静默上传暗门

最近接手了一个样本分析任务,拿到手上的样本是一个313MB的加密压缩包。单从文件名来看平平无奇,后缀是rar,备注写着“产品资料备份v3.2”,但当同事告诉我这个包是从一台中了招的内部服务器上导出来的,而且文件体积异常…

作者头像 李华