PaddleSpeech TTS 批量合成工具 `synthesize` 完全指南:从元数据到 Waveform 的声学模型与声码器合成管线
PaddleSpeech TTS 批量合成工具synthesize完全指南从元数据到 Waveform 的声学模型与声码器合成管线【免费下载链接】PaddleSpeechEasy-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.t2s.exps.synthesize是飞桨 PaddleSpeech 文本转语音TTS模块中基于测试元数据metadata.jsonl批量合成波形的核心命令行工具。它把「声学模型Acoustic ModelAM 神经声码器Vocoder」两阶段合成管线封装为一个可直接运行的 Python 入口读取预处理阶段生成的归一化特征元数据依次推理出梅尔频谱再由声码器还原为 16/24kHz 采样率的.wav音频并逐条打印合成速度与实时率RTF。阅读本文后你将掌握synthesize.py的全部命令行参数、支持的声学模型与声码器组合、配置文件与统计文件的作用、多说话人与语音克隆voice cloning的接入方式以及如何基于仓库示例脚本完成一次真实的批量合成。本文对应 Sphinx 自动生成文档 paddlespeech.t2s.exps.synthesize.rst该 RST 通过automodule指令挂载模块文档其全部技术内容源自 synthesize.py 及其依赖的 syn_utils.py。工具定位合成阶段在 TTS 全流程中的位置在 PaddleSpeech 的 TTS 示例如 examples/csmsc/tts3中一个完整的实验流程是数据预处理preprocess将音频切分、提取特征mel、pitch、energy划分 train/dev/test 三个子集每个子集内含raw与norm两个目录并生成音素词典phone_id_map.txt、说话人词典speaker_id_map.txt以及归一化统计量dump/train/*_stats.npy。模型训练train训练声学模型产出 checkpoint.pdz。合成synthesize本文主角用训练好的声学模型 预训练声码器把dump/test/norm/metadata.jsonl逐条转成波形。推理inference将动图模型转静图后用 Paddle Inference 运行。metadata.jsonl是合成的输入它是一张「表」每一行包含该条目的 phone 序列、text_lengths、speech_lengths、durations、speech/pitch/energy 特征路径、说话人 id 与utt_id等信息见 README。synthesize.py正是消费这份元数据来逐条复现测试集音频。核心工作流evaluate()的三段式管线synthesize.py的入口是main()它先通过parse_args()解析参数再根据--ngpu/--nxpu/--nnpu/--nmlu决定设备paddle.set_device四者全为 0 时回退 CPU最后调用evaluate(args)执行合成主逻辑synthesize.py#L32-L139。evaluate()的核心流程可分四步① 加载元数据与配置with jsonlines.open(args.test_metadata, r) as reader: test_metadata list(reader) with open(args.am_config) as f: am_config CfgNode(yaml.safe_load(f)) with open(args.voc_config) as f: voc_config CfgNode(yaml.safe_load(f))配置统一用yacs.config.CfgNode封装因此 YAML 中除model外的顶层字段如fs、n_mels也可以直接以属性方式访问例如计算 RTF 时读取am_config.fs。② 构造声学模型推理器am_name args.am[:args.am.rindex(_)] # 如 fastspeech2 am_dataset args.am[args.am.rindex(_) 1:] # 如 csmsc am_inference get_am_inference(amargs.am, am_configam_config, ...)模型名采用{model_name}_{dataset}约定下划线切分后既用于动态导入模型类也用于决定元数据字段与推理入参见下文模型分支。③ 构造测试数据集与声码器get_test_dataset()syn_utils.py#L152-L191依据am_name与数据集/语音克隆开关决定DataTable读取的字段get_voc_inference()syn_utils.py#L445-L485负责加载声码器生成器、去掉 weight norm、装载 Z-Score 归一化器并包成推理类。④ 逐条推理并写盘for datum in test_dataset: utt_id datum[utt_id] with timer() as t: with paddle.no_grad(): mel am_inference(phone_ids, ...) # 声学模型 → mel wav voc_inference(mel) # 声码器 → waveform ... sf.write(str(output_dir / (utt_id .wav)), wav, samplerateam_config.fs)每条音频的耗时、Hz每秒采样点数、RTFfs / speed会打印到终端全部结束后再输出整体generation speed与平均 RTF。timer来自第三方timer包soundfile负责按am_config.fs配置文件里的采样率写盘。声学模型分支FastSpeech2 / SpeedySpeech / Tacotron2 / DiffSingerevaluate()内按am_name分派不同的推理入参synthesize.py#L88-L124这是理解合成语义的关键声学模型输入字段推理调用说明fastspeech2textphone idsam_inference(phone_ids, spk_id..., spk_emb...)支持多说话人spk_id与语音克隆spk_embspeedyspeechphones、tonesam_inference(phone_ids, tone_ids)需要--tones_dict声调词典tacotron2textam_inference(phone_ids, spk_emb...)仅语音克隆时带spk_embdiffsingertext、note、note_dur、is_sluram_inference(phone_ids, note..., note_dur..., is_slur..., get_mel_fs2False)歌声合成SVS专用其中 FastSpeech2/Tacotron2 的多说话人逻辑由--voice-cloning与元数据字段联合驱动if args.voice_cloning and spk_emb in datum: spk_emb paddle.to_tensor(np.load(datum[spk_emb])) elif spk_id in datum: spk_id paddle.to_tensor(datum[spk_id])即语音克隆模式下优先加载预提取的说话人 embeddingspk_emb文件路径存于元数据中否则若元数据带spk_id多说话人数据集如 aishell3/vctk则走说话人 id 条件。DiffSinger 分支值得一提get_mel_fs2False表示 mel 由扩散diffusion解码器生成而非 FastSpeech2 主干--speech_stretchs参数传入 mel 频谱的最小/最大值文件dump/train/speech_stretchs.npy在get_am_inference()中加载为spec_min/spec_max张量并注入模型syn_utils.py#L407-L419。命令行参数全解声学模型、声码器与运行环境parse_args()synthesize.py#L142-L254)定义了完整的参数体系可分为三类声学模型AM参数参数默认值说明--amfastspeech2_csmsc声学模型类型格式{model}_{dataset}可选值见下方列表--am_configNone声学模型 YAML 配置如default.yaml--am_ckptNone声学模型 checkpoint.pdz加载其中main_params--am_statNone训练时用于归一化频谱的均值/标准差.npy--phones_dictNone音素词典phone 词汇表决定vocab_size--tones_dictNone声调词典SpeedySpeech 等需要决定tone_size--speaker_dictNone说话人 id 映射文件多说话人模型需要决定spk_num--voice-cloningFalse是否以语音克隆方式推理str2bool类型--speech_stretchsNonemel 频谱最小/最大值文件DiffSinger 专用--am的完整可选值来自源码choicesspeedyspeech_csmsc、fastspeech2_csmsc、fastspeech2_ljspeech、fastspeech2_aishell3、fastspeech2_vctk、tacotron2_csmsc、tacotron2_ljspeech、tacotron2_aishell3、fastspeech2_mix、fastspeech2_canton、diffsinger_opencpop。注意_mix对应中英混合模型、_canton对应粤语模型。声码器Vocoder参数参数默认值说明--vocpwgan_csmsc声码器类型格式{model}_{dataset}--voc_configNone声码器 YAML 配置generator_params/model--voc_ckptNone声码器 checkpoint.pdz--voc_statNone声码器训练时的归一化统计.npy--voc完整可选值pwgan_csmsc、pwgan_ljspeech、pwgan_aishell3、pwgan_vctk、mb_melgan_csmsc、wavernn_csmsc、hifigan_csmsc、hifigan_ljspeech、hifigan_aishell3、hifigan_vctk、style_melgan_csmsc、pwgan_opencpop、hifigan_opencpop。从 syn_utils.py#L445-L485 可以看到声码器加载细节除wavernn外统一读取voc_config[generator_params]实例化生成器从 checkpoint 的generator_params键恢复权重并调用remove_weight_norm()WaveRNN 则走voc_config[model]与main_params。此外源码对 NPU 环境做了适配当paddle.get_device()以npu开头时会将 pad 模式强制设为constant以保证算子兼容。环境与其他参数参数默认值说明--ngpu1GPU 数量0时使用 GPU--nxpu0XPU 数量需ngpu0时生效--nnpu0NPU 数量需ngpu0时生效--nmlu0MLU 数量需ngpu0时生效--test_metadata必填测试集元数据metadata.jsonl--output_dir必填输出目录合成的{utt_id}.wav写入此处设备选择逻辑在main()中synthesize.py#L257-L275按 gpu → xpu → npu → mlu → cpu 的优先级设置 Paddle 设备因此一条命令即可在不同硬件上运行。配置文件与统计文件合成正确性的三个支点声学模型配置如--am_config以 examples/csmsc/tts3/conf/default.yaml 为例关键字段直接决定推理行为特征域fs: 24000采样率同时用于 RTF 计算与写盘、n_fft: 2048、n_shift: 300、win_length: 1200、fmin/fmax: 80/7600、n_mels: 80mel 维度对应odim。模型域modeladim注意力维度、elayers/dlayers编解码层数、eunits/dunits前馈维度、duration_predictor_*时长预测器、pitch_predictor_*、energy_predictor_*、postnet_*等。get_am_inference()中 FastSpeech2 通过am_class(idimvocab_size, odimodim, spk_numspk_num, **am_config[model])实例化syn_utils.py#L404-L406odim正是取自am_config.n_mels。归一化统计--am_stat/--voc_stat这两个.npy文件各含(mean, std)两个数组代码通过ZScore归一化器在推理类内部完成「mel 反归一化」denorm。声学模型的am_stat对应训练时dump/train/speech_stats.npy声码器的voc_stat对应其训练时的feats_stats.npy。词典文件--phones_dict/--tones_dict/--speaker_dict三者均为每行一个条目的文本文件。get_am_inference()中通过统计行数得到vocab_size、tone_size、spk_num作为模型输入维度/说话人数量的依据syn_utils.py#L385-L397。示例实战以 CSMSC 与 AISHELL3 为例单说话人FastSpeech2 多种声码器CSMSCexamples/csmsc/tts3/local/synthesize.sh 展示了同一声学模型搭配 5 种声码器的合成方式stage 0–4 分别对应 pwgan / mb_melgan / style_melgan / hifigan / wavernnFLAGS_allocator_strategynaive_best_fit \ FLAGS_fraction_of_gpu_memory_to_use0.01 \ python3 ${BIN_DIR}/../synthesize.py \ --amfastspeech2_csmsc \ --am_config${config_path} \ --am_ckpt${train_output_path}/checkpoints/${ckpt_name} \ --am_statdump/train/speech_stats.npy \ --vocpwgan_csmsc \ --voc_configpwg_baker_ckpt_0.4/pwg_default.yaml \ --voc_ckptpwg_baker_ckpt_0.4/pwg_snapshot_iter_400000.pdz \ --voc_statpwg_baker_ckpt_0.4/pwg_stats.npy \ --test_metadatadump/test/norm/metadata.jsonl \ --output_dir${train_output_path}/test \ --phones_dictdump/phone_id_map.txt脚本由run.sh以./local/synthesize.sh ${conf_path} ${train_output_path} ${ckpt_name} ${stage}的形式调用。其中FLAGS_allocator_strategynaive_best_fit与FLAGS_fraction_of_gpu_memory_to_use0.01是 Paddle 内存分配策略的环境变量用于压低推理时的显存占用。多说话人FastSpeech2_aishell3 说话人词典examples/aishell3/tts3/local/synthesize.sh 与单说话人版的差异仅在于--amfastspeech2_aishell3并追加--speaker_dictdump/speaker_id_map.txt。此时get_test_dataset()检测到am_dataset in {aishell3,vctk,mix,canton}且speaker_dict非空会自动给字段列表追加spk_id推理时从元数据取说话人 id 传入模型。歌声合成DiffSinger_opencpopexamples/opencpop/svs1/local/synthesize.sh 展示了 SVS 场景python3 ${BIN_DIR}/../synthesize.py \ --amdiffsinger_opencpop \ --am_config${config_path} \ --am_ckpt${train_output_path}/checkpoints/${ckpt_name} \ --am_statdump/train/speech_stats.npy \ --vocpwgan_opencpop \ --voc_configpwgan_opencpop_ckpt_1.4.0/default.yaml \ --voc_ckptpwgan_opencpop_ckpt_1.4.0/snapshot_iter_100000.pdz \ --voc_statpwgan_opencpop_ckpt_1.4.0/feats_stats.npy \ --test_metadatadump/test/norm/metadata.jsonl \ --output_dir${train_output_path}/test \ --phones_dictdump/phone_id_map.txt \ --speech_stretchsdump/train/speech_stretchs.npy注意 DiffSinger 需要额外提供--speech_stretchs其元数据行必须包含note、note_dur、is_slur等歌声标注字段对应 syn_utils.py 中diffsinger的字段定义。与相邻合成入口的差异synthesize_e2e / inferencepaddlespeech.t2s.exps目录下存在多个功能互补的入口见 exps 目录synthesize.py本文主角输入是预处理产出的metadata.jsonl适合批量复现测试集/评估声学模型也是 examples 中synthesize.sh调用的目标。synthesize_e2e.py输入是普通文本文件每行utt_id sentence内部通过get_frontend()/run_frontend()实时完成文本前端text frontend→ phone ids 的转换再由动态图或静态图推理对应示例的synthesize_e2e.sh适合端到端合成任意句子。inference.py基于 Paddle Inference 静态图推理器get_predictor()/get_am_output()/get_voc_output()均封装在 syn_utils.py是模型部署形态的合成示例。三者共享syn_utils.py中的模型别名表model_aliassyn_utils.py#L48-L92该表把fastspeech2/speedyspeech/tacotron2/diffsinger/erniesat及pwgan/mb_melgan/style_melgan/hifigan/wavernn等名称动态映射到具体模型类这也是--am/--voc仅需字符串即可实例化模型的原因。运行前提与常见问题依赖需要paddlepaddle、yacs、jsonlines、soundfile、numpy、timer等合成时需source path.sh以正确设置PYTHONPATH与BIN_DIR示例脚本均基于此约定。文件对应关系--am_config/--am_ckpt/--am_stat/--phones_dict对应声学模型预训练包内的 4 个文件如 FastSpeech2 的default.yaml、snapshot_iter_76000.pdz、speech_stats.npy、phone_id_map.txt--voc_config/--voc_ckpt/--voc_stat对应声码器包内的 3 个文件见 README。设备切换XPU/NPU/MLU 均以「--ngpu0 对应数量参数 0」的方式启用四者全为 0 时使用 CPU。RTF 解读终端打印的RTF为合成耗时与音频时长之比RTF 1表示快于实时。该值受am_config.fs与单条音频大小共同影响适合作为批量合成的性能基线。禁用 DataLoader 日志evaluate()开头执行logging.getLogger(DataLoader).disabled True避免海量数据加载日志刷屏仅保留每条音频的合成进度输出。小结synthesize是 PaddleSpeech TTS 训练后评估与批量合成的标准入口它以metadata.jsonl为输入用「声学模型 声码器」组合在paddle.no_grad()下完成 mel 预测与波形还原支持 FastSpeech2 / SpeedySpeech / Tacotron2 / DiffSinger 四类声学模型与 PWGan / HiFiGAN / MelGAN / StyleMelGAN / WaveRNN 等声码器的任意组合并原生兼容 GPU / XPU / NPU / MLU / CPU 多硬件环境。结合 syn_utils.py 中的模型别名表与推理器封装你可以在此基础上进一步扩展新的模型组合或将合成能力迁移到静态图、ONNX 等部署形态对应inference.py、ort_predict.py等入口。【免费下载链接】PaddleSpeechEasy-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),仅供参考