赞
踩
现在你可以拥有自己的AI歌手啦,在AiStudio中上传数据集后,按照下面的步骤进行操作,经过漫长的训练等待后(4~14天),就可以拥有一个不错的AI歌手了。项目魔改自PaddleSpeech中的Fastspeech2说话人模型,有兴趣的同好可以去阅读相关技术论文。
使用流程说明:
自己标注的数据应与Opencpop的格式相同
配置好后如需直接用我训练好的模型进行歌声合成,可跳转到第7步
因为Opencpop使用的标注和PaddleSpeech不兼容,需要转换为PaddleSpeech支持的格式
技术交流:项目使用过程中,如果遇到问题可以扫码加入艾梦的声动小群进行讨论。
PS: 本项目文件目录下的vocoder.ipynb文件用于训练声码器,声码器可以将声学模型生成的梅尔谱转换为波形文件
在Opencpop官网申请并下载数据集,将数据集上次到AIStudio上,不公开。
挂载在项目上后建议放在 work 目录下,放在 data 目录下次打开会不见
若使用自己的歌声数据集,应该先执行训练声码器项目
opencpop(数据文件夹)
├── wavs
├── 2001000001.wav
├── 2001000002.wav
├── 2001000003.wav
├── ...
├── 2100003756.wav
└── transcriptions.txt
上传数据说明:
音频文件为单声道wav格式,采样率原数据是44100,建议上传采样率大于等于24000的数据,之后都会被降采样到24000
音频文件名|歌词|音素|音符|音符持续时长|音素持续时长|连音
示例
2001000001|感受停在我发端的指尖|g an sh ou t ing z ai w o f a d uan d e SP zh i j ian AP|G#4/Ab4 G#4/Ab4 G#4/Ab4 G#4/Ab4 F#4/Gb4 F#4/Gb4 F#4/Gb4 F#4/Gb4 E4 E4 E4 E4 D#4/Eb4 D#4/Eb4 D#4/Eb4 D#4/Eb4 rest E4 E4 E4 E4 rest|0.253030 0.253030 0.428030 0.428030 0.320870 0.320870 0.358110 0.358110 0.218610 0.218610 0.519380 0.519380 0.351070 0.351070 0.152260 0.152260 0.089470 0.405810 0.405810 0.696660 0.696660 0.284630|0.0317 0.22133 0.15421 0.27382 0.06335 0.25752 0.07101 0.2871 0.03623 0.18238 0.18629 0.33309 0.01471 0.33636 0.01415 0.13811 0.08947 0.12862 0.27719 0.07962 0.61704 0.28463|0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2001000005|面对浩瀚的星海我们微小得像尘埃|m ian d ui h ao h an an d e x ing h ai ai ai AP w o m en w ei x iao d e x iang ch en ai ai ai SP|C#4/Db4 C#4/Db4 D#4/Eb4 D#4/Eb4 C#4/Db4 C#4/Db4 D#4/Eb4 D#4/Eb4 E4 D#4/Eb4 D#4/Eb4 E4 E4 G#4/Ab4 G#4/Ab4 A4 G#4/Ab4 rest C#4/Db4 C#4/Db4 C#4/Db4 C#4/Db4 D#4/Eb4 D#4/Eb4 C#4/Db4 C#4/Db4 D#4/Eb4 D#4/Eb4 E4 E4 E4 E4 G#4/Ab4 A4 G#4/Ab4 rest|0.196990 0.196990 0.102120 0.102120 0.304680 0.304680 0.096780 0.096780 0.100220 0.150010 0.150010 0.361460 0.361460 0.221070 0.221070 0.183240 0.478670 0.384620 0.106510 0.106510 0.143020 0.143020 0.169480 0.169480 0.224180 0.224180 0.089360 0.089360 0.414460 0.414460 0.378050 0.378050 0.162790 0.207380 0.317260 0.297040|0.02765 0.16934 0.01874 0.08338 0.0821 0.22258 0.0693 0.02748 0.10022 0.07137 0.07864 0.12471 0.23675 0.12356 0.09751 0.18324 0.47867 0.38462 0.0405 0.06601 0.08303 0.05999 0.04687 0.12261 0.09778 0.1264 0.02321 0.06615 0.11958 0.29488 0.06723 0.31082 0.16279 0.20738 0.31726 0.29704|0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
安装 轻改版PaddleSpeech
# 配置 PaddleSpeech 开发环境
!git clone https://gitee.com/HighCWu/PaddleSpeech.git --branch svs
%cd PaddleSpeech
!pip install . -i https://mirror.baidu.com/pypi/simple --user
# 下载 NLTK
%cd /home/aistudio
!wget -P data https://paddlespeech.bj.bcebos.com/Parakeet/tools/nltk_data.tar.gz
!tar zxvf data/nltk_data.tar.gz
重启一下内核,使得刚刚安装的依赖都能加载进notebook
# 删除软链接
# aistudio会报错: paddlespeech 的 repo中存在失效软链接
# 执行下面这行命令!!
!find -L /home/aistudio -type l -delete
import subprocess # 命令行执行函数,可以进入指定路径下执行 def run_cmd(cmd, cwd_path): p = subprocess.Popen(cmd, shell=True, cwd=cwd_path) res = p.wait() print(cmd) print("运行结果:", res) if res == 0: # 运行成功 print("运行成功") return True else: # 运行失败 print("运行失败") return False
# 试验路径
exp_dir = "/home/aistudio/work/exp"
import os
# 配置试验相关路径信息
cwd_path = "/home/aistudio/PaddleSpeech/examples/opencpop/tts3"
dump_dir = os.path.join(exp_dir, 'dump')
output_dir = os.path.join(exp_dir, 'exp')
main_root = "/home/aistudio/PaddleSpeech"
model = "fastspeech2"
bin_dir = f"{main_root}/paddlespeech/t2s/exps/{model}"
# 使用默认示例,只上传音频数据+标注文本
# 输入数据集路径
datasets_dir = "/home/aistudio/work/datasets"
data_dir = f"{datasets_dir}/opencpop"
# 输出文件路径
wav_output_dir = os.path.join(exp_dir, "output")
os.makedirs(wav_output_dir, exist_ok=True)
# 将默认的 yaml 拷贝一份到 exp_dir 下,方便修改
import shutil
in_label = f"{cwd_path}/conf/default.yaml"
shutil.copy(in_label, exp_dir + "/default.yaml")
训练过程中如果有需要修改的参数,就修改 /home/aistudio/work/exp/default.yaml
config_path = os.path.join(exp_dir, "default.yaml")
import os
import glob
if not os.path.exists('/home/aistudio/data/fastspeech2_opencpop_ckpt'):
am_ckpt_paths = glob.glob('/home/aistudio/data/data*/fastspeech2_opencpop_ckpt.tar.gz')[0]
!cd /home/aistudio/data && tar xfz '{am_ckpt_paths}' -C /home/aistudio/data/
!mkdir -p '{dump_dir}'/train
!mkdir -p '{output_dir}'/checkpoints
!cp /home/aistudio/data/fastspeech2_opencpop_ckpt/default.yaml '{config_path}'
!cp /home/aistudio/data/fastspeech2_opencpop_ckpt/phone_id_map.txt '{dump_dir}'/
!cp /home/aistudio/data/fastspeech2_opencpop_ckpt/speech_stats.npy '{dump_dir}'/train/
!cp /home/aistudio/data/fastspeech2_opencpop_ckpt/pitch_stats.npy '{dump_dir}'/train/
!cp /home/aistudio/data/fastspeech2_opencpop_ckpt/snapshot_iter_1000000.pdz '{output_dir}'/checkpoints
点击此处直接跳转到使用已有模型合成歌声部分进行合成实验。
# 举例:这里将data目录下的数据集解压到 datasets 路径下,这一步你可以换成自己的数据集
%cd /home/aistudio/work
!mkdir -p datasets
!unzip -qq ../data/data*/opencpop.zip -d ./datasets/
%cd ..
cmd = f"""
python3 {main_root}/utils/gen_duration_for_svs.py \
--inputdir={datasets_dir} \
--output=durations.txt \
--config={config_path}
"""
# 执行该步骤
run_cmd(cmd, cwd_path)
训练数据预处理
cmd1 = f""" python3 {bin_dir}/preprocess.py \ --rootdir={data_dir} \ --dataset=opencpop \ --dumpdir={dump_dir} \ --dur-file=durations.txt \ --config={config_path} \ --cut-sil=True \ --num-cpu=20 """ cmd2 = f""" python3 {main_root}/utils/compute_statistics.py \ --metadata={dump_dir}/train/raw/metadata.jsonl \ --field-name="speech" """ cmd3 = f""" python3 {main_root}/utils/compute_statistics.py \ --metadata={dump_dir}/train/raw/metadata.jsonl \ --field-name="pitch" """ cmd4 = f""" python3 {main_root}/utils/compute_statistics.py \ --metadata={dump_dir}/train/raw/metadata.jsonl \ --field-name="energy" """ cmd5 = f""" python3 {bin_dir}/normalize.py \ --metadata={dump_dir}/train/raw/metadata.jsonl \ --dumpdir={dump_dir}/train/norm \ --speech-stats={dump_dir}/train/speech_stats.npy \ --pitch-stats={dump_dir}/train/pitch_stats.npy \ --energy-stats={dump_dir}/train/energy_stats.npy \ --phones-dict={dump_dir}/phone_id_map.txt \ --speaker-dict={dump_dir}/speaker_id_map.txt """ cmd6 = f""" python3 {bin_dir}/normalize.py \ --metadata={dump_dir}/dev/raw/metadata.jsonl \ --dumpdir={dump_dir}/dev/norm \ --speech-stats={dump_dir}/train/speech_stats.npy \ --pitch-stats={dump_dir}/train/pitch_stats.npy \ --energy-stats={dump_dir}/train/energy_stats.npy \ --phones-dict={dump_dir}/phone_id_map.txt \ --speaker-dict={dump_dir}/speaker_id_map.txt """ cmd7 = f""" python3 {bin_dir}/normalize.py \ --metadata={dump_dir}/test/raw/metadata.jsonl \ --dumpdir={dump_dir}/test/norm \ --speech-stats={dump_dir}/train/speech_stats.npy \ --pitch-stats={dump_dir}/train/pitch_stats.npy \ --energy-stats={dump_dir}/train/energy_stats.npy \ --phones-dict={dump_dir}/phone_id_map.txt \ --speaker-dict={dump_dir}/speaker_id_map.txt """
# 执行该步骤
run_cmd(cmd1, cwd_path)
run_cmd(cmd2, cwd_path)
run_cmd(cmd3, cwd_path)
run_cmd(cmd4, cwd_path)
run_cmd(cmd5, cwd_path)
run_cmd(cmd6, cwd_path)
run_cmd(cmd7, cwd_path)
不同的数据集是不好给出统一的训练参数,因此在这一步,开发者可以根据自己训练的实际情况调整参数,重要参数说明:
step
(在default.yaml中通过train_max_steps
设置最大步数)
- step 决定了训练的步数,可以结合 VisualDL 服务,在 AIstudio 中查看训练数据是否已经收敛,当数据集数量增加时,预设的训练轮次(2500000)不一定可以达到收敛状态
- 当训练步数过多时,建议新建终端,进入
/home/aistudio/PaddleSpeech/examples/opencpop/tts3
路径下, 执行cmd
命令,AIStudio 在打印特别多的训练信息时,会产生错误
cmd = f"""
python {bin_dir}/train.py \
--train-metadata={dump_dir}/train/norm/metadata.jsonl \
--dev-metadata={dump_dir}/dev/norm/metadata.jsonl \
--config={config_path} \
--output-dir={output_dir} \
--ngpu=1 \
--phones-dict={dump_dir}/phone_id_map.txt
"""
print(cmd)
# 执行该步骤
# 如果训练轮次过多,则复制上面的cmd到终端中运行
run_cmd(cmd, cwd_path)
# 找到最新生成的模型 def find_max_ckpt(model_path): max_ckpt = 0 max_cpkt_path = '' for filename in os.listdir(model_path): if filename.endswith('.pdz'): files = filename[:-4] a1, a2, it = files.split("_") if int(it) > max_ckpt: max_ckpt = int(it) max_cpkt_path = os.path.join(model_path, filename) return max_ckpt, max_cpkt_path if not os.path.exists('/home/aistudio/data/hifigan_opencpop_ckpt'): import glob voc_ckpt_paths = glob.glob('/home/aistudio/data/data*/hifigan_opencpop_ckpt.zip')[0] !cd /home/aistudio/data && unzip -qq '{voc_ckpt_paths}' -d /home/aistudio/data/ voc_ckpt_path = '/home/aistudio/data/hifigan_opencpop_ckpt' _, voc_ckpt_path_pdz = find_max_ckpt(voc_ckpt_path) model_path = os.path.join(output_dir, "checkpoints") ckpt, cpkt_path = find_max_ckpt(model_path)
cmd = f""" python3 {bin_dir}/../synthesize.py \ --am=fastspeech2_opencpop \ --am_config={config_path} \ --am_ckpt={cpkt_path} \ --am_stat={dump_dir}/train/speech_stats.npy \ --voc=hifigan_opencpop \ --voc_config={voc_ckpt_path}/default.yaml \ --voc_ckpt={voc_ckpt_path_pdz} \ --voc_stat={voc_ckpt_path}/feats_stats.npy \ --test_metadata={dump_dir}/test/norm/metadata.jsonl \ --output_dir={wav_output_dir} \ --phones_dict={dump_dir}/phone_id_map.txt \ --use_durations=True \ --use_pitch=True """ print(cmd)
run_cmd(cmd, cwd_path)
# 找到最新的模型 def find_max_ckpt(model_path): max_ckpt = 0 max_cpkt_path = '' for filename in os.listdir(model_path): if filename.endswith('.pdz'): files = filename[:-4] a1, a2, it = files.split("_") if int(it) > max_ckpt: max_ckpt = int(it) max_cpkt_path = os.path.join(model_path, filename) return max_ckpt, max_cpkt_path if not os.path.exists('/home/aistudio/data/hifigan_opencpop_ckpt'): import glob voc_ckpt_paths = glob.glob('/home/aistudio/data/data*/hifigan_opencpop_ckpt.zip')[0] !cd /home/aistudio/data && unzip -qq '{voc_ckpt_paths}' -d /home/aistudio/data/ voc_ckpt_path = '/home/aistudio/data/hifigan_opencpop_ckpt' _, voc_ckpt_path_pdz = find_max_ckpt(voc_ckpt_path) model_path = os.path.join(output_dir, "checkpoints") ckpt, ckpt_path = find_max_ckpt(model_path)
# 导入相关库 # 如果出现导入出错,请重启内核,从头运行一次 import yaml from frontend import parse_args, IPyWidgetInfer # 配置一下参数信息 model_path = os.path.join(output_dir, "checkpoints") ckpt = find_max_ckpt(model_path) args = parse_args() args.am = 'fastspeech2_opencpop' args.am_config = config_path args.am_ckpt = ckpt_path args.am = 'fastspeech2_opencpop' args.am_config = config_path args.am_stat = f'{dump_dir}/train/speech_stats.npy' args.am_pitch_stat = f'{dump_dir}/train/pitch_stats.npy' args.voc = 'hifigan_opencpop' args.voc_config = f'{voc_ckpt_path}/default.yaml' args.voc_ckpt = f'{voc_ckpt_path_pdz}' args.voc_stat = f'{voc_ckpt_path}/feats_stats.npy' args.lang = 'sing-zh' args.phones_dict = f'{dump_dir}/phone_id_map.txt' args.ngpu = 1 # 加载模型 ipy_config = yaml.safe_load(open('settings.yaml')) ipy_infer = IPyWidgetInfer(args, **ipy_config)
# 显示测试界面
ipy_infer.run()
VBox(children=(HTML(value='<h1><center><b>轻改版PaddleSpeech歌声合成模型</b></center></h2>'), HTML(value='<p><p>该模型在开源数…
虽然有PaddleSpeech套件以前就写好的Fastspeech2的模型训练架构,但是从数据集处理到训练到测试数据合成都需要不同程度的魔改,花费了我不少时间。通过上面的学习,相信你也可以使用自己的数据集来训练一个属于自己的歌声合成模型。由于涉及到深度学习模型训练部分,不同的数据集需要做不同的参数尝试,希望你也可以调试出让自己满意的模型。
直接使用Fastspeech2模型训练并没有达到非常好的合成效果,下一步我将尝试在PaddleSpeech上继续魔改,实现DiffSinger模型的歌声合成效果。
最后,在学习过程中,你遇到任何问题都可以加入我的技术交流群与我群群友进行深入的交流探讨。
艾梦的声动小群
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。