前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手把手教学!如何自己训练一个AI歌手 - so-vits-svc云端训练教程

手把手教学!如何自己训练一个AI歌手 - so-vits-svc云端训练教程

原创
作者头像
小东_
修改2023-08-27 01:31:26
3.4K0
修改2023-08-27 01:31:26
举报

介绍

so-vits-svc是基于VITS的开源项目,VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)是一种结合变分推理、标准化流和对抗训练的高表现力语音合成模型。

环境

本文章使用的是腾讯云GPU计算型GN7,具体环境如下:

代码语言:shell
复制
# 系统环境
Ubuntu 22.04 LTS
# 显卡环境
NVIDIA-SMI 470.182.03    Driver Version: 470.182.03    CUDA Version: 11.4
# python环境
Python 3.10
# GPU环境
Tesla T4 16G * 1
# CPU环境
8核	32GB
365404354399d97e8333b.png
365404354399d97e8333b.png
87053539fd2c945364ffb.png
87053539fd2c945364ffb.png

音频处理

为了训练,我们需要将音频文件分离成人声和伴奏两个音轨,并将人声音频文件切分成10-20秒的音频片段。

  1. 使用Spleeter分离人声音轨
代码语言:shell
复制
apt install ffmpeg        #该条命令要在root用户下安装
pip install spleeter
代码语言:shell
复制
mkdir spleeter && cd spleeter
mkdir raw
#下载模型
mkdir pretrained_models
wget -P pretrained_models https://github.com/deezer/spleeter/releases/download/v1.4.0/2stems.tar.gz
# 境内vps下载太慢,可以使用下面的链接
# wget -P pretrained_models https://kgithub.com/deezer/spleeter/releases/download/v1.4.0/2stems.tar.gz
mkdir -p pretrained_models/2stems
tar -zxvf pretrained_models/2stems.tar.gz -C pretrained_models/2stems/
  1. 测试分离人声
代码语言:shell
复制
# 测试
wget https://github.com/deezer/spleeter/raw/master/audio_example.mp3
spleeter separate -p spleeter:2stems -o output audio_example.mp3
代码语言:shell
复制
output/
└── audio_example
    ├── accompaniment.wav # 伴奏
    └── vocals.wav   # 人声
  1. 批量分离音轨

将需要分离的音频文件放到spleeter/raw目录下,然后执行下面的命令 为了方便批量处理,可以使用下面的脚本 下面脚本将raw目录下的所有.wav文件分离成人声和伴奏两个音轨,并保存到spleeter/audio_output文件夹中

代码语言:shell
复制
#!/bin/bash

# 创建output文件夹(如果不存在)
mkdir -p audio_output

# 遍历raw目录下的WAV文件
for file in raw/*.wav; do

  # 检查文件类型是否为MP3
  if [[ -f "$file" ]]; then
    echo "正在处理文件: $file"

    # 提取文件名(不包括扩展名)
    filename=$(basename "$file" .wav)

    # 使用spleeter命令进行分离并保存到audio_output/文件夹中
    spleeter separate \
        -o audio_output \
        "$file" \
        -f "$filename"_{instrument}.wav
  fi
  
done

echo "分离完成!"

效果如下

代码语言:shell
复制
ubuntu@VM-0-12-ubuntu:~/spleeter$ tree audio_output/
audio_output/
├── 11_accompaniment.wav
├── 11_vocals.wav
├── 12_accompaniment.wav
├── 12_vocals.wav
├── 13_accompaniment.wav
└── 13_vocals.wav

0 directories, 6 files
  1. 切分音频片段
代码语言:shell
复制
pip librosa soundfile

执行下面脚本,将会从audio_output目录中的每个音频文件中提取出10-20秒的音频片段,并保存到clips目录中。

代码语言:python
代码运行次数:0
复制
import librosa
import soundfile
import random
import os

# 获取当前工作目录
cwd = os.getcwd()

# 设置原始音频文件所在目录和新文件保存目录
src_folder = os.path.join(cwd, 'audio_output')  # 原始音频文件所在目录
dst_folder = os.path.join(cwd, 'clips')  # 新文件保存目录

# 创建新文件保存目录
if not os.path.exists(dst_folder):
    os.makedirs(dst_folder)

# 遍历源目录中的所有wav文件
for filename in os.listdir(src_folder):
    if filename.endswith("vocals.wav"):
        audio_path = os.path.join(src_folder, filename)
        print(f"Processing {audio_path}...")

        # 加载音频文件
        audio, sr = librosa.load(audio_path, sr=None, mono=False)

        # 去除音频文件中的静音部分
        audio_trimmed, index = librosa.effects.trim(audio, top_db=20, frame_length=2048, hop_length=512)

        # 计算总时长和总采样点数
        duration = len(audio_trimmed[0]) / sr
        total_samples = audio_trimmed.shape[-1]

        # 确定每个片段应该包含的采样点数
        min_duration = 10  # 最小片段长度(秒)
        max_duration = 20  # 最大片段长度(秒)
        segment_duration = random.uniform(min_duration, max_duration)  # 随机生成片段长度
        segment_samples = int(segment_duration * sr)  # 将片段长度转换为采样点数

        # 循环遍历音频文件,并将每个片段保存为新的音频文件
        for i in range(0, total_samples, segment_samples):
            start = i  # 当前片段的起始采样点
            end = min(i + segment_samples, total_samples)  # 当前片段的结束采样点

            chunk = audio_trimmed[:, start:end]  # 截取当前片段的音频数据
            if len(chunk.shape) > 1:
                chunk = chunk.T  # 如果是立体声,则交换通道

            # 构造新文件名
            clip_filename = f"{os.path.splitext(filename)[0]}_{i//segment_samples}.wav"
            clip_path = os.path.join(dst_folder, clip_filename)

            soundfile.write(clip_path, chunk, sr)  # 保存当前片段的音频数据到文件中

开始训练

  1. 克隆存储库并安装依赖项
代码语言:shell
复制
git clone https://github.com/svc-develop-team/so-vits-svc.git
cd so-vits-svc
apt install python3-venv   #该条命令要在root用户下安装
python3 -m venv myenv
source myenv/bin/activate
pip uninstall -y torchdata torchtext
pip install --upgrade pip setuptools numpy numba
pip install pyworld praat-parselmouth fairseq tensorboardX torchcrepe librosa==0.9.1 pyyaml pynvml pyloudnorm
pip install torch torchvision torchaudio 
pip install rich loguru matplotlib
pip install faiss-gpu
pip uninstall omegaconf
pip install omegaconf==2.0.5
pip install antlr4-python3-runtime==4.8
pip install antlr4-python3-runtime==4.8
pip install tensorboard
  1. 数据集准备

将上一步中生成的音频片段文件夹clips移动到so-vits-svc/dataset_raw目录下,目录结构如下:

代码语言:shell
复制
dataset_raw
├───speaker0
│   ├───xxx1-xxx1.wav
│   ├───...
│   └───Lxx-0xx8.wav

speaker0 是合成目标说话人的名称。推理时需要用到该名称。 对于每一个音频文件的名称并没有格式的限制(000001.wav~999999.wav之类的命名方式也是合法的),不过文件类型必须是wav。

  1. 获取预训练模型
代码语言:shell
复制
cd so-vits-svc
#download_pretrained_model
curl -L https://huggingface.co/datasets/ms903/sovits4.0-768vec-layer12/resolve/main/sovits_768l12_pre_large_320k/clean_D_320000.pth -o logs/44k/D_0.pth
curl -L https://huggingface.co/datasets/ms903/sovits4.0-768vec-layer12/resolve/main/sovits_768l12_pre_large_320k/clean_G_320000.pth -o logs/44k/G_0.pth
#download_pretrained_diffusion_model
#不训练扩散模型时不需要下载
wget -L https://huggingface.co/datasets/ms903/Diff-SVC-refactor-pre-trained-model/resolve/main/fix_pitch_add_vctk_600k/model_0.pt -o logs/44k/diffusion/model_0.pt

#如果使用rmvpeF0预测器的话,需要下载预训练的 RMVPE 模型
curl -L https://huggingface.co/datasets/ylzz1997/rmvpe_pretrain_model/resolve/main/rmvpe.pt -o pretrain/rmvpe.pt
curl -L https://huggingface.co/datasets/ylzz1997/rmvpe_pretrain_model/resolve/main/fcpe.pt -o pretrain/fcpe.pt
  1. 使用 contentvec 作为声音编码器(推荐)

vec768l12vec256l9 需要该编码器

或者下载下面的 ContentVec,大小只有 199MB,但效果相同:

  • contentvec :hubert_base.pt
  • 将文件名改为checkpoint_best_legacy_500.pt后,放在pretrain目录下
代码语言:shell
复制
# contentvec
wget -P pretrain/ https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/hubert_base.pt -O checkpoint_best_legacy_500.pt
# 也可手动下载放在 pretrain 目录

更多编码器请参考so-vits-svc

  1. 重采样至 44100Hz 单声道
代码语言:shell
复制
python resample.py
  1. 自动划分训练集、验证集,以及自动生成配置文件
代码语言:shell
复制
python preprocess_flist_config.py --speech_encoder=vec768l12
  1. 生成 hubert 与 f0
代码语言:shell
复制
python preprocess_hubert_f0.py --f0_predictor=crepe
d259e8a5d04af5ef37347.png
d259e8a5d04af5ef37347.png

加速预处理 如若您的数据集比较大,可以尝试添加--num_processes参数:

代码语言:shell
复制
python preprocess_hubert_f0.py --f0_predictor=crepe --num_processes 8
  1. 主模型训练
代码语言:shell
复制
python train.py -c configs/config.json -m 44k

扩散模型(可选), 尚若需要浅扩散功能,需要训练扩散模型,扩散模型训练方法为:

代码语言:shell
复制
python train_diff.py -c configs/diffusion.yaml

用tensorboard查看训练情况

代码语言:shell
复制
tensorboard --logdir logs/44k --host=0.0.0.0
2dbf82e248e02abde1b16.png
2dbf82e248e02abde1b16.png
407edfd7f243e3cdcff29.png
407edfd7f243e3cdcff29.png
  1. 聚类模型训练(可选)
代码语言:shell
复制
python cluster/train_cluster.py --gpu

模型训练结束后,模型文件保存在logs/44k目录下,聚类模型会保存在logs/44k/kmeans_10000.pt,扩散模型在logs/44k/diffusion下 。

推理 (对配置要求不高可以用自己的电脑进行)

  1. 参数说明
代码语言:shell
复制
# 例
python inference_main.py -m "logs/44k/G_30400.pth" -c "configs/config.json" -n "君の知らない物語-src.wav" -t 0 -s "nen"

必填项部分:

  • -m | --model_path:模型路径
  • -c | --config_path:配置文件路径
  • -n | --clean_names:wav 文件名列表,放在 raw 文件夹下
  • -t | --trans:音高调整,支持正负(半音)
  • -s | --spk_list:合成目标说话人名称
  • -cl | --clip:音频强制切片,默认 0 为自动切片,单位为秒/s

可选项部分:部分具体见下一节

  • -lg | --linear_gradient:两段音频切片的交叉淡入长度,如果强制切片后出现人声不连贯可调整该数值,如果连贯建议采用默认值 0,单位为秒
  • -f0p | --f0_predictor:选择 F0 预测器,可选择 crepe,pm,dio,harvest,rmvpe,fcpe, 默认为 pm(注意:crepe 为原 F0 使用均值滤波器)
  • -a | --auto_predict_f0:语音转换自动预测音高,转换歌声时不要打开这个会严重跑调
  • -cm | --cluster_model_path:聚类模型或特征检索索引路径,留空则自动设为各方案模型的默认路径,如果没有训练聚类或特征检索则随便填
  • -cr | --cluster_infer_ratio:聚类方案或特征检索占比,范围 0-1,若没有训练聚类模型或特征检索则默认 0 即可
  • -eh | --enhance:是否使用 NSF_HIFIGAN 增强器,该选项对部分训练集少的模型有一定的音质增强效果,但是对训练好的模型有反面效果,默认关闭
  • -shd | --shallow_diffusion:是否使用浅层扩散,使用后可解决一部分电音问题,默认关闭,该选项打开时,NSF_HIFIGAN 增强器将会被禁止
  • -usm | --use_spk_mix:是否使用角色融合/动态声线融合
  • -lea | --loudness_envelope_adjustment:输入源响度包络替换输出响度包络融合比例,越靠近 1 越使用输出响度包络
  • -fr | --feature_retrieval:是否使用特征检索,如果使用聚类模型将被禁用,且 cm 与 cr 参数将会变成特征检索的索引路径与混合比例

浅扩散设置:

  • -dm | --diffusion_model_path:扩散模型路径
  • -dc | --diffusion_config_path:扩散模型配置文件路径
  • -ks | --k_step:扩散步数,越大越接近扩散模型的结果,默认 100
  • -od | --only_diffusion:纯扩散模式,该模式不会加载 sovits 模型,以扩散模型推理
  • -se | --second_encoding:二次编码,浅扩散前会对原始音频进行二次编码,玄学选项,有时候效果好,有时候效果差
  • 推理

下面以孙燕姿的模型为例,演示如何使用 so-vits-svc 进行音色转换 模型地址:孙燕姿模型 先看效果

<audio id="audio" controls="" preload="none">

代码语言:txt
复制
  <source id="mp3" src="https://pan.tryxd.cn/d/aliyundrive/so-vits-svc/%E4%BA%BA%E6%9D%A5%E4%BA%BA%E5%BE%80-%E5%AD%99%E7%87%95%E5%A7%BF.wav">

</audio>

代码语言:shell
复制
# 例
spleeter separate -o raw 人来人往.wav -f 人来人往_{instrument}.wav
python inference_main.py -m "logs/44k/G_27200.pth" -c "configs/sun.json" -n "人来人往_vocals.wav" -t 0 -s "sun" -cm "logs/44k/kmeans_10000.pt" 

logs/44k/G_27200.pth为主模型 configs/sun.json为配置文件 人来人往_vocals.wavraw目录下待转换的人声音频文件 sun为目标说话人名称(configs/sun.json中的spk对应的vlaue) logs/44k/kmeans_10000.pt为聚类模型

f0553cd31dd50ac6b8b81.png
f0553cd31dd50ac6b8b81.png

分享的孙燕姿模型由于是4.0版本的,需要在 config.json 的 model 字段中添加 speech_encoder 字段,具体如下: "model": { ......... "ssl_dim": 256, "n_speakers": 200, "speech_encoder":"vec256l9" }

1b6e53d58cf52db149347.png
1b6e53d58cf52db149347.png
  1. 合并人声与伴奏
代码语言:shell
复制
ffmpeg -i 人来人往_accompaniment.wav -i 人来人往_vocals.wav_0key_sun_sovits_pm.flac -filter_complex amix=inputs=2:duration=first:dropout_transition=3 output.wav
参考:https://github.com/svc-develop-team/so-vits-svc/tree/4.1-Stable

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 环境
  • 音频处理
  • 开始训练
  • 推理 (对配置要求不高可以用自己的电脑进行)
    • 参考:https://github.com/svc-develop-team/so-vits-svc/tree/4.1-Stable
    相关产品与服务
    媒体 AI 处理
    媒体 AI 处理(Media Artificial Intelligence processing)基于腾讯云点播产品提供智能化的媒体内容审核、分析、识别能力,包含违禁检测,画面识别、语音转文字等功能。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档