mirror of
https://github.com/RVC-Boss/GPT-SoVITS.git
synced 2026-07-13 11:31:11 +08:00
Merge ffb520ee54fafc83db3aa13db327266bab63904c into 13055fa56994e75a7152c176047c56c62bbeede4
This commit is contained in:
commit
ebf8dd138d
@ -287,8 +287,9 @@ class TTS_Config:
|
||||
configs: dict = self._load_configs(self.configs_path)
|
||||
|
||||
assert isinstance(configs, dict)
|
||||
version = configs.get("version", "v2").lower()
|
||||
assert version in ["v1", "v2", "v3", "v4"]
|
||||
version = "v2"
|
||||
if "custom" in configs and configs["custom"]["version"].lower() in ["v1", "v2", "v3", "v4"]:
|
||||
version = configs["custom"]["version"].lower()
|
||||
self.default_configs[version] = configs.get(version, self.default_configs[version])
|
||||
self.configs: dict = configs.get("custom", deepcopy(self.default_configs[version]))
|
||||
|
||||
@ -467,7 +468,7 @@ class TTS:
|
||||
version, model_version, if_lora_v3 = get_sovits_version_from_path_fast(weights_path)
|
||||
path_sovits = self.configs.default_configs[model_version]["vits_weights_path"]
|
||||
|
||||
if if_lora_v3 == True and os.path.exists(path_sovits) == False:
|
||||
if model_version in {"v3", "v4"} and os.path.exists(path_sovits) == False:
|
||||
info = path_sovits + i18n("SoVITS %s 底模缺失,无法加载相应 LoRA 权重"%model_version)
|
||||
raise FileExistsError(info)
|
||||
|
||||
@ -519,7 +520,7 @@ class TTS:
|
||||
if "pretrained" not in weights_path and hasattr(vits_model, "enc_q"):
|
||||
del vits_model.enc_q
|
||||
|
||||
if if_lora_v3 == False:
|
||||
if model_version not in {"v3", "v4"}:
|
||||
print(
|
||||
f"Loading VITS weights from {weights_path}. {vits_model.load_state_dict(dict_s2['weight'], strict=False)}"
|
||||
)
|
||||
@ -614,9 +615,6 @@ class TTS:
|
||||
self.vocoder_configs["upsample_rate"] = 480
|
||||
self.vocoder_configs["overlapped_len"] = 12
|
||||
|
||||
|
||||
|
||||
|
||||
self.vocoder = self.vocoder.eval()
|
||||
if self.configs.is_half == True:
|
||||
self.vocoder = self.vocoder.half().to(self.configs.device)
|
||||
@ -1256,7 +1254,7 @@ class TTS:
|
||||
speed_factor,
|
||||
False,
|
||||
fragment_interval,
|
||||
super_sampling if self.configs.use_vocoder and self.configs.version == "v3" else False,
|
||||
super_sampling if self.configs.use_vocoder and self.configs.version in {"v3", "v4"} else False,
|
||||
)
|
||||
else:
|
||||
audio.append(batch_audio_fragment)
|
||||
@ -1277,7 +1275,7 @@ class TTS:
|
||||
speed_factor,
|
||||
split_bucket,
|
||||
fragment_interval,
|
||||
super_sampling if self.configs.use_vocoder and self.configs.version == "v3" else False,
|
||||
super_sampling if self.configs.use_vocoder and self.configs.version in {"v3", "v4"} else False,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@ -91,6 +91,8 @@ infer_ttswebui = os.environ.get("infer_ttswebui", 9872)
|
||||
infer_ttswebui = int(infer_ttswebui)
|
||||
is_share = os.environ.get("is_share", "False")
|
||||
is_share = eval(is_share)
|
||||
local_mode = os.environ.get("local_mode", "False")
|
||||
local_mode = eval(local_mode)
|
||||
if "_CUDA_VISIBLE_DEVICES" in os.environ:
|
||||
os.environ["CUDA_VISIBLE_DEVICES"] = os.environ["_CUDA_VISIBLE_DEVICES"]
|
||||
is_half = eval(os.environ.get("is_half", "True")) and torch.cuda.is_available()
|
||||
@ -1273,7 +1275,7 @@ with gr.Blocks(title="GPT-SoVITS WebUI") as app:
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.queue().launch( # concurrency_count=511, max_size=1022
|
||||
server_name="0.0.0.0",
|
||||
server_name="127.0.0.1" if local_mode else "0.0.0.0",
|
||||
inbrowser=True,
|
||||
share=is_share,
|
||||
server_port=infer_ttswebui,
|
||||
|
||||
110
api.py
110
api.py
@ -163,7 +163,7 @@ from transformers import AutoModelForMaskedLM, AutoTokenizer
|
||||
import numpy as np
|
||||
from feature_extractor import cnhubert
|
||||
from io import BytesIO
|
||||
from module.models import SynthesizerTrn, SynthesizerTrnV3
|
||||
from module.models import SynthesizerTrn, SynthesizerTrnV3, Generator
|
||||
from peft import LoraConfig, get_peft_model
|
||||
from AR.models.t2s_lightning_module import Text2SemanticLightningModule
|
||||
from text import cleaned_text_to_sequence
|
||||
@ -176,9 +176,9 @@ import subprocess
|
||||
|
||||
class DefaultRefer:
|
||||
def __init__(self, path, text, language):
|
||||
self.path = args.default_refer_path
|
||||
self.text = args.default_refer_text
|
||||
self.language = args.default_refer_language
|
||||
self.path = path
|
||||
self.text = text
|
||||
self.language = language
|
||||
|
||||
def is_ready(self) -> bool:
|
||||
return is_full(self.path, self.text, self.language)
|
||||
@ -214,6 +214,38 @@ def init_bigvgan():
|
||||
else:
|
||||
bigvgan_model = bigvgan_model.to(device)
|
||||
|
||||
def init_vocoder(version: str):
|
||||
global bigvgan_model
|
||||
from BigVGAN import bigvgan
|
||||
|
||||
if version == "v3":
|
||||
bigvgan_model = bigvgan.BigVGAN.from_pretrained(
|
||||
"%s/GPT_SoVITS/pretrained_models/models--nvidia--bigvgan_v2_24khz_100band_256x" % (now_dir,),
|
||||
use_cuda_kernel=False,
|
||||
) # if True, RuntimeError: Ninja is required to load C++ extensions
|
||||
# remove weight norm in the model and set to eval mode
|
||||
bigvgan_model.remove_weight_norm()
|
||||
bigvgan_model = bigvgan_model.eval()
|
||||
|
||||
elif version == "v4":
|
||||
bigvgan_model = Generator(
|
||||
initial_channel=100,
|
||||
resblock="1",
|
||||
resblock_kernel_sizes=[3, 7, 11],
|
||||
resblock_dilation_sizes=[[1, 3, 5], [1, 3, 5], [1, 3, 5]],
|
||||
upsample_rates=[10, 6, 2, 2, 2],
|
||||
upsample_initial_channel=512,
|
||||
upsample_kernel_sizes=[20, 12, 4, 4, 4],
|
||||
gin_channels=0, is_bias=True
|
||||
)
|
||||
bigvgan_model.remove_weight_norm()
|
||||
state_dict_g = torch.load("%s/GPT_SoVITS/pretrained_models/gsv-v4-pretrained/vocoder.pth" % (now_dir,), map_location="cpu")
|
||||
bigvgan_model.load_state_dict(state_dict_g)
|
||||
|
||||
if is_half == True:
|
||||
bigvgan_model = bigvgan_model.half().to(device)
|
||||
else:
|
||||
bigvgan_model = bigvgan_model.to(device)
|
||||
|
||||
resample_transform_dict = {}
|
||||
|
||||
@ -253,6 +285,20 @@ mel_fn = lambda x: mel_spectrogram_torch(
|
||||
},
|
||||
)
|
||||
|
||||
mel_fn_v4 = lambda x: mel_spectrogram_torch(
|
||||
x,
|
||||
**{
|
||||
"n_fft": 1280,
|
||||
"win_size": 1280,
|
||||
"hop_size": 320,
|
||||
"num_mels": 100,
|
||||
"sampling_rate": 32000,
|
||||
"fmin": 0,
|
||||
"fmax": None,
|
||||
"center": False,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
sr_model = None
|
||||
|
||||
@ -294,11 +340,11 @@ from process_ckpt import get_sovits_version_from_path_fast, load_sovits_new
|
||||
|
||||
def get_sovits_weights(sovits_path):
|
||||
path_sovits_v3 = "GPT_SoVITS/pretrained_models/s2Gv3.pth"
|
||||
is_exist_s2gv3 = os.path.exists(path_sovits_v3)
|
||||
path_sovits_v4 = "GPT_SoVITS/pretrained_models/gsv-v4-pretrained/s2Gv4.pth"
|
||||
|
||||
version, model_version, if_lora_v3 = get_sovits_version_from_path_fast(sovits_path)
|
||||
if if_lora_v3 == True and is_exist_s2gv3 == False:
|
||||
logger.info("SoVITS V3 底模缺失,无法加载相应 LoRA 权重")
|
||||
if (if_lora_v3 == True and not os.path.exists(path_sovits_v3)) or (model_version == "v4" and not os.path.exists(path_sovits_v4)):
|
||||
logger.info(f"SoVITS {model_version.upper()} 底模缺失,无法加载相应 LoRA 权重")
|
||||
|
||||
dict_s2 = load_sovits_new(sovits_path)
|
||||
hps = dict_s2["config"]
|
||||
@ -311,11 +357,8 @@ def get_sovits_weights(sovits_path):
|
||||
else:
|
||||
hps.model.version = "v2"
|
||||
|
||||
if model_version == "v3":
|
||||
hps.model.version = "v3"
|
||||
|
||||
model_params_dict = vars(hps.model)
|
||||
if model_version != "v3":
|
||||
if model_version not in {"v3", "v4"}:
|
||||
vq_model = SynthesizerTrn(
|
||||
hps.data.filter_length // 2 + 1,
|
||||
hps.train.segment_size // hps.data.hop_length,
|
||||
@ -323,14 +366,16 @@ def get_sovits_weights(sovits_path):
|
||||
**model_params_dict,
|
||||
)
|
||||
else:
|
||||
model_params_dict["version"]=model_version
|
||||
vq_model = SynthesizerTrnV3(
|
||||
hps.data.filter_length // 2 + 1,
|
||||
hps.train.segment_size // hps.data.hop_length,
|
||||
n_speakers=hps.data.n_speakers,
|
||||
**model_params_dict,
|
||||
)
|
||||
init_bigvgan()
|
||||
model_version = hps.model.version
|
||||
# init_bigvgan()
|
||||
init_vocoder(model_version)
|
||||
|
||||
logger.info(f"模型版本: {model_version}")
|
||||
if "pretrained" not in sovits_path:
|
||||
try:
|
||||
@ -342,10 +387,13 @@ def get_sovits_weights(sovits_path):
|
||||
else:
|
||||
vq_model = vq_model.to(device)
|
||||
vq_model.eval()
|
||||
if if_lora_v3 == False:
|
||||
if model_version not in {"v3", "v4"}:
|
||||
vq_model.load_state_dict(dict_s2["weight"], strict=False)
|
||||
else:
|
||||
vq_model.load_state_dict(load_sovits_new(path_sovits_v3)["weight"], strict=False)
|
||||
if model_version == "v4":
|
||||
vq_model.load_state_dict(load_sovits_new(path_sovits_v4)["weight"], strict=False)
|
||||
else:
|
||||
vq_model.load_state_dict(load_sovits_new(path_sovits_v3)["weight"], strict=False)
|
||||
lora_rank = dict_s2["lora_rank"]
|
||||
lora_config = LoraConfig(
|
||||
target_modules=["to_k", "to_q", "to_v", "to_out.0"],
|
||||
@ -394,13 +442,11 @@ def change_gpt_sovits_weights(gpt_path, sovits_path):
|
||||
try:
|
||||
gpt = get_gpt_weights(gpt_path)
|
||||
sovits = get_sovits_weights(sovits_path)
|
||||
speaker_list["default"] = Speaker(name="default", gpt=gpt, sovits=sovits)
|
||||
return JSONResponse({"code": 0, "message": "Success"}, status_code=200)
|
||||
except Exception as e:
|
||||
return JSONResponse({"code": 400, "message": str(e)}, status_code=400)
|
||||
|
||||
speaker_list["default"] = Speaker(name="default", gpt=gpt, sovits=sovits)
|
||||
return JSONResponse({"code": 0, "message": "Success"}, status_code=200)
|
||||
|
||||
|
||||
|
||||
def get_bert_feature(text, word2ph):
|
||||
with torch.no_grad():
|
||||
inputs = tokenizer(text, return_tensors="pt")
|
||||
@ -759,7 +805,7 @@ def get_tts_wav(
|
||||
prompt_semantic = codes[0, 0]
|
||||
prompt = prompt_semantic.unsqueeze(0).to(device)
|
||||
|
||||
if version != "v3":
|
||||
if version not in {"v3", "v4"}:
|
||||
refers = []
|
||||
if inp_refs:
|
||||
for path in inp_refs:
|
||||
@ -810,8 +856,7 @@ def get_tts_wav(
|
||||
)
|
||||
pred_semantic = pred_semantic[:, -idx:].unsqueeze(0)
|
||||
t3 = ttime()
|
||||
|
||||
if version != "v3":
|
||||
if version not in {"v3", "v4"}:
|
||||
audio = (
|
||||
vq_model.decode(pred_semantic, torch.LongTensor(phones2).to(device).unsqueeze(0), refers, speed=speed)
|
||||
.detach()
|
||||
@ -830,16 +875,18 @@ def get_tts_wav(
|
||||
if sr != 24000:
|
||||
ref_audio = resample(ref_audio, sr)
|
||||
# print("ref_audio",ref_audio.abs().mean())
|
||||
mel2 = mel_fn(ref_audio)
|
||||
mel2 = mel_fn_v4(ref_audio) if version == "v4" else mel_fn(ref_audio)
|
||||
mel2 = norm_spec(mel2)
|
||||
T_min = min(mel2.shape[2], fea_ref.shape[2])
|
||||
mel2 = mel2[:, :, :T_min]
|
||||
fea_ref = fea_ref[:, :, :T_min]
|
||||
if T_min > 468:
|
||||
mel2 = mel2[:, :, -468:]
|
||||
fea_ref = fea_ref[:, :, -468:]
|
||||
T_min = 468
|
||||
chunk_len = 934 - T_min
|
||||
T_ref = 500 if version == "v4" else 468
|
||||
T_chunk = 1000 if version == "v4" else 934
|
||||
if T_min > T_ref:
|
||||
mel2 = mel2[:, :, -T_ref:]
|
||||
fea_ref = fea_ref[:, :, -T_ref:]
|
||||
T_min = T_ref
|
||||
chunk_len = T_chunk - T_min
|
||||
# print("fea_ref",fea_ref,fea_ref.shape)
|
||||
# print("mel2",mel2)
|
||||
mel2 = mel2.to(dtype)
|
||||
@ -867,7 +914,8 @@ def get_tts_wav(
|
||||
cmf_res = torch.cat(cfm_resss, 2)
|
||||
cmf_res = denorm_spec(cmf_res)
|
||||
if bigvgan_model == None:
|
||||
init_bigvgan()
|
||||
# init_bigvgan()
|
||||
init_vocoder(version)
|
||||
with torch.inference_mode():
|
||||
wav_gen = bigvgan_model(cmf_res)
|
||||
audio = wav_gen[0][0].cpu().detach().numpy()
|
||||
@ -880,7 +928,7 @@ def get_tts_wav(
|
||||
audio_opt = np.concatenate(audio_opt, 0)
|
||||
t4 = ttime()
|
||||
|
||||
sr = hps.data.sampling_rate if version != "v3" else 24000
|
||||
sr = hps.data.sampling_rate if version != "v3" and version != "v4" else 24000
|
||||
if if_sr and sr == 24000:
|
||||
audio_opt = torch.from_numpy(audio_opt).float().to(device)
|
||||
audio_opt, sr = audio_sr(audio_opt.unsqueeze(0), sr)
|
||||
|
||||
@ -30,6 +30,9 @@ webui_port_subfix = 9871
|
||||
|
||||
api_port = 9880
|
||||
|
||||
# 设置为True可启用本地模式,该模式只允许本机访问,避免出现潜在安全问题。默认为False。
|
||||
local_mode = False
|
||||
|
||||
if infer_device == "cuda":
|
||||
gpu_name = torch.cuda.get_device_name(0)
|
||||
if (
|
||||
|
||||
@ -298,6 +298,7 @@ if __name__ == "__main__":
|
||||
parser.add_argument("--json_key_text", default="text", help="the text key name in json, Default: text")
|
||||
parser.add_argument("--json_key_path", default="wav_path", help="the path key name in json, Default: wav_path")
|
||||
parser.add_argument("--g_batch", default=10, help="max number g_batch wav to display, Default: 10")
|
||||
parser.add_argument("--local_mode", action="store_true", help="enable local mode (bind to 127.0.0.1)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@ -407,7 +408,7 @@ if __name__ == "__main__":
|
||||
)
|
||||
|
||||
demo.launch(
|
||||
server_name="0.0.0.0",
|
||||
server_name="127.0.0.1" if args.local_mode else "0.0.0.0",
|
||||
inbrowser=True,
|
||||
# quiet=True,
|
||||
share=eval(args.is_share),
|
||||
|
||||
@ -32,6 +32,7 @@ device = sys.argv[1]
|
||||
is_half = eval(sys.argv[2])
|
||||
webui_port_uvr5 = int(sys.argv[3])
|
||||
is_share = eval(sys.argv[4])
|
||||
local_mode = sys.argv[5].lower() == 'true' if len(sys.argv) > 5 else False
|
||||
|
||||
|
||||
def html_left(text, label="p"):
|
||||
@ -220,7 +221,7 @@ with gr.Blocks(title="UVR5 WebUI") as app:
|
||||
api_name="uvr_convert",
|
||||
)
|
||||
app.queue().launch( # concurrency_count=511, max_size=1022
|
||||
server_name="0.0.0.0",
|
||||
server_name="127.0.0.1" if local_mode else "0.0.0.0",
|
||||
inbrowser=True,
|
||||
share=is_share,
|
||||
server_port=webui_port_uvr5,
|
||||
|
||||
8
webui.py
8
webui.py
@ -74,6 +74,7 @@ from config import (
|
||||
webui_port_main,
|
||||
webui_port_subfix,
|
||||
webui_port_uvr5,
|
||||
local_mode,
|
||||
)
|
||||
from tools import my_utils
|
||||
from tools.i18n.i18n import I18nAuto, scan_language_list
|
||||
@ -388,6 +389,8 @@ def change_label(path_list):
|
||||
webui_port_subfix,
|
||||
is_share,
|
||||
)
|
||||
if local_mode:
|
||||
cmd += " --local_mode"
|
||||
yield (
|
||||
process_info(process_name_subfix, "opened"),
|
||||
{"__type__": "update", "visible": False},
|
||||
@ -412,6 +415,8 @@ def change_uvr5():
|
||||
global p_uvr5
|
||||
if p_uvr5 is None:
|
||||
cmd = '"%s" tools/uvr5/webui.py "%s" %s %s %s' % (python_exec, infer_device, is_half, webui_port_uvr5, is_share)
|
||||
if local_mode:
|
||||
cmd += " True"
|
||||
yield (
|
||||
process_info(process_name_uvr5, "opened"),
|
||||
{"__type__": "update", "visible": False},
|
||||
@ -450,6 +455,7 @@ def change_tts_inference(bert_path, cnhubert_base_path, gpu_number, gpt_path, so
|
||||
os.environ["is_half"] = str(is_half)
|
||||
os.environ["infer_ttswebui"] = str(webui_port_infer_tts)
|
||||
os.environ["is_share"] = str(is_share)
|
||||
os.environ["local_mode"] = str(local_mode)
|
||||
yield (
|
||||
process_info(process_name_tts, "opened"),
|
||||
{"__type__": "update", "visible": False},
|
||||
@ -1955,7 +1961,7 @@ with gr.Blocks(title="GPT-SoVITS WebUI") as app:
|
||||
gr.Markdown(value=i18n("施工中,请静候佳音"))
|
||||
|
||||
app.queue().launch( # concurrency_count=511, max_size=1022
|
||||
server_name="0.0.0.0",
|
||||
server_name="127.0.0.1" if local_mode else "0.0.0.0",
|
||||
inbrowser=True,
|
||||
share=is_share,
|
||||
server_port=webui_port_main,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user