Python - Bert-VITS2 自定义训练语音

news2024/9/23 11:13:50

目录

一.引言

二.前期准备

1.Conda 环境搭建

2.Bert 模型下载

3.预训练模型下载 

三.数据准备

1.音频文件批量处理

2.训练文件地址生成

3.模型训练配置生成

4.训练文件重采样

5.Tensor pt 文件生成

四.模型训练

1.预训练模型

2.模型训练

3.模型收菜

五.总结


一.引言

前面我们通过视频 OCR 技术识别老剧台词、通过 Wave2Lip 技术实现人声同步、通过 GFP_GAN 实现图像人脸增强,还通过 Real-ESRGAN 实现了图像质量增强,相当于实现了图片、视频的全方位处理,本文基于语音进行自定义处理,通过 Bert-VITS2 训练自定义语音,模仿指定角色发声。

二.前期准备

1.Conda 环境搭建

git 地址: https://github.com/fishaudio/Bert-VITS2/

博主网不好,直接把代码下载下来了再传到服务器了。

cd Bert-VITS2-master
 
conda create -n vits2 python=3.9
conda activate vits2
 
pip install torch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2
pip install -r requirements.txt
 
pip install openai-whisper

如果在国内安装比较慢,可以在 pip 命令后指定源,博主这里使用清华源:

pip install xxx -i https://pypi.tuna.tsinghua.edu.cn/simple

执行完毕后激活环境:

conda activate vits2

2.Bert 模型下载

这里主要下载中文、英文、日文的相关 Bert 模型,用来识别文字,为什么有日本版本,后面了解了一下这个开源项目里很多大佬都喜欢玩原神,所以很多语音需要用到。这也可能是为什么 git 里开发大佬们的头像都很二次元的原因。

Tips:

这里最新版本需要下载 4 个 Bert 模型,老版本需要 3 个,大家可以在运行时关注模型的报错信息,一般是 Connection 请求失败,此时会打日志告知请求哪个 Hugging Face 的链接失败了,我们找到这个链接并在 bert 目录下找到对应文件地址,把模型文件都下进来就可以,这个比较有普适性。

◆ 中文

链接: https://huggingface.co/hfl/chinese-roberta-wwm-ext-large/tree/main

下载 pytorch_model.bin 文件,放置到 bert/chinese-roberta-wwm-ext-large/ 文件夹下:

◆ 英文

链接:  https://huggingface.co/microsoft/deberta-v3-large/tree/main

下载 pytroch_model.bin 与 spm.model,放置到 bert/deberta-v3-large/ 文件夹下:

◆ 日文- 1

链接: https://huggingface.co/ku-nlp/deberta-v2-large-japanese/tree/main

下载 pytorch_model.bin,放置到 bert/deberta-v2-large-japanese/ 文件夹下:

◆ 日文- 2

 链接: https://huggingface.co/ku-nlp/deberta-v2-large-japanese-char-wwm

下载 pytorch_model.bin,放置到 bert/deberta-v2-large-japanese-char-wwm/ 文件夹下:

3.预训练模型下载 

预训练模型链接: https://openi.pcl.ac.cn/Stardust_minus/Bert-VITS2/

上面的链接包含 "Bert-VITS2中日底模" 文件,大家需要在页面注册后才能下载,模型下载后放到 /data/models 目录下,这里需要事先在 git 目录下 mkdir data 创建 data 文件夹:

三.数据准备

1.音频文件批量处理

由于我们的任务是训练学习目标角色的声音,所以需要准备对应角色的语音片段,语音是 mp3 格式,但是音频处理一般都会转换为 wav 格式。

◆ 创建文件地址

首先在项目内创建文件夹存储对应音频内容:

mkdir -p data
mkdir -p data/long
mkdir -p data/short
mkdir -p data/long/swk

这里 long 存放长语音,short 存放短语音,当然如果你是现成切好的,那就直接都放到 short 就可以,这里博主准备了一段孙悟空的长语音放在 long 文件夹下。

◆ 长短语音切割

在项目内创建 spilit_reg.py,在 main 函数下的 persons 数组内传入 long 文件夹内角色的名称,如果有多个角色训练样本,可以在数组中传入多个。

import os
from pathlib import Path
import librosa
from scipy.io import wavfile
import numpy as np
import whisper
 
 
def split_long_audio(model, filepaths, save_dir, person, out_sr=44100):
    files = os.listdir(filepaths)
    filepaths=[os.path.join(filepaths, i) for i in files]
 
    for file_idx, filepath in enumerate(filepaths):
 
        save_path = Path(save_dir)
        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"{person}_{i}.wav"
            i += 1
            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语音识别
def transcribe_one(audio_path): 
    audio = whisper.load_audio(audio_path)
    audio = whisper.pad_or_trim(audio)
    mel = whisper.log_mel_spectrogram(audio).to(model.device)
    _, probs = model.detect_language(mel)
    print(f"Detected language: {max(probs, key=probs.get)}")
    lang = max(probs, key=probs.get)
    options = whisper.DecodingOptions(beam_size=5)
    result = whisper.decode(model, mel, options)
 
    print(result.text)
    return result.text
 
 
if __name__ == '__main__':
    whisper_size = "medium"
    model = whisper.load_model(whisper_size)
 
    persons = ['swk']
 
    for person in persons:
        audio_path = f"./data/short/{person}"
        if os.path.exists(audio_path):
            for filename in os.listdir(audio_path):
                file_path = os.path.join(audio_path, filename)
                os.remove(file_path)
        split_long_audio(model, f"./data/long/{person}", f"./data/short/{person}", person)
        files = os.listdir(audio_path)
        file_list_sorted = sorted(files, key=lambda x: int(os.path.splitext(x)[0].split('_')[1]))
        filepaths = [os.path.join(audio_path, i) for i in file_list_sorted]
        for file_idx, filepath in enumerate(filepaths):
            text = transcribe_one(filepath)
            with open(f"./data/short/{person}/{person}_{file_idx}.lab", 'w') as f:
                f.write(text)

上面的代码会把长音频分割为多个短音频,并且识别语音内容,结果放置在 /data/short 下对应的 peoson 目录中: 

python  spilit_reg.py 

wav 为切割后的短音频,lab 为语音识别的内容。 

2.训练文件地址生成

在项目下 vim gen_filelist.py

import os
 
out_file = f"filelists/full.txt"
 
def process():
    persons = ['swk']
    ch_language = 'ZH'
 
    with open(out_file, 'w', encoding="Utf-8") as wf:        
        for person in persons:
            path = f"./data/short/{person}"
            files = os.listdir(path)
            for f in files:
                if f.endswith(".lab"):
                    with open(os.path.join(path, f), 'r', encoding="utf-8") as perFile:
                        line = perFile.readline() 
                        result = f"./data/short/{person}/{f.split('.')[0]}.wav|{person}|{ch_language}|{line}"
                        wf.write(f"{result}\n")
 
 
if __name__ == "__main__":
    process()

和上面一样,将 persons 文件夹写入自己的单个或多个角色名称对应的文件夹名字,语言就 ZH 即中文。

python gen_filelist.py

运行后在 filelists 文件夹下生成 full.txt 文件,其内部保存了训练地址与中文以及音频的对应:

...

./data/short/swk/swk_3.wav|swk|ZH|不见
./data/short/swk/swk_82.wav|swk|ZH|早上喂養白馬水草條魚

...

3.模型训练配置生成

◆ 默认配置生成

python preprocess_text.py

第一次执行 preprocess_text.py 文件会基于 configs 的文件生成默认的 config.yml 配置文件。

已根据默认配置文件default_config.yml生成配置文件config.yml。请按该配置文件的说明进行配置后重新运行。
如无特殊需求,请勿修改default_config.yml或备份该文件。

◆ 自定义配置

配置文件很长,我们主要改变下面几项:

- resample 对应我们的输入输出数据地址

- preprocess_text 对应我们预处理后生成的文件对应地址

- bert_gen bert 生成的配置文件地址,这个是源代码自带的,可以修改

- train_ms 配置训练的内容,models 为基座模型即我们上面刚下的预训练模型

- webui 这里根据自己情况定,博主在服务器上非本机开发,所以没有用 webui

dataset_path: ""
 
resample:
  in_dir: "data/short" 
  out_dir: "data/short"
 
preprocess_text:
  transcription_path: "filelists/full.txt"
  cleaned_path: ""
  train_path: "filelists/train.txt"
  val_path: "filelists/val.txt"
  config_path: "configs/config.json"
 
bert_gen:
  config_path: "configs/config.json"
 
train_ms:
  model: "data/models"
  config_path: "configs/config.json"
 
webui:
  device: "cuda"
  model: "models/G_8000.pth"
  config_path: "configs/config.json"

除此之外,一些更详细的配置,例如 train_ms 里训练的 epoch 等等,可以在 configs/config.json 查看并修改:

◆ 更新配置生成

python preprocess_text.py

上面的配置修改完成后,再次运行会基于配置分割 train/val 并放置到 filelists 文件夹下: 

4.训练文件重采样

上面配置中指定了 resampel 的目录,我们再次运行即可实现 resample,resample 后会覆盖之前的 wav 文件。

5.Tensor pt 文件生成

python bert_gen.py

运行 bert_gen 代码,在对应 persons 的 short 目录下,会新增 .pt 文件,至此我们的数据准备完毕,链路比较长,但是多操作几次发现都是固定套路,这里 bert 语音识别时运行时间稍长需要耐心等待:

四.模型训练

1.预训练模型

上面前期准备我们已经准备了底模文件作为我们训练的 baseline,后续的新模型将基于 baseline  进行,这里有三个文件:

- D_0.pth

生成对抗网络里判别器 (Discriminator) 的初始数据,其负责区分真实数据和生成器生成的假数据。

- DUR_0.pth

这里博主没有细看论文,不太确定这模型的作用,不过大致看提到过几次 Duration,不知道是不是和音频时长相关。

- G_0.pth

生成对抗网络中生成器 (Generator) 的权重,其任务是生成以假乱真的数据。

2.模型训练

训练数据放在了 data/short 文件下,大家也可以自己修改,只要预处理步骤还有 config.yml 文件能够互相匹配即可,训练配置则到 configs/config.json 修改即可:

nohup python train_ms.py > log 2>&1 &

后台开启训练,出现下述日志代表训练开始:

Tips:

这里有几个点可能需要修改,否则会训练报错。

◆ LocalRank

在 train_ms.py 上方加入一行代码,否则可能会报错 KeyError: 'Local_RANK':

os.environ["LOCAL_RANK"] = '0'

◆ Float64

博主采用 V100 显卡训练,提示不支持 torch.bfloat16 格式,所以需要把 train_ms.py 里用到 bfloat16 的都修改为 float16,大家可以根据自己的显卡情况调整,能支持的话最好。

3.模型收菜

训练配置中默认保留最近的 8 个 Checkpoint,所以 D/G/DUR 都保存了近半个以及原始的模型权重:

这里训练了 1000 个 epoch:

模型训练部分的分享就到这里,后面有空我们继续分享如何使用自定义模型进行推理。

五.总结

视频识别 OCR: https://blog.csdn.net/BIT_666/article/details/134308219

人脸修复 GFP_GAN: https://blog.csdn.net/BIT_666/article/details/134263119

图声对应 Wave2Lip: https://blog.csdn.net/BIT_666/article/details/134506504

画质提升 Real-ESRGAN :https://blog.csdn.net/BIT_666/article/details/134688586 

上面是前面一段时间分享的图像、视频以及语音的相关算法内容,大家有兴趣也可以根据对应步骤去本机实现,本文 VITS2 语音生成服务特别感谢下文老哥提供的训练思路:

@智慧医疗探索者: https://blog.csdn.net/lsb2002/article/details/134294018

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1369081.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flask修改Response Headers中的Server值

Headers中的Server会暴露出Python版本,导致的结果就是方便被渗透快速定位Python版本后找到对应版本的漏洞,因此导致网络安全问题 伪方法: 像这个马上就暴露出Python版本,如何解决这个网络上有说直接用response.headers.remove(Ser…

STL标准库与泛型编程(侯捷)笔记6(完结)

STL标准库与泛型编程(侯捷) 本文是学习笔记,仅供个人学习使用。如有侵权,请联系删除。 参考链接 Youbute: 侯捷-STL标准库与泛型编程 B站: 侯捷 - STL Github:STL源码剖析中源码 https://github.com/SilverMaple/STLSourceCo…

diffusers加速文生图速度;stable-diffusion、PixArt-α

参考: https://pytorch.org/blog/accelerating-generative-ai-3/ https://colab.research.google.com/drive/1jZ5UZXk7tcpTfVwnX33dDuefNMcnW9ME?usp=sharing#scrollTo=jueYhY5YMe22 大概GPU资源8G-16G;另外模型资源下载慢可以在国内镜像:https://aifasthub.com/ 1、加速…

RK3568上如何使用MPP进行硬解码

目录 前言正文一、FFmpeg 拉流处理二、RK3568 mpp硬解码1、简介2、普通mpp解码流程3、核心代码 END、总结的知识与问题1、一直出现jitter buffer full 这样的问题2、如何打印帧率?3、分析av_packet_alloc、av_init_packet、av_packet_unref、av_packet_free、av_fra…

尤雨溪:框架挖坑靠文档来补,这算 PUA 用户吗?丨 RTE 开发者日报 Vol.122

开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE (Real Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

经典八股文之RocketMQ

核心概念 NameServer nameserver是整个rocketmq的大脑,是rocketmq的注册中心。broker在启动时向所有nameserver注册。生产者在发送消息之前先从 NameServer 获取 Broker 服务器地址列表(消费者一 样),然后根据负载均衡算法从列表中选择一台服务器进行消…

ADKEY多按键制作阻值选择2(回答网友问题)

回答网友的问题 网友原来的电路图 adc组合按键电阻阻值参考_ad 检测四个开关 阻值-CSDN博客https://blog.csdn.net/weixin_43833645/article/details/128615455?spm1001.2014.3001.5501截图如下 现在对齐进行简化(少了一个按键) 其采样值列表如下图 …

Web3.0与虚拟现实:改变前端开发的新机遇

Hello大家好!我是咕噜的铁蛋!。近年来,Web3.0和虚拟现实技术的兴起引起了广泛的关注和讨论。它们不仅在互联网领域带来了革命性的变化,同时也给前端开发者带来了全新的机遇和挑战。今天铁蛋讲和大家一起探讨Web3.0与虚拟现实如何改…

游戏、设计选什么内存条?光威龙武系列DDR5量大管饱

如果你是一位PC玩家或者创作者,日常工作娱乐中,确实少不了大容量高频内存的支持,这样可以获得更高的工作效率,光威龙武系列DDR5内存条无疑是理想之选。它可以为计算机提供强劲的性能表现和稳定的运行体验,让我们畅玩游…

Python猜数游戏

文章目录 1 Game Rule2 Code3 Result 1 Game Rule 猜数字游戏目的是猜测出程序想出的数字,基本逻辑: 程序随机选择1到100之间的一个数字或任何其他数字组合; 然后它会要求玩家输入它的建议; 然后它会检查这个数字是否与计算机随…

React 入门 - 05(响应式与事件绑定)

本章内容 目录 一、响应式设计思想二、React 中的事件绑定 继上一节我们简单实现一个 TodoList来更加了解编写组件的一些细节。本节继续这个案例功能的完成。 一、响应式设计思想 1、在原生的 JS中,如果要实现点击”提交“按钮就将输入框的内容添加至页面列表中&…

mysql忘记root密码后怎么重置

mysql忘记root密码后重置方法【windows版本】 重置密码步骤停掉mysql服务跳过密码进入数据库在user表中重置密码使用新密码登录mysql到此,密码就成功修改了,完结,撒花~ 重置密码步骤 当我们忘记mysql的密码时,连接mysql会报这样的…

虾皮商品标题:如何创建有效的虾皮商品标题

虾皮(Shopee)平台是一个非常受欢迎的电商平台,为卖家提供了一个广阔的销售渠道。在虾皮上,一个有效的商品标题是吸引潜在买家注意力的关键元素之一。一个好的商品标题能够吸引更多的点击和浏览量,从而提高销售机会。下…

vue设置height:100vh导致页面超出屏幕可以上下滑动

刚开始设置的height:100vh&#xff0c;就会出现如图的效果&#xff0c;会出现上下滚动 <template><view class"container">......</view> </template><style lang"scss">.container {height: 100vh;} </style> 解决方…

99%的人还不知道的私域流量管理工具

一、多个微信可以聚合管理 简单来讲这是一款一个窗口对多个个人微信号的聊天转化工具&#xff0c;一款集成众多功能的网页版聊天工具&#xff0c;支持多开N个微信号在同一个窗口&#xff0c;实现了集中会话&#xff0c;不用来回切换账号。 二、常用语快捷回复 可对常用的问题…

代码随想录算法训练营Day08|344.反转字符串、541. 反转字符串II、卡码网:替换数字、151.翻转字符串里的单词、卡码网:右旋字符串

文章目录 一、344.反转字符串1. 双指针法 二、541. 反转字符串II1. 字符串解法 三、卡码网&#xff1a;替换数字四、151.翻转字符串里的单词1.使用库函数2.自行编写函数3.创建字符数组填充3.双反转移位 五、卡码网&#xff1a;右旋字符串1. 自行编写函数 总结 一、344.反转字符…

专利:发明和实用新型的区别

上一篇给大家分享了专利&#xff0c;今天说一下发明和实用新型得区别。 什么是发明专利&#xff1f; 发明&#xff0c;是指对产品、方法或者其改进所提出的新的技术方案。发明与实用新型和外观设计一起&#xff0c;构成我国专利法所保护的对象。发明专利作为知识产权的一种&am…

面向设计师的11个必备AI工具

在当今快速发展的设计领域&#xff0c;人工智能&#xff08;AI&#xff09;工具已成为不可或缺的创新催化剂。这些工具专门用于提高效率和创造力&#xff0c;从而重新定义传统的设计方法。AI正在彻底改变设计师的工作方式&#xff0c;从自动处理任务到发掘新的创造力机会&#…

【微信支付】【java】Springboot对接开发微信支付

本文章是介绍java对接微信支付&#xff0c;包括微信预下单、支付、退款等等。 一、微信配置申请 1、微信支付配置申请 详细操作流程参考官方文档&#xff1a;https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml#part-1 配置完成需要以下信息&#xff1…

银河麒麟Kylin-Server-V10-SP3使用ISO镜像搭建本地内网YUM/DNF源cdrom/http

机房服务器安装一般是内网环境&#xff0c;需要配置本地的YUM/DNF源。本文介绍通过ISO镜像搭建内网环境的UM/DNF源 准备工作&#xff1a; 提前准备好Kylin-Server-V10-SP3的ISO镜像文件。 本机IP地址&#xff1a;192.168.40.201 镜像存放目录/data/iso/Kylin-Server-V10-SP3-Ge…