From 72b30ce777fd6745b3d343805e8820e3127fd149 Mon Sep 17 00:00:00 2001 From: starylan Date: Fri, 30 May 2025 00:26:48 +0800 Subject: [PATCH] docs(webui): Split i18n sentences for detection --- GPT_SoVITS/inference_webui.py | 229 +++++++++++++++++++++++------ GPT_SoVITS/inference_webui_fast.py | 165 +++++++++++++++++---- 2 files changed, 320 insertions(+), 74 deletions(-) diff --git a/GPT_SoVITS/inference_webui.py b/GPT_SoVITS/inference_webui.py index 46820145..c507b09a 100644 --- a/GPT_SoVITS/inference_webui.py +++ b/GPT_SoVITS/inference_webui.py @@ -66,8 +66,13 @@ else: with open("./weight.json", "r", encoding="utf-8") as file: weight_data = file.read() weight_data = json.loads(weight_data) - gpt_path = os.environ.get("gpt_path", weight_data.get("GPT", {}).get(version, pretrained_gpt_name)) - sovits_path = os.environ.get("sovits_path", weight_data.get("SoVITS", {}).get(version, pretrained_sovits_name)) + gpt_path = os.environ.get( + "gpt_path", weight_data.get("GPT", {}).get(version, pretrained_gpt_name) + ) + sovits_path = os.environ.get( + "sovits_path", + weight_data.get("SoVITS", {}).get(version, pretrained_sovits_name), + ) if isinstance(gpt_path, list): gpt_path = gpt_path[0] if isinstance(sovits_path, list): @@ -77,8 +82,12 @@ with open("./weight.json", "r", encoding="utf-8") as file: # "gpt_path", pretrained_gpt_name # ) # sovits_path = os.environ.get("sovits_path", pretrained_sovits_name) -cnhubert_base_path = os.environ.get("cnhubert_base_path", "GPT_SoVITS/pretrained_models/chinese-hubert-base") -bert_path = os.environ.get("bert_path", "GPT_SoVITS/pretrained_models/chinese-roberta-wwm-ext-large") +cnhubert_base_path = os.environ.get( + "cnhubert_base_path", "GPT_SoVITS/pretrained_models/chinese-hubert-base" +) +bert_path = os.environ.get( + "bert_path", "GPT_SoVITS/pretrained_models/chinese-roberta-wwm-ext-large" +) infer_ttswebui = os.environ.get("infer_ttswebui", 9872) infer_ttswebui = int(infer_ttswebui) is_share = os.environ.get("is_share", "False") @@ -222,7 +231,9 @@ def resample(audio_tensor, sr0, sr1): global resample_transform_dict key = "%s-%s" % (sr0, sr1) if key not in resample_transform_dict: - resample_transform_dict[key] = torchaudio.transforms.Resample(sr0, sr1).to(device) + resample_transform_dict[key] = torchaudio.transforms.Resample(sr0, sr1).to( + device + ) return resample_transform_dict[key](audio_tensor) @@ -239,8 +250,11 @@ def change_sovits_weights(sovits_path, prompt_language=None, text_language=None) print(sovits_path, version, model_version, if_lora_v3) is_exist = is_exist_s2gv3 if model_version == "v3" else is_exist_s2gv4 if if_lora_v3 == True and is_exist == False: - info = "GPT_SoVITS/pretrained_models/s2Gv3.pth" + i18n( - "SoVITS %s 底模缺失,无法加载相应 LoRA 权重" % model_version + info = ( + "GPT_SoVITS/pretrained_models/s2Gv3.pth" + + f"SoVITS {model_version}" + + " : " + + i18n("底模缺失,无法加载相应 LoRA 权重") ) gr.Warning(info) raise FileExistsError(info) @@ -255,7 +269,10 @@ def change_sovits_weights(sovits_path, prompt_language=None, text_language=None) prompt_text_update = {"__type__": "update", "value": ""} prompt_language_update = {"__type__": "update", "value": i18n("中文")} if text_language in list(dict_language.keys()): - text_update, text_language_update = {"__type__": "update"}, {"__type__": "update", "value": text_language} + text_update, text_language_update = {"__type__": "update"}, { + "__type__": "update", + "value": text_language, + } else: text_update = {"__type__": "update", "value": ""} text_language_update = {"__type__": "update", "value": i18n("中文")} @@ -276,12 +293,22 @@ def change_sovits_weights(sovits_path, prompt_language=None, text_language=None) "__type__": "update", "visible": visible_sample_steps, "value": 32 if model_version == "v3" else 8, - "choices": [4, 8, 16, 32, 64, 128] if model_version == "v3" else [4, 8, 16, 32], + "choices": ( + [4, 8, 16, 32, 64, 128] if model_version == "v3" else [4, 8, 16, 32] + ), }, {"__type__": "update", "visible": visible_inp_refs}, - {"__type__": "update", "value": False, "interactive": True if model_version not in v3v4set else False}, + { + "__type__": "update", + "value": False, + "interactive": True if model_version not in v3v4set else False, + }, {"__type__": "update", "visible": True if model_version == "v3" else False}, - {"__type__": "update", "value": i18n("模型加载中,请等待"), "interactive": False}, + { + "__type__": "update", + "value": i18n("模型加载中,请等待"), + "interactive": False, + }, ) dict_s2 = load_sovits_new(sovits_path) @@ -323,12 +350,17 @@ def change_sovits_weights(sovits_path, prompt_language=None, text_language=None) vq_model = vq_model.to(device) vq_model.eval() if if_lora_v3 == False: - print("loading sovits_%s" % model_version, vq_model.load_state_dict(dict_s2["weight"], strict=False)) + print( + "loading sovits_%s" % model_version, + vq_model.load_state_dict(dict_s2["weight"], strict=False), + ) else: path_sovits = path_sovits_v3 if model_version == "v3" else path_sovits_v4 print( "loading sovits_%spretrained_G" % model_version, - vq_model.load_state_dict(load_sovits_new(path_sovits)["weight"], strict=False), + vq_model.load_state_dict( + load_sovits_new(path_sovits)["weight"], strict=False + ), ) lora_rank = dict_s2["lora_rank"] lora_config = LoraConfig( @@ -355,10 +387,16 @@ def change_sovits_weights(sovits_path, prompt_language=None, text_language=None) "__type__": "update", "visible": visible_sample_steps, "value": 32 if model_version == "v3" else 8, - "choices": [4, 8, 16, 32, 64, 128] if model_version == "v3" else [4, 8, 16, 32], + "choices": ( + [4, 8, 16, 32, 64, 128] if model_version == "v3" else [4, 8, 16, 32] + ), }, {"__type__": "update", "visible": visible_inp_refs}, - {"__type__": "update", "value": False, "interactive": True if model_version not in v3v4set else False}, + { + "__type__": "update", + "value": False, + "interactive": True if model_version not in v3v4set else False, + }, {"__type__": "update", "visible": True if model_version == "v3" else False}, {"__type__": "update", "value": i18n("合成语音"), "interactive": True}, ) @@ -410,7 +448,8 @@ def init_bigvgan(): from BigVGAN import bigvgan bigvgan_model = bigvgan.BigVGAN.from_pretrained( - "%s/GPT_SoVITS/pretrained_models/models--nvidia--bigvgan_v2_24khz_100band_256x" % (now_dir,), + "%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 @@ -445,7 +484,8 @@ def init_hifigan(): hifigan_model.eval() hifigan_model.remove_weight_norm() state_dict_g = torch.load( - "%s/GPT_SoVITS/pretrained_models/gsv-v4-pretrained/vocoder.pth" % (now_dir,), map_location="cpu" + "%s/GPT_SoVITS/pretrained_models/gsv-v4-pretrained/vocoder.pth" % (now_dir,), + map_location="cpu", ) print("loading vocoder", hifigan_model.load_state_dict(state_dict_g)) if bigvgan_model: @@ -548,7 +588,9 @@ def get_phones_and_bert(text, language, version, final=False): formattext = chinese.mix_text_normalize(formattext) return get_phones_and_bert(formattext, "zh", version) else: - phones, word2ph, norm_text = clean_text_inf(formattext, language, version) + phones, word2ph, norm_text = clean_text_inf( + formattext, language, version + ) bert = get_bert_feature(norm_text, word2ph).to(device) elif language == "all_yue" and re.search(r"[A-Za-z]", formattext): formattext = re.sub(r"[a-z]", lambda x: x.group(0).upper(), formattext) @@ -674,7 +716,11 @@ def audio_sr(audio, sr): try: sr_model = AP_BWE(device, DictToAttrRecursive) except FileNotFoundError: - gr.Warning(i18n("你没有下载超分模型的参数,因此不进行超分。如想超分请先参照教程把文件下载好")) + gr.Warning( + i18n( + "你没有下载超分模型的参数,因此不进行超分。如想超分请先参照教程把文件下载好" + ) + ) return audio.cpu().detach().numpy(), sr return sr_model(audio, sr) @@ -752,7 +798,11 @@ def get_tts_wav( else: wav16k = wav16k.to(device) wav16k = torch.cat([wav16k, zero_wav_torch]) - ssl_content = ssl_model.model(wav16k.unsqueeze(0))["last_hidden_state"].transpose(1, 2) # .float() + ssl_content = ssl_model.model(wav16k.unsqueeze(0))[ + "last_hidden_state" + ].transpose( + 1, 2 + ) # .float() codes = vq_model.extract_latent(ssl_content) prompt_semantic = codes[0, 0] prompt = prompt_semantic.unsqueeze(0).to(device) @@ -779,7 +829,9 @@ def get_tts_wav( audio_opt = [] ###s2v3暂不支持ref_free if not ref_free: - phones1, bert1, norm_text1 = get_phones_and_bert(prompt_text, prompt_language, version) + phones1, bert1, norm_text1 = get_phones_and_bert( + prompt_text, prompt_language, version + ) for i_text, text in enumerate(texts): # 解决输入目标文本的空行导致报错的问题 @@ -792,7 +844,9 @@ def get_tts_wav( print(i18n("前端处理后的文本(每句):"), norm_text2) if not ref_free: bert = torch.cat([bert1, bert2], 1) - all_phoneme_ids = torch.LongTensor(phones1 + phones2).to(device).unsqueeze(0) + all_phoneme_ids = ( + torch.LongTensor(phones1 + phones2).to(device).unsqueeze(0) + ) else: bert = bert2 all_phoneme_ids = torch.LongTensor(phones2).to(device).unsqueeze(0) @@ -834,8 +888,13 @@ def get_tts_wav( if len(refers) == 0: refers = [get_spepc(hps, ref_wav_path).to(dtype).to(device)] audio = vq_model.decode( - pred_semantic, torch.LongTensor(phones2).to(device).unsqueeze(0), refers, speed=speed - )[0][0] # .cpu().detach().numpy() + pred_semantic, + torch.LongTensor(phones2).to(device).unsqueeze(0), + refers, + speed=speed, + )[0][ + 0 + ] # .cpu().detach().numpy() else: refer = get_spepc(hps, ref_wav_path).to(device).to(dtype) phoneme_ids0 = torch.LongTensor(phones1).to(device).unsqueeze(0) @@ -863,7 +922,9 @@ def get_tts_wav( T_min = Tref chunk_len = Tchunk - T_min mel2 = mel2.to(dtype) - fea_todo, ge = vq_model.decode_encp(pred_semantic, phoneme_ids1, refer, ge, speed) + fea_todo, ge = vq_model.decode_encp( + pred_semantic, phoneme_ids1, refer, ge, speed + ) cfm_resss = [] idx = 0 while 1: @@ -873,7 +934,11 @@ def get_tts_wav( idx += chunk_len fea = torch.cat([fea_ref, fea_todo_chunk], 2).transpose(2, 1) cfm_res = vq_model.cfm.inference( - fea, torch.LongTensor([fea.size(1)]).to(fea.device), mel2, sample_steps, inference_cfg_rate=0 + fea, + torch.LongTensor([fea.size(1)]).to(fea.device), + mel2, + sample_steps, + inference_cfg_rate=0, ) cfm_res = cfm_res[:, :, mel2.shape[2] :] mel2 = cfm_res[:, :, -T_min:] @@ -1000,7 +1065,13 @@ def cut5(inp): for i, char in enumerate(inp): if char in punds: - if char == "." and i > 0 and i < len(inp) - 1 and inp[i - 1].isdigit() and inp[i + 1].isdigit(): + if ( + char == "." + and i > 0 + and i < len(inp) - 1 + and inp[i - 1].isdigit() + and inp[i + 1].isdigit() + ): items.append(char) else: items.append(char) @@ -1038,13 +1109,21 @@ def process_text(texts): def change_choices(): SoVITS_names, GPT_names = get_weights_names(GPT_weight_root, SoVITS_weight_root) - return {"choices": sorted(SoVITS_names, key=custom_sort_key), "__type__": "update"}, { + return { + "choices": sorted(SoVITS_names, key=custom_sort_key), + "__type__": "update", + }, { "choices": sorted(GPT_names, key=custom_sort_key), "__type__": "update", } -SoVITS_weight_root = ["SoVITS_weights", "SoVITS_weights_v2", "SoVITS_weights_v3", "SoVITS_weights_v4"] +SoVITS_weight_root = [ + "SoVITS_weights", + "SoVITS_weights_v2", + "SoVITS_weights_v3", + "SoVITS_weights_v4", +] GPT_weight_root = ["GPT_weights", "GPT_weights_v2", "GPT_weights_v3", "GPT_weights_v4"] for path in SoVITS_weight_root + GPT_weight_root: os.makedirs(path, exist_ok=True) @@ -1081,9 +1160,13 @@ def html_left(text, label="p"): with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: gr.Markdown( - value=i18n("本软件以MIT协议开源, 作者不对软件具备任何控制力, 使用软件者、传播软件导出的声音者自负全责.") + value=i18n( + "本软件以MIT协议开源, 作者不对软件具备任何控制力, 使用软件者、传播软件导出的声音者自负全责." + ) + "
" - + i18n("如不认可该条款, 则不能使用或引用软件包内任何代码和文件. 详见根目录LICENSE.") + + i18n( + "如不认可该条款, 则不能使用或引用软件包内任何代码和文件. 详见根目录LICENSE." + ) ) with gr.Group(): gr.Markdown(html_center(i18n("模型切换"), "h3")) @@ -1102,11 +1185,19 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: interactive=True, scale=14, ) - refresh_button = gr.Button(i18n("刷新模型路径"), variant="primary", scale=14) - refresh_button.click(fn=change_choices, inputs=[], outputs=[SoVITS_dropdown, GPT_dropdown]) + refresh_button = gr.Button( + i18n("刷新模型路径"), variant="primary", scale=14 + ) + refresh_button.click( + fn=change_choices, inputs=[], outputs=[SoVITS_dropdown, GPT_dropdown] + ) gr.Markdown(html_center(i18n("*请上传并填写参考信息"), "h3")) with gr.Row(): - inp_ref = gr.Audio(label=i18n("请上传3~10秒内参考音频,超过会报错!"), type="filepath", scale=13) + inp_ref = gr.Audio( + label=i18n("请上传3~10秒内参考音频,超过会报错!"), + type="filepath", + scale=13, + ) with gr.Column(scale=13): ref_text_free = gr.Checkbox( label=i18n("开启无参考文本模式。不填参考文本亦相当于开启。") @@ -1120,10 +1211,18 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: html_left( i18n("使用无参考文本模式时建议使用微调的GPT") + "
" - + i18n("听不清参考音频说的啥(不晓得写啥)可以开。开启后无视填写的参考文本。") + + i18n( + "听不清参考音频说的啥(不晓得写啥)可以开。开启后无视填写的参考文本。" + ) ) ) - prompt_text = gr.Textbox(label=i18n("参考音频的文本"), value="", lines=5, max_lines=5, scale=1) + prompt_text = gr.Textbox( + label=i18n("参考音频的文本"), + value="", + lines=5, + max_lines=5, + scale=1, + ) with gr.Column(scale=14): prompt_language = gr.Dropdown( label=i18n("参考音频的语种"), @@ -1150,13 +1249,21 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: gr.Radio( label=i18n("采样步数,如果觉得电,提高试试,如果觉得慢,降低试试"), value=32 if model_version == "v3" else 8, - choices=[4, 8, 16, 32, 64, 128] if model_version == "v3" else [4, 8, 16, 32], + choices=( + [4, 8, 16, 32, 64, 128] + if model_version == "v3" + else [4, 8, 16, 32] + ), visible=True, ) if model_version in v3v4set else gr.Radio( label=i18n("采样步数,如果觉得电,提高试试,如果觉得慢,降低试试"), - choices=[4, 8, 16, 32, 64, 128] if model_version == "v3" else [4, 8, 16, 32], + choices=( + [4, 8, 16, 32, 64, 128] + if model_version == "v3" + else [4, 8, 16, 32] + ), visible=False, value=32 if model_version == "v3" else 8, ) @@ -1171,7 +1278,9 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: gr.Markdown(html_center(i18n("*请填写需要合成的目标文本和语种模式"), "h3")) with gr.Row(): with gr.Column(scale=13): - text = gr.Textbox(label=i18n("需要合成的文本"), value="", lines=26, max_lines=26) + text = gr.Textbox( + label=i18n("需要合成的文本"), value="", lines=26, max_lines=26 + ) with gr.Column(scale=7): text_language = gr.Dropdown( label=i18n("需要合成的语种") + i18n(".限制范围越小判别效果越好。"), @@ -1203,7 +1312,13 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: ) with gr.Row(): speed = gr.Slider( - minimum=0.6, maximum=1.65, step=0.05, label=i18n("语速"), value=1, interactive=True, scale=1 + minimum=0.6, + maximum=1.65, + step=0.05, + label=i18n("语速"), + value=1, + interactive=True, + scale=1, ) pause_second_slider = gr.Slider( minimum=0.1, @@ -1214,22 +1329,46 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: interactive=True, scale=1, ) - gr.Markdown(html_center(i18n("GPT采样参数(无参考文本时不要太低。不懂就用默认):"))) + gr.Markdown( + html_center( + i18n("GPT采样参数(无参考文本时不要太低。不懂就用默认):") + ) + ) top_k = gr.Slider( - minimum=1, maximum=100, step=1, label=i18n("top_k"), value=15, interactive=True, scale=1 + minimum=1, + maximum=100, + step=1, + label=i18n("top_k"), + value=15, + interactive=True, + scale=1, ) top_p = gr.Slider( - minimum=0, maximum=1, step=0.05, label=i18n("top_p"), value=1, interactive=True, scale=1 + minimum=0, + maximum=1, + step=0.05, + label=i18n("top_p"), + value=1, + interactive=True, + scale=1, ) temperature = gr.Slider( - minimum=0, maximum=1, step=0.05, label=i18n("temperature"), value=1, interactive=True, scale=1 + minimum=0, + maximum=1, + step=0.05, + label=i18n("temperature"), + value=1, + interactive=True, + scale=1, ) # with gr.Column(): # gr.Markdown(value=i18n("手工调整音素。当音素框不为空时使用手工音素输入推理,无视目标文本框。")) # phoneme=gr.Textbox(label=i18n("音素框"), value="") # get_phoneme_button = gr.Button(i18n("目标文本转音素"), variant="primary") with gr.Row(): - inference_button = gr.Button(value=i18n("合成语音"), variant="primary", size="lg", scale=25) + inference_button = gr.Button( + value=i18n("合成语音"), variant="primary", size="lg", scale=25 + ) output = gr.Audio(label=i18n("输出的语音"), scale=14) inference_button.click( diff --git a/GPT_SoVITS/inference_webui_fast.py b/GPT_SoVITS/inference_webui_fast.py index 0b9525e8..6bc4be81 100644 --- a/GPT_SoVITS/inference_webui_fast.py +++ b/GPT_SoVITS/inference_webui_fast.py @@ -147,7 +147,11 @@ def inference( "text": text, "text_lang": dict_language[text_lang], "ref_audio_path": ref_audio_path, - "aux_ref_audio_paths": [item.name for item in aux_ref_audio_paths] if aux_ref_audio_paths is not None else [], + "aux_ref_audio_paths": ( + [item.name for item in aux_ref_audio_paths] + if aux_ref_audio_paths is not None + else [] + ), "prompt_text": prompt_text if not ref_text_free else "", "prompt_lang": dict_language[prompt_lang], "top_k": top_k, @@ -182,7 +186,10 @@ def custom_sort_key(s): def change_choices(): SoVITS_names, GPT_names = get_weights_names(GPT_weight_root, SoVITS_weight_root) - return {"choices": sorted(SoVITS_names, key=custom_sort_key), "__type__": "update"}, { + return { + "choices": sorted(SoVITS_names, key=custom_sort_key), + "__type__": "update", + }, { "choices": sorted(GPT_names, key=custom_sort_key), "__type__": "update", } @@ -223,15 +230,25 @@ else: with open("./weight.json", "r", encoding="utf-8") as file: weight_data = file.read() weight_data = json.loads(weight_data) - gpt_path = os.environ.get("gpt_path", weight_data.get("GPT", {}).get(version, pretrained_gpt_name)) - sovits_path = os.environ.get("sovits_path", weight_data.get("SoVITS", {}).get(version, pretrained_sovits_name)) + gpt_path = os.environ.get( + "gpt_path", weight_data.get("GPT", {}).get(version, pretrained_gpt_name) + ) + sovits_path = os.environ.get( + "sovits_path", + weight_data.get("SoVITS", {}).get(version, pretrained_sovits_name), + ) if isinstance(gpt_path, list): gpt_path = gpt_path[0] if isinstance(sovits_path, list): sovits_path = sovits_path[0] -SoVITS_weight_root = ["SoVITS_weights", "SoVITS_weights_v2", "SoVITS_weights_v3", "SoVITS_weights_v4"] +SoVITS_weight_root = [ + "SoVITS_weights", + "SoVITS_weights_v2", + "SoVITS_weights_v3", + "SoVITS_weights_v4", +] GPT_weight_root = ["GPT_weights", "GPT_weights_v2", "GPT_weights_v3", "GPT_weights_v4"] for path in SoVITS_weight_root + GPT_weight_root: os.makedirs(path, exist_ok=True) @@ -266,7 +283,12 @@ def change_sovits_weights(sovits_path, prompt_language=None, text_language=None) is_exist = is_exist_s2gv3 if model_version == "v3" else is_exist_s2gv4 path_sovits = path_sovits_v3 if model_version == "v3" else path_sovits_v4 if if_lora_v3 == True and is_exist == False: - info = path_sovits + i18n("SoVITS %s 底模缺失,无法加载相应 LoRA 权重" % model_version) + info = ( + path_sovits + + f"SoVITS {model_version}" + + " : " + + i18n("底模缺失,无法加载相应 LoRA 权重") + ) gr.Warning(info) raise FileExistsError(info) dict_language = dict_language_v1 if version == "v1" else dict_language_v2 @@ -280,7 +302,10 @@ def change_sovits_weights(sovits_path, prompt_language=None, text_language=None) prompt_text_update = {"__type__": "update", "value": ""} prompt_language_update = {"__type__": "update", "value": i18n("中文")} if text_language in list(dict_language.keys()): - text_update, text_language_update = {"__type__": "update"}, {"__type__": "update", "value": text_language} + text_update, text_language_update = {"__type__": "update"}, { + "__type__": "update", + "value": text_language, + } else: text_update = {"__type__": "update", "value": ""} text_language_update = {"__type__": "update", "value": i18n("中文")} @@ -299,8 +324,15 @@ def change_sovits_weights(sovits_path, prompt_language=None, text_language=None) text_language_update, {"__type__": "update", "interactive": visible_sample_steps, "value": 32}, {"__type__": "update", "visible": visible_inp_refs}, - {"__type__": "update", "interactive": True if model_version not in v3v4set else False}, - {"__type__": "update", "value": i18n("模型加载中,请等待"), "interactive": False}, + { + "__type__": "update", + "interactive": True if model_version not in v3v4set else False, + }, + { + "__type__": "update", + "value": i18n("模型加载中,请等待"), + "interactive": False, + }, ) tts_pipeline.init_vits_weights(sovits_path) @@ -313,7 +345,10 @@ def change_sovits_weights(sovits_path, prompt_language=None, text_language=None) text_language_update, {"__type__": "update", "interactive": visible_sample_steps, "value": 32}, {"__type__": "update", "visible": visible_inp_refs}, - {"__type__": "update", "interactive": True if model_version not in v3v4set else False}, + { + "__type__": "update", + "interactive": True if model_version not in v3v4set else False, + }, {"__type__": "update", "value": i18n("合成语音"), "interactive": True}, ) with open("./weight.json") as f: @@ -326,9 +361,13 @@ def change_sovits_weights(sovits_path, prompt_language=None, text_language=None) with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: gr.Markdown( - value=i18n("本软件以MIT协议开源, 作者不对软件具备任何控制力, 使用软件者、传播软件导出的声音者自负全责.") + value=i18n( + "本软件以MIT协议开源, 作者不对软件具备任何控制力, 使用软件者、传播软件导出的声音者自负全责." + ) + "
" - + i18n("如不认可该条款, 则不能使用或引用软件包内任何代码和文件. 详见根目录LICENSE.") + + i18n( + "如不认可该条款, 则不能使用或引用软件包内任何代码和文件. 详见根目录LICENSE." + ) ) with gr.Column(): @@ -348,13 +387,18 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: interactive=True, ) refresh_button = gr.Button(i18n("刷新模型路径"), variant="primary") - refresh_button.click(fn=change_choices, inputs=[], outputs=[SoVITS_dropdown, GPT_dropdown]) + refresh_button.click( + fn=change_choices, inputs=[], outputs=[SoVITS_dropdown, GPT_dropdown] + ) with gr.Row(): with gr.Column(): gr.Markdown(value=i18n("*请上传并填写参考信息")) with gr.Row(): - inp_ref = gr.Audio(label=i18n("主参考音频(请上传3~10秒内参考音频,超过会报错!)"), type="filepath") + inp_ref = gr.Audio( + label=i18n("主参考音频(请上传3~10秒内参考音频,超过会报错!)"), + type="filepath", + ) inp_refs = gr.File( label=i18n("辅参考音频(可选多个,或不选)"), file_count="multiple", @@ -363,7 +407,9 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: prompt_text = gr.Textbox(label=i18n("主参考音频的文本"), value="", lines=2) with gr.Row(): prompt_language = gr.Dropdown( - label=i18n("主参考音频的语种"), choices=list(dict_language.keys()), value=i18n("中文") + label=i18n("主参考音频的语种"), + choices=list(dict_language.keys()), + value=i18n("中文"), ) with gr.Column(): ref_text_free = gr.Checkbox( @@ -375,14 +421,20 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: gr.Markdown( i18n("使用无参考文本模式时建议使用微调的GPT") + "
" - + i18n("听不清参考音频说的啥(不晓得写啥)可以开。开启后无视填写的参考文本。") + + i18n( + "听不清参考音频说的啥(不晓得写啥)可以开。开启后无视填写的参考文本。" + ) ) with gr.Column(): gr.Markdown(value=i18n("*请填写需要合成的目标文本和语种模式")) - text = gr.Textbox(label=i18n("需要合成的文本"), value="", lines=20, max_lines=20) + text = gr.Textbox( + label=i18n("需要合成的文本"), value="", lines=20, max_lines=20 + ) text_language = gr.Dropdown( - label=i18n("需要合成的文本的语种"), choices=list(dict_language.keys()), value=i18n("中文") + label=i18n("需要合成的文本的语种"), + choices=list(dict_language.keys()), + value=i18n("中文"), ) with gr.Group(): @@ -391,27 +443,69 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: with gr.Column(): with gr.Row(): batch_size = gr.Slider( - minimum=1, maximum=200, step=1, label=i18n("batch_size"), value=20, interactive=True + minimum=1, + maximum=200, + step=1, + label=i18n("batch_size"), + value=20, + interactive=True, ) sample_steps = gr.Radio( - label=i18n("采样步数(仅对V3/4生效)"), value=32, choices=[4, 8, 16, 32, 64, 128], visible=True + label=i18n("采样步数(仅对V3/4生效)"), + value=32, + choices=[4, 8, 16, 32, 64, 128], + visible=True, ) with gr.Row(): fragment_interval = gr.Slider( - minimum=0.01, maximum=1, step=0.01, label=i18n("分段间隔(秒)"), value=0.3, interactive=True + minimum=0.01, + maximum=1, + step=0.01, + label=i18n("分段间隔(秒)"), + value=0.3, + interactive=True, ) speed_factor = gr.Slider( - minimum=0.6, maximum=1.65, step=0.05, label="语速", value=1.0, interactive=True + minimum=0.6, + maximum=1.65, + step=0.05, + label="语速", + value=1.0, + interactive=True, ) with gr.Row(): - top_k = gr.Slider(minimum=1, maximum=100, step=1, label=i18n("top_k"), value=5, interactive=True) - top_p = gr.Slider(minimum=0, maximum=1, step=0.05, label=i18n("top_p"), value=1, interactive=True) + top_k = gr.Slider( + minimum=1, + maximum=100, + step=1, + label=i18n("top_k"), + value=5, + interactive=True, + ) + top_p = gr.Slider( + minimum=0, + maximum=1, + step=0.05, + label=i18n("top_p"), + value=1, + interactive=True, + ) with gr.Row(): temperature = gr.Slider( - minimum=0, maximum=1, step=0.05, label=i18n("temperature"), value=1, interactive=True + minimum=0, + maximum=1, + step=0.05, + label=i18n("temperature"), + value=1, + interactive=True, ) repetition_penalty = gr.Slider( - minimum=0, maximum=2, step=0.05, label=i18n("重复惩罚"), value=1.35, interactive=True + minimum=0, + maximum=2, + step=0.05, + label=i18n("重复惩罚"), + value=1.35, + interactive=True, ) with gr.Column(): @@ -431,11 +525,19 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: scale=1, ) super_sampling = gr.Checkbox( - label=i18n("音频超采样(仅对V3生效))"), value=False, interactive=True, show_label=True + label=i18n("音频超采样(仅对V3生效))"), + value=False, + interactive=True, + show_label=True, ) with gr.Row(): - parallel_infer = gr.Checkbox(label=i18n("并行推理"), value=True, interactive=True, show_label=True) + parallel_infer = gr.Checkbox( + label=i18n("并行推理"), + value=True, + interactive=True, + show_label=True, + ) split_bucket = gr.Checkbox( label=i18n("数据分桶(并行推理时会降低一点计算量)"), value=True, @@ -445,7 +547,12 @@ with gr.Blocks(title="GPT-SoVITS WebUI", analytics_enabled=False) as app: with gr.Row(): seed = gr.Number(label=i18n("随机种子"), value=-1) - keep_random = gr.Checkbox(label=i18n("保持随机"), value=True, interactive=True, show_label=True) + keep_random = gr.Checkbox( + label=i18n("保持随机"), + value=True, + interactive=True, + show_label=True, + ) output = gr.Audio(label=i18n("输出的语音")) with gr.Row():