使用sambert-hifigan微调实现个性化声音定制
基本概念
TTS(text-to-speech): 文本到语音。输入:文本 输出:音频
Voice Cloning: 在模仿特定人物的声音。输入:文本信息+音频,输出:文本信息对应的音频。
Voice Conversion: 改变已有的语音录音,使其听起来像另一个人或以不同的情感或风格说话。输入:音频1+音频2,输出:内容和音频1一致,音色类似于音频2(例如:变声器)
相关开源项目调研
年份 | 项目名称 | 链接地址 | 描述 | 其他特性 |
---|---|---|---|---|
2023 | coqui TTS | TTS | 支持中文等多重语言,支持多种模型 | 支持voice cloning,voice conversion |
2021 | Real-Time-Voice-Cloning | Real-Time-Voice-Cloning | 功能较多,众多开源项目都参考了这一个项目 | 支持voice cloning,只支持英文 |
2023 | LocalAI | LocalAI | 包含LLM,TTS,文生图以及向量数据库 | 不支持voice cloning |
2023 | tortoise-tts | tortoise-tts | 包含TTS,中文效果不理想 | 不支持voice cloning,支持prompt engineering,如:[I am really sad,] Please feed me. -> Please feed me. |
2020 | TTS (Mozilla) | TTS | 不支持中文,只支持German,French,English | 支持微调,不支持voice cloning |
2023 | TTS (JAVA) | TTS | 纯JAVA,文档不全 | |
2022 | tts-vue | tts-vue | 基于微软的语音合成,支持中文 | 只支持基础的tts,不支持voiceclone和voiceconversion |
2019 | WaveRNN | WaveRNN | 纯pytorch的开源项目 | 仅支持训练自己的模型 |
2021 | TensorFlowTTS | TensorFlowTTS | 纯tensorflow支持中文等多种语言,支持多种模型 | 不支持voiceclone和voiceconversation |
2022 | PaddleSpeech | PaddleSpeech | 支持中英,资料文档最全,国产paddle框架 | 支持voice cloning,voice conversion |
2023 | Sambert-hifigan | speech_sambert-hifigan_tts_zh-cn_16k | 阿里的模型,提供多个发音人,支持中英 | 不支持voice cloning,支持多发音人,这个系列还有其他的语言模型:粤语,上海话,四川话,俄语等。 |
2023 | SoftVC VITS Singing Voice Conversion | so-vits-svc | 偏向于歌声Voice Conversion ,而不是TTS | 支持voice conversion |
2021 | espnet | espnet | 端到端的语音理解, 支持中文,支持多种语言 | 支持voice conversion,不支持voice cloning, |
2023 | Retrieval-based-Voice-Conversion-WebUI | Retrieval-based-Voice-Conversion-WebUI | voice conversion | 支持voice conversion |
2023 | VALL-E-X | VALL-E-X | 基于微软的语音合成,支持中文,支持voiceclone | 支持voiceclone |
sambert-hifigan整体框架
参考自:https://www.modelscope.cn/models/damo/speech_personal_sambert-hifigan_nsf_tts_zh-cn_pretrain_16k/summary
输入: 文本
输出: 音频
实验过程
数据集
以下为所用的数据集的时长
Name | Dataset_time |
---|---|
A | <5min |
B | 1hour |
C | 1hour |
D | 1hour |
E | 3-5hour |
F | 3-5hour |
长音频切片
主要使用whisper进行长音频切片,whisper采用的模型可以进行修改为large,small等,可根据机器的配置进行决定
import subprocess
from pathlib import Path
import librosa
from scipy.io import wavfile
import numpy as np
import torch
import csv
import whisper
def split_long_audio(model, filepaths, character_name, save_dir="data_dir", out_sr=44100):
if isinstance(filepaths, str):
filepaths = [filepaths]
for file_idx, filepath in enumerate(filepaths):
save_path = Path(save_dir) / character_name
save_path.mkdir(exist_ok=True, parents=True)
print(f"Transcribing file {file_idx}: '{filepath}' to segments...")
result = model.transcribe(filepath, word_timestamps=True, task="transcribe", beam_size=5, best_of=5)
segments = result['segments']
wav, sr = librosa.load(filepath, sr=None, offset=0, duration=None, mono=True)
wav, _ = librosa.effects.trim(wav, top_db=20)
peak = np.abs(wav).max()
if peak > 1.0:
wav = 0.98 * wav / peak
wav2 = librosa.resample(wav, orig_sr=sr, target_sr=out_sr)
wav2 /= max(wav2.max(), -wav2.min())
for i, seg in enumerate(segments):
start_time = seg['start']
end_time = seg['end']
wav_seg = wav2[int(start_time * out_sr):int(end_time * out_sr)]
wav_seg_name = f"{character_name}_{file_idx}_{i}.wav"
out_fpath = save_path / wav_seg_name
wavfile.write(out_fpath, rate=out_sr, data=(wav_seg * np.iinfo(np.int16).max).astype(np.int16))
whisper_size = "medium"
whisper_model = whisper.load_model(whisper_size)
split_long_audio(whisper_model, "filename.wav", "test", "dataset_raw") # 请在{filename}处填写您上传的wav文件名
音频标注
input_wav = "./test_wavs/"
output_data = "./output_training_data/"
ret, report = run_auto_label(input_wav=input_wav, work_dir=output_data, resource_revision="v1.0.5")
声学模型配置修改
train_max_steps: 1002000
linguistic_unit: {cleaners: english_cleaners, lfeat_type_list: 'sy,tone,syllable_flag,word_segment,emo_category,speaker_category',
speaker_list: 'A,F74,FBYN,FRXL,M7,xiaoyu'} #这个speak list中需要包含训练的说话人名称,例如:此处用A的声音做训练
声码器配置修改
save_interval_steps: 2000
train_max_steps: 2500000
微调
# 特征提取
python kantts/preprocess/data_process.py --voice_input_dir /data/software/anchor_voice/zhubo_output_training_data --voice_output_dir training_stage/zhubo_feats --audio_config kantts/configs/audio_config_16k.yaml --speaker A
# 训练声学模型(multisp)
CUDA_VISIBLE_DEVICES=0 python kantts/bin/train_sambert.py --model_config speech_sambert-hifigan_tts_zh-cn_multisp_pretrain_16k/basemodel_16k/sambert/config.yaml --resume_path speech_sambert-hifigan_tts_zh-cn_multisp_pretrain_16k/basemodel_16k/sambert/ckpt/checkpoint_980000.pth --root_dir training_stage/zhubo_feats --stage_dir training_stage/zhubo_sambert_ckpt
# 训练声码器
CUDA_VISIBLE_DEVICES=0 python kantts/bin/train_hifigan.py --model_config speech_sambert-hifigan_tts_zh-cn_multisp_pretrain_16k/basemodel_16k/hifigan/config.yaml --resume_path speech_sambert-hifigan_tts_zh-cn_multisp_pretrain_16k/basemodel_16k/hifigan/ckpt/checkpoint_2000000.pth --root_dir training_stage/zhubo_feats --stage_dir training_stage/zhubo_hifigan_ckpt
# 推理
CUDA_VISIBLE_DEVICES=0 python kantts/bin/text_to_wav.py --txt test.txt --output_dir res/zhubo_syn --res_zip speech_sambert-hifigan_tts_zh-cn_multisp_pretrain_16k/resource.zip --am_ckpt training_stage/zhubo_sambert_ckpt/ckpt/checkpoint_1000000.pth --voc_ckpt training_stage/zhubo_hifigan_ckpt/ckpt/checkpoint-3473.pth --speaker A
微调经验
-
高质量的数据集 >> 低质量的数量集
-
数据集的时长最好大于30min
-
低质量数据集即使时间很长,对于训练的产生的效果也不会有很大的改进
-
hifigan可以不进行微调,进行微调的时候,也可以无需进行很多轮次的迭代,因为它的loss值下降的很慢
-
声音存在颤音 电流音,且loss值较高的时候增加epoch次数可以提高生成的质量,或者进行声码器训练
-
数据集越大,每个epoch耗时越长
-
提高效果的三种方法:1. 制作高质量数据集 2. 增加声学模型的epoch次数 3.微调声码器
微调sambert loss统计
微调了好几个模型,本机环境:RTX4090,time_consume为实际所采取的epoch和消耗的时间(发现epoch持续增加,并没有提高效果所以停了)
model | Name | Time_consume | Loss | mel_loss | dur_loss | pitch_loss | energy_loss | x_band_width | h_band_width | Batch_size |
---|---|---|---|---|---|---|---|---|---|---|
sambert | A | 377 epoch/5 min | 0.5664 | 0.1509 | 0.0451 | 0.1040 | 0.0935 | 17.9310 | 17.9310 | 3.6250 |
sambert | B | 200 epoch/12min | 0.5860 | 0.1511 | 0.0609 | 0.0955 | 0.1053 | 20.1870 | 20.1870 | 4 |
sambert | C | 168 epoch/17 min | 0.6747 | 0.1587 | 0.0822 | 0.1088 | 0.1401 | 21.9500 | 21.9500 | 3.993 |
sambert | D | 252 epoch/19min | 0.7172 | 0.1661 | 0.0835 | 0.1101 | 0.1584 | 20.807 | 20.807 | 3.964 |
sambert | E | 75 epoch/17min | 0.8920 | 0.1786 | 0.1269 | 0.1416 | 0.2284 | 15.6060 | 15.6060 | 3.9960 |
Sambert | F | 500epoch/163min | 0.6349 | 0.1436 | 0.0805 | 0.1040 | 0.1331 | 21.1130 | 21.1130 | 3.9940 |
微调hifigan统计
Model | Name | Time_consume | mel_loss | adversarial_loss | feature_matching_loss | generator_loss | real_loss | fake_loss | discriminator_loss |
---|---|---|---|---|---|---|---|---|---|
Hifigan | A | 100 epoch/9min | 0.2129 | 6.1258 | 7.0702 | 27.5839 | 1.6158 | 1.5822 | 3.1981 |
Hifigan | B | 137 epoch/10 min | 0.2125 | 6.2978 | 7.3480 | 28.3807 | 1.5831 | 1.5771 | 3.1602 |
Hifigan | C | 207 epoch/23 min | 0.1943 | 5.9018 | 6.3661 | 25.1379 | 1.6605 | 1.6345 | 3.2950 |
Hifigan | D | 190 epoch/15min | 0.2117 | 6.4751 | 7.5379 | 28.8336 | 1.5494 | 1.5520 | 3.1014 |
Hifigan | E | 53epoch/18min | 0.2050 | 5.5553 | 7.1131 | 26.9672 | 1.7102. | 1.6516 | 3.3617. |
Hifigan | F | 292epoch/103min | 0.1961 | 6.9237 | 8.8899 | 31.0619 | 1.4539 | 1.5054 | 2.9716 |
优化方向
- 数据集标注,高质量数据集
- 多人物 共同推理一段文本