关于Sovits的本地部署

2023-11-02 00:50
文章标签 部署 本地 sovits

本文主要是介绍关于Sovits的本地部署,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

近几天有好多小伙伴咨询Sovits本地部署的问题,所以呢决定写个简易教程。

首先给出官方Github链接:GitHub - svc-develop-team/so-vits-svc: SoftVC VITS Singing Voice Conversion

首先放出声明(官方写的):

本项目为开源、离线的项目,SvcDevelopTeam的所有成员与本项目的所有开发者以及维护者(以下简称贡献者)对本项目没有控制力。本项目的贡献者从未向任何组织或个人提供包括但不限于数据集提取、数据集加工、算力支持、训练支持、推理等一切形式的帮助;本项目的贡献者不知晓也无法知晓使用者使用该项目的用途。故一切基于本项目训练的AI模型和合成的音频都与本项目贡献者无关。一切由此造成的问题由使用者自行承担。

此项目完全离线运行,不能收集任何用户信息或获取用户输入数据。因此,这个项目的贡献者不知道所有的用户输入和模型,因此不负责任何用户输入。

本项目只是一个框架项目,本身并没有语音合成的功能,所有的功能都需要用户自己训练模型。同时,这个项目没有任何模型,任何二次分发的项目都与这个项目的贡献者无关。

使用规约:

  1. 本项目是基于学术交流目的建立,仅供交流与学习使用,并非为生产环境准备。
  2. 任何发布到视频平台的基于 sovits 制作的视频,都必须要在简介明确指明用于变声器转换的输入源歌声、音频,例如:使用他人发布的视频 / 音频,通过分离的人声作为输入源进行转换的,必须要给出明确的原视频、音乐链接;若使用是自己的人声,或是使用其他歌声合成引擎合成的声音作为输入源进行转换的,也必须在简介加以说明。
  3. 由输入源造成的侵权问题需自行承担全部责任和一切后果。使用其他商用歌声合成软件作为输入源时,请确保遵守该软件的使用条例,注意,许多歌声合成引擎使用条例中明确指明不可用于输入源进行转换!
  4. 禁止使用该项目从事违法行为与宗教、政治等活动,该项目维护者坚决抵制上述行为,不同意此条则禁止使用该项目。
  5. 继续使用视为已同意本仓库 README 所述相关条例,本仓库 README 已进行劝导义务,不对后续可能存在问题负责。
  6. 如果将此项目用于任何其他企划,请提前联系并告知本仓库作者,十分感谢。

两点强烈建议:

1、使用Linux系统(Windows也可以,但是略麻烦)

2、GPU的显存最好在12G以上(自己电脑显存不够的话可以使用云服务器,Colab或者Autodl等都可以)

Step1: 获取视频数据

训练Sovits的时候,需要一些原始音频数据,比如你想训练AI陈奕迅,那你就得获取陈奕迅的音频数据。B站有那种歌手歌曲合集的视频,可以一次性下载很多首歌,不用一首一首的下载,所以我的所有数据都是从B站获取的,当然别的渠道也可以,只要是WAV格式的都行。其他格式的音频数据也可以,但是需要借助代码或者工具来转换以下,略麻烦,不推荐。

首先打开B站,搜索XX歌手歌曲合集,点进去,选中红框内的链接复制下来。图片不让放。。这个很简单,有没有无所谓了~

import os
import subprocess
import shutil# 视频链接列表
video_urls = ["https://www.bilibili.com/video/BV1Gt411U73U"]# 视频保存的目录
output_directory = "videos/eason"for url in video_urls:# 构建yt-dlp命令command = ["yt-dlp","-o", os.path.join(output_directory, "%(title)s.%(ext)s"),  # 输出路径url  # 要下载的视频链接]# 执行yt-dlp命令subprocess.run(command, check=True)

video_urls里面放入上面复制的链接就可以了,这里可以放多个链接,用逗号隔开就好。Video/eason是存放视频文件的地方,可以自定义。

Step2: 获取音频数据

需要训练的数据是音频数据,所以还要将上面的视频数据给分离一下,分成音频和视频。

import os
import moviepy.editor as mp
from pydub import AudioSegment
from multiprocessing import Pooldef process_video(filename):if filename.endswith('.mp4'):# 读取视频文件video = mp.VideoFileClip(os.path.join(input_video_directory, filename))# 创建音频文件audio = video.audioaudio_filename = os.path.splitext(filename)[0] + '.wav'audio.write_audiofile(os.path.join(output_audio_directory, audio_filename))# 创建无音频的视频文件video_without_audio = video.without_audio()video_filename = os.path.splitext(filename)[0] + '_no_audio.mp4'video_without_audio.write_videofile(os.path.join(output_video_directory, video_filename))# 视频输入和输出目录
input_video_directory = 'video/eason'
output_video_directory = 'audio_video/video'# 音频输出目录
output_audio_directory = 'audio_video/audio'
# 创建一个处理器池
pool = Pool()# 使用多进程处理视频文件
pool.map(process_video, os.listdir(input_video_directory))pool.close()
pool.join()

这个input_video_directory就是第一步从B站下载到的视频的存放文件夹,output_video_directory是分离后的视频存放文件地址,output_audio_directory是音频存放地址,后续训练我们只用到output_audio_directory。

如果运行以后出现"no module named xx",那就是xx包没有安装,直接pip install xx -i 清华源就好。

Step3: 人声和背景声分离

第二步获取到的音频数据是人声和背景声,比如钢琴、小提琴和吉他声等。为了获得纯净的人声,需要利用算法将它们分开。

import os
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'from spleeter.separator import Separator
import soundfile as sfdef process_folder(input_folder_path, vocals_folder_path, accompaniment_folder_path):# 使用预训练模型 'spleeter:2stems' 进行声音分离separator = Separator('spleeter:2stems')# 获取文件夹中所有.wav文件的路径file_paths = [os.path.join(input_folder_path, f) for f in os.listdir(input_folder_path) if f.endswith('.wav')]# 逐个处理音频文件for file_path in file_paths:# 加载音频文件audio_data, sample_rate = sf.read(file_path)# 分离音频文件prediction = separator.separate(audio_data)# 获取音频文件名(不含后缀)file_name = os.path.splitext(os.path.basename(file_path))[0]# 保存人声到特定的文件夹sf.write(os.path.join(vocals_folder_path, file_name + '_vocals.wav'), prediction['vocals'], sample_rate)# 保存伴奏到特定的文件夹sf.write(os.path.join(accompaniment_folder_path, file_name + '_accompaniment.wav'), prediction['accompaniment'], sample_rate)# 使用你的音频文件夹路径替换下面的路径
process_folder('audio_video/audio', 'vocals', 'accompaniment')

说明一下,process_folder函数里面第一个参数是第二步获取到的audio文件夹的地址,vocals是人声存放地址,这个就是我们的初始数据,accompaniment存放的是背景声,这个虽然训练用不到,但是后面会用到,不要删掉了。

Step4: 音频切片

一首歌通常4分钟左右,但是如果将整首歌直接送到模型,大概率会爆显存,所以现在把每一首歌切成很多个片段,每个片段长度在5-15秒左右,根据自己GPU显存来确定,我这里选择每段切成10s。

import os
import wave
import audioopinput_folder = "vocals"
output_folder = "eason"if not os.path.exists(output_folder):os.makedirs(output_folder)for audio_file in os.listdir(input_folder):if audio_file.endswith('.wav'):audio_path = os.path.join(input_folder, audio_file)with wave.open(audio_path, 'rb') as audio:params = audio.getparams()frames_per_slice = params.framerate * 8  # 15 seconds of framesfor i in range(0, params.nframes, frames_per_slice):audio.setpos(i)frames = audio.readframes(frames_per_slice)# If the audio is stereo, we need to half the slice size because it contains two channelsif params.nchannels == 2:frames = audioop.tomono(frames, params.sampwidth, 0.5, 0.5)slice_file_name = f"{audio_file.split('.wav')[0]}_slice_{i//frames_per_slice}.wav"slice_path = os.path.join(output_folder, slice_file_name)with wave.open(slice_path, 'wb') as slice:slice.setnchannels(1 if params.nchannels == 2 else params.nchannels)slice.setsampwidth(params.sampwidth)slice.setframerate(params.framerate)slice.writeframes(frames)

这里面,input_folder是第三步人声的文件夹地址,output_folder是切片以后的声音片段文件夹的地址,建议将output_folder命名为歌手英文名。

上面的是我自己写的一些小工具,下面接着官方教程。

Step5: 下载一些Pretrain文件

hubert_base.pt是声音编码器文件,把它下载下来将文件名改为checkpoint_best_legacy_500.pt后,放在pretrain目录下。

clean_G_320000.pth和clean_G_320000.pth是预训练底膜文件,分别改名成G_0.pth和D_0.pth文件放在logs/44k下面,PS这俩玩意找了半天才从huffingface找到,之前用的其他人的底膜,训练出来的电音小王子把我给整麻了。

model_0.pt是扩散模型预训练文件,放在logs/44k/diffusion下面,同样在huffingface找到了,huffingfaceNB!!!!!!!

链接:https://pan.baidu.com/s/1zhoqdZtY7ELmQLd0ZEzd0g?pwd=vda8 
提取码:vda8 
--来自百度网盘超级会员V4的分享

Step6: 将切片后的音频片段重采样至44100HZ单声道

命令行切到so-vits-svc-4.1-Stable文件夹,然后运行resample.py

cd so-vits-svc-4.1-Stablepython resample.py

Step7: 自动划分训练集、验证集和生成配置文件

python preprocess_flist_config.py --speech_encoder vec768l12

运行完成后会生成config.json和diffusion.yaml文件夹,需要进行一些修改,搬运下官方解释:

diffusion.yaml
  • cache_all_data:加载所有数据集到内存中,某些平台的硬盘IO过于低下、同时内存容量 远大于 数据集体积时可以启用

  • duration:训练时音频切片时长,可根据显存大小调整,注意,该值必须小于训练集内音频的最短时间!

  • batch_size:单次训练加载到GPU的数据量,调整到低于显存容量的大小即可

  • timesteps : 扩散模型总步数,默认为1000.

  • k_step_max : 训练时可仅训练k_step_max步扩散以节约训练时间,注意,该值必须小于timesteps,0为训练整个扩散模型,注意,如果不训练整个扩散模型将无法使用仅扩散模型推理!

json文件夹可以用记事本打开

  • keep_ckpts:训练时保留最后几个模型,0为保留所有,默认只保留最后3

  • all_in_mem:加载所有数据集到内存中,某些平台的硬盘IO过于低下、同时内存容量 远大于 数据集体积时可以启用

  • batch_size:单次训练加载到GPU的数据量,调整到低于显存容量的大小即可

  • vocoder_name : 选择一种声码器,默认为nsf-hifigan.

Step8: 生成hubert和f0

python preprocess_hubert_f0.py --f0_predictor dio

这个过程比较缓慢,需要耐心等待。此外,最好保持硬盘内存剩余容量在10G以上。

Step9: 主模型训练

python train.py -c configs/config.json -m 44k

这里其实还有个扩散模型训练,为了省事就只训练主模型。

模型训练结束后,模型文件保存在logs/44k目录下,扩散模型在logs/44k/diffusion

Step10: 推理

python inference_main.py -m "logs/44k/G_30400.pth" -c "configs/config.json" -n "君の知らない物語-src.wav" -t 0 -s "nen"
logs/44k/G_30400.pth是训练出来的权重,根据自己训练结果调整
君の知らない物語-src.wav  是需要换声的音频

最后一个参数nen是你需要换声的对象的名字,与之前的纯净人声的文件夹名字一致,比如这里就是eason,需要注意的是我这里只同时训练了一个歌手,多个歌手需要将不同歌手切片后的声音片段放在不用文件夹里面,并且需要用不用的文件名区分,比如周杰伦可以用Jay来命名。

注意!!!!如果使用whisper-ppg 声音编码器进行推理,需要将--clip设置为25,-lg设置为1。否则将无法正常推理。

推理结果会放在results文件夹里面,一首歌的结果可能会分成两片或更多,自己合成一下,然后跟之前accompaniment文件夹里面对应的背景声合成一下就完事了。

这篇关于关于Sovits的本地部署的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/326953

相关文章

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

MySQL 主从复制部署及验证(示例详解)

《MySQL主从复制部署及验证(示例详解)》本文介绍MySQL主从复制部署步骤及学校管理数据库创建脚本,包含表结构设计、示例数据插入和查询语句,用于验证主从同步功能,感兴趣的朋友一起看看吧... 目录mysql 主从复制部署指南部署步骤1.环境准备2. 主服务器配置3. 创建复制用户4. 获取主服务器状态5

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

如何在Ubuntu 24.04上部署Zabbix 7.0对服务器进行监控

《如何在Ubuntu24.04上部署Zabbix7.0对服务器进行监控》在Ubuntu24.04上部署Zabbix7.0监控阿里云ECS服务器,需配置MariaDB数据库、开放10050/1005... 目录软硬件信息部署步骤步骤 1:安装并配置mariadb步骤 2:安装Zabbix 7.0 Server

一文详解Git中分支本地和远程删除的方法

《一文详解Git中分支本地和远程删除的方法》在使用Git进行版本控制的过程中,我们会创建多个分支来进行不同功能的开发,这就容易涉及到如何正确地删除本地分支和远程分支,下面我们就来看看相关的实现方法吧... 目录技术背景实现步骤删除本地分支删除远程www.chinasem.cn分支同步删除信息到其他机器示例步骤

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe

Maven项目打包时添加本地Jar包的操作步骤

《Maven项目打包时添加本地Jar包的操作步骤》在Maven项目开发中,我们经常会遇到需要引入本地Jar包的场景,比如使用未发布到中央仓库的第三方库或者处理版本冲突的依赖项,本文将详细介绍如何通过M... 目录一、适用场景说明​二、核心操作命令​1. 命令格式解析​2. 实战案例演示​三、项目配置步骤​1

使用Python实现调用API获取图片存储到本地的方法

《使用Python实现调用API获取图片存储到本地的方法》开发一个自动化工具,用于从JSON数据源中提取图像ID,通过调用指定API获取未经压缩的原始图像文件,并确保下载结果与Postman等工具直接... 目录使用python实现调用API获取图片存储到本地1、项目概述2、核心功能3、环境准备4、代码实现