Compare commits

...

7 Commits

Author SHA1 Message Date
RVC-Boss
dbf7702b54
Update README.md 2025-06-05 11:59:58 +08:00
RVC-Boss
fa9457c875
Update Changelog_CN.md 2025-06-05 11:52:00 +08:00
Jialiang Zhu
035dcbad03
Fix AttributeError when prompt_cache['refer_spec'][0] is a tuple (#2428)
Co-authored-by: tzrain <tz_rain@foxmail.com>
2025-06-05 10:55:21 +08:00
RVC-Boss
a080e19f91
去除不需要的告警AttributeError: module 'onnxruntime' has no attribute 'preload_dlls'
去除不需要的告警AttributeError: module 'onnxruntime' has no attribute 'preload_dlls'
2025-06-05 10:48:50 +08:00
RVC-Boss
69e671f793
fix sv_path
fix sv_path
2025-06-05 10:48:11 +08:00
RVC-Boss
3fcffb2e95
fix v3v4 resample function
fix v3v4 resample function
2025-06-05 10:47:32 +08:00
XXXXRT666
05d44215f1
Make Pre-Commit-Hook Exit 0 While Using Ruff Check (#2427)
Modified gradio Layout
Refactor WebUI half-precision and GPU detection logic
2025-06-05 10:46:05 +08:00
8 changed files with 645 additions and 550 deletions

View File

@ -8,7 +8,7 @@ repos:
# Run the linter.
- id: ruff
types_or: [ python, pyi ]
args: [ --fix ]
args: [ --fix , "--exit-zero" ]
# Run the formatter.
- id: ruff-format
types_or: [ python, pyi ]

View File

@ -1407,7 +1407,10 @@ class TTS:
):
prompt_semantic_tokens = self.prompt_cache["prompt_semantic"].unsqueeze(0).unsqueeze(0).to(self.configs.device)
prompt_phones = torch.LongTensor(self.prompt_cache["phones"]).unsqueeze(0).to(self.configs.device)
refer_audio_spec = self.prompt_cache["refer_spec"][0].to(dtype=self.precision, device=self.configs.device)
raw_entry = self.prompt_cache["refer_spec"][0]
if isinstance(raw_entry, tuple):
raw_entry = raw_entry[0]
refer_audio_spec = raw_entry.to(dtype=self.precision,device=self.configs.device)
fea_ref, ge = self.vits_model.decode_encp(prompt_semantic_tokens, prompt_phones, refer_audio_spec)
ref_audio: torch.Tensor = self.prompt_cache["raw_audio"]
@ -1474,7 +1477,10 @@ class TTS:
) -> List[torch.Tensor]:
prompt_semantic_tokens = self.prompt_cache["prompt_semantic"].unsqueeze(0).unsqueeze(0).to(self.configs.device)
prompt_phones = torch.LongTensor(self.prompt_cache["phones"]).unsqueeze(0).to(self.configs.device)
refer_audio_spec = self.prompt_cache["refer_spec"][0].to(dtype=self.precision, device=self.configs.device)
raw_entry = self.prompt_cache["refer_spec"][0]
if isinstance(raw_entry, tuple):
raw_entry = raw_entry[0]
refer_audio_spec = raw_entry.to(dtype=self.precision,device=self.configs.device)
fea_ref, ge = self.vits_model.decode_encp(prompt_semantic_tokens, prompt_phones, refer_audio_spec)
ref_audio: torch.Tensor = self.prompt_cache["raw_audio"]

View File

@ -202,16 +202,6 @@ if is_half == True:
else:
ssl_model = ssl_model.to(device)
resample_transform_dict = {}
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)
return resample_transform_dict[key](audio_tensor)
###todo:put them to process_ckpt and modify my_save func (save sovits weights), gpt save weights use my_save in process_ckpt
# symbol_version-model_version-if_lora_v3
@ -899,7 +889,7 @@ def get_tts_wav(
ref_audio = ref_audio.mean(0).unsqueeze(0)
tgt_sr = 24000 if model_version == "v3" else 32000
if sr != tgt_sr:
ref_audio = resample(ref_audio, sr, tgt_sr)
ref_audio = resample(ref_audio, sr, tgt_sr,device)
# print("ref_audio",ref_audio.abs().mean())
mel2 = mel_fn(ref_audio) if model_version == "v3" else mel_fn_v4(ref_audio)
mel2 = norm_spec(mel2)

View File

@ -23,8 +23,8 @@ from .utils import load_config
onnxruntime.set_default_logger_severity(3)
try:
onnxruntime.preload_dlls()
except:
traceback.print_exc()
except:pass
#traceback.print_exc()
warnings.filterwarnings("ignore")
model_version = "1.1"

View File

@ -328,6 +328,23 @@ Use v4 from v1/v2/v3 environment:
3. Download v4 pretrained models (gsv-v4-pretrained/s2v4.ckpt, and gsv-v4-pretrained/vocoder.pth) from [huggingface](https://huggingface.co/lj1995/GPT-SoVITS/tree/main) and put them into `GPT_SoVITS/pretrained_models`.
## V2Pro Release Notes
New Features:
1. Slightly higher VRAM usage than v2, surpassing v4's performance, with v2's hardware cost and speed.
[more details](https://github.com/RVC-Boss/GPT-SoVITS/wiki/GPT%E2%80%90SoVITS%E2%80%90features-(%E5%90%84%E7%89%88%E6%9C%AC%E7%89%B9%E6%80%A7))
2.v1/v2 and the v2Pro series share the same characteristics, while v3/v4 have similar features. For training sets with average audio quality, v1/v2/v2Pro can deliver decent results, but v3/v4 cannot. Additionally, the synthesized tone and timebre of v3/v4 lean more toward the reference audio rather than the overall training set.
Use v2Pro from v1/v2/v3/v4 environment:
1. `pip install -r requirements.txt` to update some packages
2. Clone the latest codes from github.
3. Download v2Pro pretrained models (v2Pro/s2Dv2Pro.pth, v2Pro/s2Gv2Pro.pth, v2Pro/s2Dv2ProPlus.pth, v2Pro/s2Gv2ProPlus.pth, and sv/pretrained_eres2netv2w24s4ep4.ckpt) from [huggingface](https://huggingface.co/lj1995/GPT-SoVITS/tree/main) and put them into `GPT_SoVITS/pretrained_models`.
## Todo List
- [x] **High Priority:**

177
config.py
View File

@ -1,30 +1,32 @@
import sys
import os
import re
import sys
import torch,re
import torch
from tools.i18n.i18n import I18nAuto
from tools.i18n.i18n import I18nAuto, scan_language_list
i18n = I18nAuto(language=os.environ.get("language", "Auto"))
pretrained_sovits_name = {
"v1":"GPT_SoVITS/pretrained_models/s2G488k.pth",
"v2":"GPT_SoVITS/pretrained_models/gsv-v2final-pretrained/s2G2333k.pth",
"v3":"GPT_SoVITS/pretrained_models/s2Gv3.pth",###v3v4还要检查vocoder算了。。。
"v4":"GPT_SoVITS/pretrained_models/gsv-v4-pretrained/s2Gv4.pth",
"v2Pro":"GPT_SoVITS/pretrained_models/v2Pro/s2Gv2Pro.pth",
"v2ProPlus":"GPT_SoVITS/pretrained_models/v2Pro/s2Gv2ProPlus.pth",
"v1": "GPT_SoVITS/pretrained_models/s2G488k.pth",
"v2": "GPT_SoVITS/pretrained_models/gsv-v2final-pretrained/s2G2333k.pth",
"v3": "GPT_SoVITS/pretrained_models/s2Gv3.pth", ###v3v4还要检查vocoder算了。。。
"v4": "GPT_SoVITS/pretrained_models/gsv-v4-pretrained/s2Gv4.pth",
"v2Pro": "GPT_SoVITS/pretrained_models/v2Pro/s2Gv2Pro.pth",
"v2ProPlus": "GPT_SoVITS/pretrained_models/v2Pro/s2Gv2ProPlus.pth",
}
pretrained_gpt_name = {
"v1":"GPT_SoVITS/pretrained_models/s1bert25hz-2kh-longer-epoch=68e-step=50232.ckpt",
"v2":"GPT_SoVITS/pretrained_models/gsv-v2final-pretrained/s1bert25hz-5kh-longer-epoch=12-step=369668.ckpt",
"v3":"GPT_SoVITS/pretrained_models/s1v3.ckpt",
"v4":"GPT_SoVITS/pretrained_models/s1v3.ckpt",
"v2Pro":"GPT_SoVITS/pretrained_models/s1v3.ckpt",
"v2ProPlus":"GPT_SoVITS/pretrained_models/s1v3.ckpt",
"v1": "GPT_SoVITS/pretrained_models/s1bert25hz-2kh-longer-epoch=68e-step=50232.ckpt",
"v2": "GPT_SoVITS/pretrained_models/gsv-v2final-pretrained/s1bert25hz-5kh-longer-epoch=12-step=369668.ckpt",
"v3": "GPT_SoVITS/pretrained_models/s1v3.ckpt",
"v4": "GPT_SoVITS/pretrained_models/s1v3.ckpt",
"v2Pro": "GPT_SoVITS/pretrained_models/s1v3.ckpt",
"v2ProPlus": "GPT_SoVITS/pretrained_models/s1v3.ckpt",
}
name2sovits_path={
name2sovits_path = {
# i18n("不训练直接推v1底模"): "GPT_SoVITS/pretrained_models/s2G488k.pth",
i18n("不训练直接推v2底模"): "GPT_SoVITS/pretrained_models/gsv-v2final-pretrained/s2G2333k.pth",
# i18n("不训练直接推v3底模"): "GPT_SoVITS/pretrained_models/s2Gv3.pth",
@ -32,29 +34,47 @@ name2sovits_path={
i18n("不训练直接推v2Pro底模"): "GPT_SoVITS/pretrained_models/v2Pro/s2Gv2Pro.pth",
i18n("不训练直接推v2ProPlus底模"): "GPT_SoVITS/pretrained_models/v2Pro/s2Gv2ProPlus.pth",
}
name2gpt_path={
name2gpt_path = {
# i18n("不训练直接推v1底模"):"GPT_SoVITS/pretrained_models/s1bert25hz-2kh-longer-epoch=68e-step=50232.ckpt",
i18n("不训练直接推v2底模"):"GPT_SoVITS/pretrained_models/gsv-v2final-pretrained/s1bert25hz-5kh-longer-epoch=12-step=369668.ckpt",
i18n("不训练直接推v3底模"):"GPT_SoVITS/pretrained_models/s1v3.ckpt",
i18n(
"不训练直接推v2底模"
): "GPT_SoVITS/pretrained_models/gsv-v2final-pretrained/s1bert25hz-5kh-longer-epoch=12-step=369668.ckpt",
i18n("不训练直接推v3底模"): "GPT_SoVITS/pretrained_models/s1v3.ckpt",
}
SoVITS_weight_root = ["SoVITS_weights", "SoVITS_weights_v2", "SoVITS_weights_v3", "SoVITS_weights_v4", "SoVITS_weights_v2Pro", "SoVITS_weights_v2ProPlus"]
GPT_weight_root = ["GPT_weights", "GPT_weights_v2", "GPT_weights_v3", "GPT_weights_v4", "GPT_weights_v2Pro", "GPT_weights_v2ProPlus"]
SoVITS_weight_version2root={
"v1":"SoVITS_weights",
"v2":"SoVITS_weights_v2",
"v3":"SoVITS_weights_v3",
"v4":"SoVITS_weights_v4",
"v2Pro":"SoVITS_weights_v2Pro",
"v2ProPlus":"SoVITS_weights_v2ProPlus",
SoVITS_weight_root = [
"SoVITS_weights",
"SoVITS_weights_v2",
"SoVITS_weights_v3",
"SoVITS_weights_v4",
"SoVITS_weights_v2Pro",
"SoVITS_weights_v2ProPlus",
]
GPT_weight_root = [
"GPT_weights",
"GPT_weights_v2",
"GPT_weights_v3",
"GPT_weights_v4",
"GPT_weights_v2Pro",
"GPT_weights_v2ProPlus",
]
SoVITS_weight_version2root = {
"v1": "SoVITS_weights",
"v2": "SoVITS_weights_v2",
"v3": "SoVITS_weights_v3",
"v4": "SoVITS_weights_v4",
"v2Pro": "SoVITS_weights_v2Pro",
"v2ProPlus": "SoVITS_weights_v2ProPlus",
}
GPT_weight_version2root={
"v1":"GPT_weights",
"v2":"GPT_weights_v2",
"v3":"GPT_weights_v3",
"v4":"GPT_weights_v4",
"v2Pro":"GPT_weights_v2Pro",
"v2ProPlus":"GPT_weights_v2ProPlus",
GPT_weight_version2root = {
"v1": "GPT_weights",
"v2": "GPT_weights_v2",
"v3": "GPT_weights_v3",
"v4": "GPT_weights_v4",
"v2Pro": "GPT_weights_v2Pro",
"v2ProPlus": "GPT_weights_v2ProPlus",
}
def custom_sort_key(s):
# 使用正则表达式提取字符串中的数字部分和非数字部分
parts = re.split("(\d+)", s)
@ -62,27 +82,37 @@ def custom_sort_key(s):
parts = [int(part) if part.isdigit() else part for part in parts]
return parts
def get_weights_names():
SoVITS_names = []
for key in name2sovits_path:
if os.path.exists(name2sovits_path[key]):SoVITS_names.append(key)
if os.path.exists(name2sovits_path[key]):
SoVITS_names.append(key)
for path in SoVITS_weight_root:
if not os.path.exists(path):continue
if not os.path.exists(path):
continue
for name in os.listdir(path):
if name.endswith(".pth"):
SoVITS_names.append("%s/%s" % (path, name))
if not SoVITS_names:
SoVITS_names = [""]
GPT_names = []
for key in name2gpt_path:
if os.path.exists(name2gpt_path[key]):GPT_names.append(key)
if os.path.exists(name2gpt_path[key]):
GPT_names.append(key)
for path in GPT_weight_root:
if not os.path.exists(path):continue
if not os.path.exists(path):
continue
for name in os.listdir(path):
if name.endswith(".ckpt"):
GPT_names.append("%s/%s" % (path, name))
SoVITS_names=sorted(SoVITS_names, key=custom_sort_key)
GPT_names=sorted(GPT_names, key=custom_sort_key)
SoVITS_names = sorted(SoVITS_names, key=custom_sort_key)
GPT_names = sorted(GPT_names, key=custom_sort_key)
if not GPT_names:
GPT_names = [""]
return SoVITS_names, GPT_names
def change_choices():
SoVITS_names, GPT_names = get_weights_names()
return {"choices": SoVITS_names, "__type__": "update"}, {
@ -106,10 +136,6 @@ pretrained_gpt_path = "GPT_SoVITS/pretrained_models/s1bert25hz-2kh-longer-epoch=
exp_root = "logs"
python_exec = sys.executable or "python"
if torch.cuda.is_available():
infer_device = "cuda"
else:
infer_device = "cpu"
webui_port_main = 9874
webui_port_uvr5 = 9873
@ -118,20 +144,55 @@ webui_port_subfix = 9871
api_port = 9880
if infer_device == "cuda":
gpu_name = torch.cuda.get_device_name(0)
if (
("16" in gpu_name and "V100" not in gpu_name.upper())
or "P40" in gpu_name.upper()
or "P10" in gpu_name.upper()
or "1060" in gpu_name
or "1070" in gpu_name
or "1080" in gpu_name
):
is_half = False
if infer_device == "cpu":
is_half = False
def get_device_dtype_sm(idx: int) -> tuple[torch.device, torch.dtype, float, float]:
cpu = torch.device("cpu")
cuda = torch.device(f"cuda:{idx}")
if not torch.cuda.is_available():
return cpu, torch.float32, 0.0, 0.0
device_idx = idx
capability = torch.cuda.get_device_capability(device_idx)
name = torch.cuda.get_device_name(device_idx)
mem_bytes = torch.cuda.get_device_properties(device_idx).total_memory
mem_gb = mem_bytes / (1024**3) + 0.4
major, minor = capability
sm_version = major + minor / 10.0
is_16_series = bool(re.search(r"16\d{2}", name))
if mem_gb < 4:
return cpu, torch.float32, 0.0, 0.0
if (sm_version >= 7.0 and sm_version != 7.5) or (5.3 <= sm_version <= 6.0):
if is_16_series and sm_version == 7.5:
return cuda, torch.float32, sm_version, mem_gb # 16系卡除外
else:
return cuda, torch.float16, sm_version, mem_gb
return cpu, torch.float32, 0.0, 0.0
IS_GPU = True
GPU_INFOS: list[str] = []
GPU_INDEX: set[int] = set()
GPU_COUNT = torch.cuda.device_count()
CPU_INFO: str = "0\tCPU " + i18n("CPU训练,较慢")
tmp: list[tuple[torch.device, torch.dtype, float, float]] = []
memset: set[float] = set()
for i in range(max(GPU_COUNT, 1)):
tmp.append(get_device_dtype_sm(i))
for j in tmp:
device = j[0]
memset.add(j[3])
if device.type != "cpu":
GPU_INFOS.append(f"{device.index}\t{torch.cuda.get_device_name(device.index)}")
GPU_INDEX.add(device.index)
if not GPU_INFOS:
IS_GPU = False
GPU_INFOS.append(CPU_INFO)
GPU_INDEX.add(0)
infer_device = max(tmp, key=lambda x: (x[2], x[3]))[0]
is_half = any(dtype == torch.float16 for _, dtype, _, _ in tmp)
class Config:

View File

@ -386,5 +386,11 @@
- 2025.06.04 [Commit#b7c0c5ca](https://github.com/RVC-Boss/GPT-SoVITS/commit/b7c0c5ca878bcdd419fd86bf80dba431a6653356)~[Commit#298ebb03](https://github.com/RVC-Boss/GPT-SoVITS/commit/298ebb03c5a719388527ae6a586c7ea960344e70): **新增 GPT-SoVITS V2Pro 系列模型**.
- 类型: 新功能
- 提交: RVC-Boss
- 2025.06.05 https://github.com/RVC-Boss/GPT-SoVITS/pull/2426: config/inference_webui初始化bug修复.
- 类型: 修复
- 提交: SapphireLab
- 2025.06.05 https://github.com/RVC-Boss/GPT-SoVITS/pull/2427: 优化精度自动检测逻辑;给webui前端界面模块增加可收缩式支持.
- 类型: 新功能
- 提交: XXXXRT666

967
webui.py

File diff suppressed because it is too large Load Diff