""" 按中英混合识别 按日英混合识别 多语种启动切分识别语种 全部按中文识别 全部按英文识别 全部按日文识别 """ import argparse import contextlib import gc import logging import os import re from functools import partial import gradio as gr import psutil import torch from config import change_choices, get_dtype, get_weights_names, pretrained_sovits_name from config import infer_device as default_device from GPT_SoVITS.Accelerate import MLX, PyTorch, backends from GPT_SoVITS.process_ckpt import inspect_version from GPT_SoVITS.TTS_infer_pack.TTS import NO_PROMPT_ERROR, TTS, TTS_Config from tools.assets import css, js, top_html from tools.i18n.i18n import I18nAuto, scan_language_list logging.getLogger("markdown_it").setLevel(logging.ERROR) logging.getLogger("urllib3").setLevel(logging.ERROR) logging.getLogger("httpcore").setLevel(logging.ERROR) logging.getLogger("httpx").setLevel(logging.ERROR) logging.getLogger("asyncio").setLevel(logging.ERROR) logging.getLogger("charset_normalizer").setLevel(logging.ERROR) logging.getLogger("torchaudio._extension").setLevel(logging.ERROR) os.environ["TOKENIZERS_PARALLELISM"] = "false" def set_high_priority(): if os.name != "nt": return p = psutil.Process(os.getpid()) with contextlib.suppress(psutil.AccessDenied): p.nice(psutil.HIGH_PRIORITY_CLASS) print("已将进程优先级设为 High") set_high_priority() _LANG_RE = re.compile(r"^[a-z]{2}[_-][A-Z]{2}$") def lang_type(text: str) -> str: if text == "Auto": return text if not _LANG_RE.match(text): raise argparse.ArgumentTypeError(f"Unspported Format: {text}, Expected ll_CC/ll-CC") ll, cc = re.split(r"[_-]", text) language = f"{ll}_{cc}" if language in scan_language_list(): return language else: return "Auto" def none_or_str(value: str): if value == "None": return None return value def build_parser() -> argparse.ArgumentParser: p = argparse.ArgumentParser( prog="inference_webui", description=f"python -s -m GPT_SoVITS.inference_webui zh_CN -b {backends[-1]}", ) p.add_argument( "language", nargs="?", default="Auto", type=lang_type, help="Language Code, Such as zh_CN, en-US", ) p.add_argument( "--backends", "-b", choices=backends, default=backends[-1], help="AR Inference Backend", required=False, ) p.add_argument( "--quantization", "-q", default="None", choices=MLX.quantization_methods_mlx + PyTorch.quantization_methods_torch, type=none_or_str, help="Quantization Method", required=False, ) p.add_argument( "--device", "-d", default=str(default_device), help="Inference Device", required=False, ) p.add_argument( "--port", "-p", default=9872, type=int, help="WebUI Binding Port", required=False, ) p.add_argument( "--share", "-s", default=False, action="store_true", help="Gradio Share Link", required=False, ) p.add_argument( "--cnhubert", default="GPT_SoVITS/pretrained_models/chinese-hubert-base", help="CNHuBERT Pretrain", required=False, ) p.add_argument( "--bert", default="GPT_SoVITS/pretrained_models/chinese-roberta-wwm-ext-large", help="BERT Pretrain", required=False, ) p.add_argument( "--gpt", default="", help="GPT Model", required=False, ) p.add_argument( "--sovits", default="", help="SoVITS Model", required=False, ) return p args = build_parser().parse_args() infer_ttswebui = int(args.port) is_share = args.share infer_device = torch.device(args.device) device = infer_device dtype = get_dtype(device.index) is_half = dtype == torch.float16 i18n = I18nAuto(language=args.language) change_choices_i18n = partial(change_choices, i18n=i18n) SoVITS_names, GPT_names = get_weights_names(i18n) gpt_path = str(args.gpt) or GPT_names[0][-1] sovits_path = str(args.sovits) or SoVITS_names[0][-1] cnhubert_base_path = str(args.cnhubert) bert_path = str(args.bert) version = model_version = "v2" is_lora = False cut_method = { i18n("不切"): "cut0", i18n("凑四句一切"): "cut1", i18n("凑50字一切"): "cut2", i18n("按中文句号。切"): "cut3", i18n("按英文句号.切"): "cut4", i18n("按标点符号切"): "cut5", } path_sovits_v3 = pretrained_sovits_name["v3"] path_sovits_v4 = pretrained_sovits_name["v4"] is_exist_s2gv3 = os.path.exists(path_sovits_v3) is_exist_s2gv4 = os.path.exists(path_sovits_v4) tts_config = TTS_Config("GPT_SoVITS/configs/tts_infer.yaml") tts_config.device = device tts_config.is_half = is_half # tts_config.version = version tts_config.update_version(version) if gpt_path is not None: tts_config.t2s_weights_path = gpt_path if sovits_path is not None: tts_config.vits_weights_path = sovits_path if cnhubert_base_path is not None: tts_config.cnhuhbert_base_path = cnhubert_base_path if bert_path is not None: tts_config.bert_base_path = bert_path tts_pipeline = TTS(tts_config, args.backends, args.quantization) gpt_path = tts_config.t2s_weights_path sovits_path = tts_config.vits_weights_path version = tts_config.version dict_language_v1 = { i18n("中文"): "all_zh", # 全部按中文识别 i18n("英文"): "en", # 全部按英文识别#######不变 i18n("日文"): "all_ja", # 全部按日文识别 i18n("中英混合"): "zh", # 按中英混合识别####不变 i18n("日英混合"): "ja", # 按日英混合识别####不变 i18n("多语种混合"): "auto", # 多语种启动切分识别语种 } dict_language_v2 = { i18n("中文"): "all_zh", # 全部按中文识别 i18n("英文"): "en", # 全部按英文识别#######不变 i18n("日文"): "all_ja", # 全部按日文识别 i18n("粤语"): "all_yue", # 全部按中文识别 i18n("韩文"): "all_ko", # 全部按韩文识别 i18n("中英混合"): "zh", # 按中英混合识别####不变 i18n("日英混合"): "ja", # 按日英混合识别####不变 i18n("粤英混合"): "yue", # 按粤英混合识别####不变 i18n("韩英混合"): "ko", # 按韩英混合识别####不变 i18n("多语种混合"): "auto", # 多语种启动切分识别语种 i18n("多语种混合(粤语)"): "auto_yue", # 多语种启动切分识别语种 } dict_language = dict_language_v1 if version == "v1" else dict_language_v2 print(tts_config) async def inference( text, text_lang, ref_audio_path, aux_ref_audio_paths, prompt_text, prompt_lang, top_k, top_p, temperature, text_split_method, batch_size, speed_factor, ref_text_free, fragment_interval, parallel_infer, repetition_penalty, sample_steps, super_sampling, ): inputs = { "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 [], "prompt_text": prompt_text if not ref_text_free else "", "prompt_lang": dict_language[prompt_lang], "top_k": top_k, "top_p": top_p, "temperature": temperature, "text_split_method": cut_method[text_split_method], "batch_size": int(batch_size), "speed_factor": float(speed_factor), "split_bucket": False, "return_fragment": False, "fragment_interval": fragment_interval, "seed": -1, "parallel_infer": parallel_infer, "repetition_penalty": repetition_penalty, "sample_steps": int(sample_steps), "super_sampling": super_sampling, } try: async for chunk in tts_pipeline.run(inputs): yield chunk gc.collect() if "cuda" in str(tts_config.device): torch.cuda.empty_cache() elif str(tts_config.device) == "mps": torch.mps.empty_cache() except NO_PROMPT_ERROR: gr.Warning(i18n("V3/V4不支持无参考文本模式, 请填写参考文本!")) except RuntimeError as e: gr.Warning(str(e)) v3v4set = {"v3", "v4"} async def change_sovits_weights(sovits_path, prompt_language=None, text_language=None): global version, model_version, dict_language, is_lora model_version, version, is_lora, _, __ = inspect_version(sovits_path) tts_config.update_version(model_version) 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 is_lora is True and is_exist is False: 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 if prompt_language is not None and text_language is not None: if prompt_language in list(dict_language.keys()): prompt_text_update, prompt_language_update = gr.skip(), gr.update(choices=list(dict_language.keys())) else: prompt_text_update = gr.update(value="") prompt_language_update = gr.update(value=i18n("中文"), choices=list(dict_language.keys())) if text_language in list(dict_language.keys()): text_update, text_language_update = gr.skip(), gr.skip() else: text_update = gr.update(value="") text_language_update = gr.update(value=i18n("中文"), choices=list(dict_language.keys())) if model_version in v3v4set: visible_sample_steps = True visible_inp_refs = False else: visible_sample_steps = False visible_inp_refs = True yield ( prompt_text_update, prompt_language_update, text_update, text_language_update, gr.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], ), gr.update(visible=visible_inp_refs), gr.update(value=False, interactive=True if model_version not in v3v4set else False), gr.update(visible=True if model_version == "v3" else False), gr.update(value=i18n("模型加载中, 请等待"), interactive=False), ) tts_pipeline.init_vits_weights(sovits_path) yield ( gr.skip(), gr.skip(), gr.skip(), gr.skip(), gr.skip(), gr.skip(), gr.skip(), gr.skip(), gr.update(value=i18n("合成语音"), interactive=True), ) async def change_gpt_weights(gpt_path): tts_pipeline.init_t2s_weights(gpt_path) def html_center(text, label="p"): return f"""