Merge branch 'RVC-Boss:main' into feat/frontend-usability-enhancements

This commit is contained in:
Karasukaigan 2025-07-02 15:35:45 +08:00 committed by GitHub
commit 539ad38d31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 624 additions and 307 deletions

View File

@ -121,71 +121,67 @@ class TextPreprocessor:
def get_phones_and_bert(self, text: str, language: str, version: str, final: bool = False): def get_phones_and_bert(self, text: str, language: str, version: str, final: bool = False):
with self.bert_lock: with self.bert_lock:
if language in {"en", "all_zh", "all_ja", "all_ko", "all_yue"}: text = re.sub(r' {2,}', ' ', text)
# language = language.replace("all_","") textlist = []
formattext = text langlist = []
while " " in formattext: if language == "all_zh":
formattext = formattext.replace(" ", " ") for tmp in LangSegmenter.getTexts(text,"zh"):
if language == "all_zh": langlist.append(tmp["lang"])
if re.search(r"[A-Za-z]", formattext): textlist.append(tmp["text"])
formattext = re.sub(r"[a-z]", lambda x: x.group(0).upper(), formattext) elif language == "all_yue":
formattext = chinese.mix_text_normalize(formattext) for tmp in LangSegmenter.getTexts(text,"zh"):
return self.get_phones_and_bert(formattext, "zh", version) if tmp["lang"] == "zh":
tmp["lang"] = "yue"
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "all_ja":
for tmp in LangSegmenter.getTexts(text,"ja"):
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "all_ko":
for tmp in LangSegmenter.getTexts(text,"ko"):
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "en":
langlist.append("en")
textlist.append(text)
elif language == "auto":
for tmp in LangSegmenter.getTexts(text):
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "auto_yue":
for tmp in LangSegmenter.getTexts(text):
if tmp["lang"] == "zh":
tmp["lang"] = "yue"
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
else:
for tmp in LangSegmenter.getTexts(text):
if langlist:
if (tmp["lang"] == "en" and langlist[-1] == "en") or (tmp["lang"] != "en" and langlist[-1] != "en"):
textlist[-1] += tmp["text"]
continue
if tmp["lang"] == "en":
langlist.append(tmp["lang"])
else: else:
phones, word2ph, norm_text = self.clean_text_inf(formattext, language, version) # 因无法区别中日韩文汉字,以用户输入为准
bert = self.get_bert_feature(norm_text, word2ph).to(self.device) langlist.append(language)
elif language == "all_yue" and re.search(r"[A-Za-z]", formattext): textlist.append(tmp["text"])
formattext = re.sub(r"[a-z]", lambda x: x.group(0).upper(), formattext) # print(textlist)
formattext = chinese.mix_text_normalize(formattext) # print(langlist)
return self.get_phones_and_bert(formattext, "yue", version) phones_list = []
else: bert_list = []
phones, word2ph, norm_text = self.clean_text_inf(formattext, language, version) norm_text_list = []
bert = torch.zeros( for i in range(len(textlist)):
(1024, len(phones)), lang = langlist[i]
dtype=torch.float32, phones, word2ph, norm_text = self.clean_text_inf(textlist[i], lang, version)
).to(self.device) bert = self.get_bert_inf(phones, word2ph, norm_text, lang)
elif language in {"zh", "ja", "ko", "yue", "auto", "auto_yue"}: phones_list.append(phones)
textlist = [] norm_text_list.append(norm_text)
langlist = [] bert_list.append(bert)
if language == "auto": bert = torch.cat(bert_list, dim=1)
for tmp in LangSegmenter.getTexts(text): phones = sum(phones_list, [])
langlist.append(tmp["lang"]) norm_text = "".join(norm_text_list)
textlist.append(tmp["text"])
elif language == "auto_yue":
for tmp in LangSegmenter.getTexts(text):
if tmp["lang"] == "zh":
tmp["lang"] = "yue"
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
else:
for tmp in LangSegmenter.getTexts(text):
if langlist:
if (tmp["lang"] == "en" and langlist[-1] == "en") or (
tmp["lang"] != "en" and langlist[-1] != "en"
):
textlist[-1] += tmp["text"]
continue
if tmp["lang"] == "en":
langlist.append(tmp["lang"])
else:
# 因无法区别中日韩文汉字,以用户输入为准
langlist.append(language)
textlist.append(tmp["text"])
# print(textlist)
# print(langlist)
phones_list = []
bert_list = []
norm_text_list = []
for i in range(len(textlist)):
lang = langlist[i]
phones, word2ph, norm_text = self.clean_text_inf(textlist[i], lang, version)
bert = self.get_bert_inf(phones, word2ph, norm_text, lang)
phones_list.append(phones)
norm_text_list.append(norm_text)
bert_list.append(bert)
bert = torch.cat(bert_list, dim=1)
phones = sum(phones_list, [])
norm_text = "".join(norm_text_list)
if not final and len(phones) < 6: if not final and len(phones) < 6:
return self.get_phones_and_bert("." + text, language, version, final=True) return self.get_phones_and_bert("." + text, language, version, final=True)
@ -240,4 +236,4 @@ class TextPreprocessor:
punctuations = "".join(re.escape(p) for p in punctuation) punctuations = "".join(re.escape(p) for p in punctuation)
pattern = f"([{punctuations}])([{punctuations}])+" pattern = f"([{punctuations}])([{punctuations}])+"
result = re.sub(pattern, r"\1", text) result = re.sub(pattern, r"\1", text)
return result return result

View File

@ -586,68 +586,67 @@ from text import chinese
def get_phones_and_bert(text, language, version, final=False): def get_phones_and_bert(text, language, version, final=False):
if language in {"en", "all_zh", "all_ja", "all_ko", "all_yue"}: text = re.sub(r' {2,}', ' ', text)
formattext = text textlist = []
while " " in formattext: langlist = []
formattext = formattext.replace(" ", " ") if language == "all_zh":
if language == "all_zh": for tmp in LangSegmenter.getTexts(text,"zh"):
if re.search(r"[A-Za-z]", formattext): langlist.append(tmp["lang"])
formattext = re.sub(r"[a-z]", lambda x: x.group(0).upper(), formattext) textlist.append(tmp["text"])
formattext = chinese.mix_text_normalize(formattext) elif language == "all_yue":
return get_phones_and_bert(formattext, "zh", version) for tmp in LangSegmenter.getTexts(text,"zh"):
if tmp["lang"] == "zh":
tmp["lang"] = "yue"
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "all_ja":
for tmp in LangSegmenter.getTexts(text,"ja"):
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "all_ko":
for tmp in LangSegmenter.getTexts(text,"ko"):
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "en":
langlist.append("en")
textlist.append(text)
elif language == "auto":
for tmp in LangSegmenter.getTexts(text):
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "auto_yue":
for tmp in LangSegmenter.getTexts(text):
if tmp["lang"] == "zh":
tmp["lang"] = "yue"
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
else:
for tmp in LangSegmenter.getTexts(text):
if langlist:
if (tmp["lang"] == "en" and langlist[-1] == "en") or (tmp["lang"] != "en" and langlist[-1] != "en"):
textlist[-1] += tmp["text"]
continue
if tmp["lang"] == "en":
langlist.append(tmp["lang"])
else: else:
phones, word2ph, norm_text = clean_text_inf(formattext, language, version) # 因无法区别中日韩文汉字,以用户输入为准
bert = get_bert_feature(norm_text, word2ph).to(device) langlist.append(language)
elif language == "all_yue" and re.search(r"[A-Za-z]", formattext): textlist.append(tmp["text"])
formattext = re.sub(r"[a-z]", lambda x: x.group(0).upper(), formattext) print(textlist)
formattext = chinese.mix_text_normalize(formattext) print(langlist)
return get_phones_and_bert(formattext, "yue", version) phones_list = []
else: bert_list = []
phones, word2ph, norm_text = clean_text_inf(formattext, language, version) norm_text_list = []
bert = torch.zeros( for i in range(len(textlist)):
(1024, len(phones)), lang = langlist[i]
dtype=torch.float16 if is_half == True else torch.float32, phones, word2ph, norm_text = clean_text_inf(textlist[i], lang, version)
).to(device) bert = get_bert_inf(phones, word2ph, norm_text, lang)
elif language in {"zh", "ja", "ko", "yue", "auto", "auto_yue"}: phones_list.append(phones)
textlist = [] norm_text_list.append(norm_text)
langlist = [] bert_list.append(bert)
if language == "auto": bert = torch.cat(bert_list, dim=1)
for tmp in LangSegmenter.getTexts(text): phones = sum(phones_list, [])
langlist.append(tmp["lang"]) norm_text = "".join(norm_text_list)
textlist.append(tmp["text"])
elif language == "auto_yue":
for tmp in LangSegmenter.getTexts(text):
if tmp["lang"] == "zh":
tmp["lang"] = "yue"
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
else:
for tmp in LangSegmenter.getTexts(text):
if langlist:
if (tmp["lang"] == "en" and langlist[-1] == "en") or (tmp["lang"] != "en" and langlist[-1] != "en"):
textlist[-1] += tmp["text"]
continue
if tmp["lang"] == "en":
langlist.append(tmp["lang"])
else:
# 因无法区别中日韩文汉字,以用户输入为准
langlist.append(language)
textlist.append(tmp["text"])
print(textlist)
print(langlist)
phones_list = []
bert_list = []
norm_text_list = []
for i in range(len(textlist)):
lang = langlist[i]
phones, word2ph, norm_text = clean_text_inf(textlist[i], lang, version)
bert = get_bert_inf(phones, word2ph, norm_text, lang)
phones_list.append(phones)
norm_text_list.append(norm_text)
bert_list.append(bert)
bert = torch.cat(bert_list, dim=1)
phones = sum(phones_list, [])
norm_text = "".join(norm_text_list)
if not final and len(phones) < 6: if not final and len(phones) < 6:
return get_phones_and_bert("." + text, language, version, final=True) return get_phones_and_bert("." + text, language, version, final=True)

View File

@ -3,44 +3,38 @@ import re
# jieba静音 # jieba静音
import jieba import jieba
jieba.setLogLevel(logging.CRITICAL) jieba.setLogLevel(logging.CRITICAL)
# 更改fast_langdetect大模型位置 # 更改fast_langdetect大模型位置
from pathlib import Path from pathlib import Path
import fast_langdetect import fast_langdetect
fast_langdetect.infer._default_detector = fast_langdetect.infer.LangDetector(fast_langdetect.infer.LangDetectConfig(cache_dir=Path(__file__).parent.parent.parent / "pretrained_models" / "fast_langdetect"))
fast_langdetect.infer._default_detector = fast_langdetect.infer.LangDetector(
fast_langdetect.infer.LangDetectConfig(
cache_dir=Path(__file__).parent.parent.parent / "pretrained_models" / "fast_langdetect"
)
)
from split_lang import LangSplitter from split_lang import LangSplitter
def full_en(text): def full_en(text):
pattern = r"^(?=.*[A-Za-z])[A-Za-z0-9\s\u0020-\u007E\u2000-\u206F\u3000-\u303F\uFF00-\uFFEF]+$" pattern = r'^(?=.*[A-Za-z])[A-Za-z0-9\s\u0020-\u007E\u2000-\u206F\u3000-\u303F\uFF00-\uFFEF]+$'
return bool(re.match(pattern, text)) return bool(re.match(pattern, text))
def full_cjk(text): def full_cjk(text):
# 来自wiki # 来自wiki
cjk_ranges = [ cjk_ranges = [
(0x4E00, 0x9FFF), # CJK Unified Ideographs (0x4E00, 0x9FFF), # CJK Unified Ideographs
(0x3400, 0x4DB5), # CJK Extension A (0x3400, 0x4DB5), # CJK Extension A
(0x20000, 0x2A6DD), # CJK Extension B (0x20000, 0x2A6DD), # CJK Extension B
(0x2A700, 0x2B73F), # CJK Extension C (0x2A700, 0x2B73F), # CJK Extension C
(0x2B740, 0x2B81F), # CJK Extension D (0x2B740, 0x2B81F), # CJK Extension D
(0x2B820, 0x2CEAF), # CJK Extension E (0x2B820, 0x2CEAF), # CJK Extension E
(0x2CEB0, 0x2EBEF), # CJK Extension F (0x2CEB0, 0x2EBEF), # CJK Extension F
(0x30000, 0x3134A), # CJK Extension G (0x30000, 0x3134A), # CJK Extension G
(0x31350, 0x323AF), # CJK Extension H (0x31350, 0x323AF), # CJK Extension H
(0x2EBF0, 0x2EE5D), # CJK Extension H (0x2EBF0, 0x2EE5D), # CJK Extension H
] ]
pattern = r"[0-9、-〜。!?.!?… /]+$" pattern = r'[0-9、-〜。!?.!?… /]+$'
cjk_text = "" cjk_text = ""
for char in text: for char in text:
@ -51,7 +45,7 @@ def full_cjk(text):
return cjk_text return cjk_text
def split_jako(tag_lang, item): def split_jako(tag_lang,item):
if tag_lang == "ja": if tag_lang == "ja":
pattern = r"([\u3041-\u3096\u3099\u309A\u30A1-\u30FA\u30FC]+(?:[0-9、-〜。!?.!?… ]+[\u3041-\u3096\u3099\u309A\u30A1-\u30FA\u30FC]*)*)" pattern = r"([\u3041-\u3096\u3099\u309A\u30A1-\u30FA\u30FC]+(?:[0-9、-〜。!?.!?… ]+[\u3041-\u3096\u3099\u309A\u30A1-\u30FA\u30FC]*)*)"
else: else:
@ -59,118 +53,165 @@ def split_jako(tag_lang, item):
lang_list: list[dict] = [] lang_list: list[dict] = []
tag = 0 tag = 0
for match in re.finditer(pattern, item["text"]): for match in re.finditer(pattern, item['text']):
if match.start() > tag: if match.start() > tag:
lang_list.append({"lang": item["lang"], "text": item["text"][tag : match.start()]}) lang_list.append({'lang':item['lang'],'text':item['text'][tag:match.start()]})
tag = match.end() tag = match.end()
lang_list.append({"lang": tag_lang, "text": item["text"][match.start() : match.end()]}) lang_list.append({'lang':tag_lang,'text':item['text'][match.start():match.end()]})
if tag < len(item["text"]): if tag < len(item['text']):
lang_list.append({"lang": item["lang"], "text": item["text"][tag : len(item["text"])]}) lang_list.append({'lang':item['lang'],'text':item['text'][tag:len(item['text'])]})
return lang_list return lang_list
def merge_lang(lang_list, item): def merge_lang(lang_list, item):
if lang_list and item["lang"] == lang_list[-1]["lang"]: if lang_list and item['lang'] == lang_list[-1]['lang']:
lang_list[-1]["text"] += item["text"] lang_list[-1]['text'] += item['text']
else: else:
lang_list.append(item) lang_list.append(item)
return lang_list return lang_list
class LangSegmenter: class LangSegmenter():
# 默认过滤器, 基于gsv目前四种语言 # 默认过滤器, 基于gsv目前四种语言
DEFAULT_LANG_MAP = { DEFAULT_LANG_MAP = {
"zh": "zh", "zh": "zh",
"yue": "zh", # 粤语 "yue": "zh", # 粤语
"wuu": "zh", # 吴语 "wuu": "zh", # 吴语
"zh-cn": "zh", "zh-cn": "zh",
"zh-tw": "x", # 繁体设置为x "zh-tw": "x", # 繁体设置为x
"ko": "ko", "ko": "ko",
"ja": "ja", "ja": "ja",
"en": "en", "en": "en",
} }
def getTexts(text): def getTexts(text,default_lang = ""):
lang_splitter = LangSplitter(lang_map=LangSegmenter.DEFAULT_LANG_MAP) lang_splitter = LangSplitter(lang_map=LangSegmenter.DEFAULT_LANG_MAP)
lang_splitter.merge_across_digit = False
substr = lang_splitter.split_by_lang(text=text) substr = lang_splitter.split_by_lang(text=text)
lang_list: list[dict] = [] lang_list: list[dict] = []
for _, item in enumerate(substr): have_num = False
dict_item = {"lang": item.lang, "text": item.text}
# 处理短英文被识别为其他语言的问题 for _, item in enumerate(substr):
if full_en(dict_item["text"]): dict_item = {'lang':item.lang,'text':item.text}
dict_item["lang"] = "en"
lang_list = merge_lang(lang_list, dict_item) if dict_item['lang'] == 'digit':
if default_lang != "":
dict_item['lang'] = default_lang
else:
have_num = True
lang_list = merge_lang(lang_list,dict_item)
continue continue
# 处理非日语夹日文的问题(不包含CJK) # 处理短英文被识别为其他语言的问题
ja_list: list[dict] = [] if full_en(dict_item['text']):
if dict_item["lang"] != "ja": dict_item['lang'] = 'en'
ja_list = split_jako("ja", dict_item) lang_list = merge_lang(lang_list,dict_item)
continue
if not ja_list: if default_lang != "":
ja_list.append(dict_item) dict_item['lang'] = default_lang
lang_list = merge_lang(lang_list,dict_item)
continue
else:
# 处理非日语夹日文的问题(不包含CJK)
ja_list: list[dict] = []
if dict_item['lang'] != 'ja':
ja_list = split_jako('ja',dict_item)
# 处理非韩语夹韩语的问题(不包含CJK) if not ja_list:
ko_list: list[dict] = [] ja_list.append(dict_item)
temp_list: list[dict] = []
for _, ko_item in enumerate(ja_list):
if ko_item["lang"] != "ko":
ko_list = split_jako("ko", ko_item)
if ko_list: # 处理非韩语夹韩语的问题(不包含CJK)
temp_list.extend(ko_list) ko_list: list[dict] = []
else: temp_list: list[dict] = []
temp_list.append(ko_item) for _, ko_item in enumerate(ja_list):
if ko_item["lang"] != 'ko':
ko_list = split_jako('ko',ko_item)
# 未存在非日韩文夹日韩文 if ko_list:
if len(temp_list) == 1: temp_list.extend(ko_list)
# 未知语言检查是否为CJK
if dict_item["lang"] == "x":
cjk_text = full_cjk(dict_item["text"])
if cjk_text:
dict_item = {"lang": "zh", "text": cjk_text}
lang_list = merge_lang(lang_list, dict_item)
else: else:
lang_list = merge_lang(lang_list, dict_item) temp_list.append(ko_item)
continue
else:
lang_list = merge_lang(lang_list, dict_item)
continue
# 存在非日韩文夹日韩文 # 未存在非日韩文夹日韩文
for _, temp_item in enumerate(temp_list): if len(temp_list) == 1:
# 未知语言检查是否为CJK # 未知语言检查是否为CJK
if temp_item["lang"] == "x": if dict_item['lang'] == 'x':
cjk_text = full_cjk(dict_item["text"]) cjk_text = full_cjk(dict_item['text'])
if cjk_text: if cjk_text:
dict_item = {"lang": "zh", "text": cjk_text} dict_item = {'lang':'zh','text':cjk_text}
lang_list = merge_lang(lang_list, dict_item) lang_list = merge_lang(lang_list,dict_item)
else:
lang_list = merge_lang(lang_list,dict_item)
continue
else: else:
lang_list = merge_lang(lang_list, dict_item) lang_list = merge_lang(lang_list,dict_item)
else: continue
lang_list = merge_lang(lang_list, temp_item)
# 存在非日韩文夹日韩文
for _, temp_item in enumerate(temp_list):
# 未知语言检查是否为CJK
if temp_item['lang'] == 'x':
cjk_text = full_cjk(temp_item['text'])
if cjk_text:
lang_list = merge_lang(lang_list,{'lang':'zh','text':cjk_text})
else:
lang_list = merge_lang(lang_list,temp_item)
else:
lang_list = merge_lang(lang_list,temp_item)
# 有数字
if have_num:
temp_list = lang_list
lang_list = []
for i, temp_item in enumerate(temp_list):
if temp_item['lang'] == 'digit':
if default_lang:
temp_item['lang'] = default_lang
elif lang_list and i == len(temp_list) - 1:
temp_item['lang'] = lang_list[-1]['lang']
elif not lang_list and i < len(temp_list) - 1:
temp_item['lang'] = temp_list[1]['lang']
elif lang_list and i < len(temp_list) - 1:
if lang_list[-1]['lang'] == temp_list[i + 1]['lang']:
temp_item['lang'] = lang_list[-1]['lang']
elif lang_list[-1]['text'][-1] in [",",".","!","?","","","",""]:
temp_item['lang'] = temp_list[i + 1]['lang']
elif temp_list[i + 1]['text'][0] in [",",".","!","?","","","",""]:
temp_item['lang'] = lang_list[-1]['lang']
elif temp_item['text'][-1] in ["","."]:
temp_item['lang'] = lang_list[-1]['lang']
elif len(lang_list[-1]['text']) >= len(temp_list[i + 1]['text']):
temp_item['lang'] = lang_list[-1]['lang']
else:
temp_item['lang'] = temp_list[i + 1]['lang']
else:
temp_item['lang'] = 'zh'
lang_list = merge_lang(lang_list,temp_item)
# 筛X
temp_list = lang_list temp_list = lang_list
lang_list = [] lang_list = []
for _, temp_item in enumerate(temp_list): for _, temp_item in enumerate(temp_list):
if temp_item["lang"] == "x": if temp_item['lang'] == 'x':
if lang_list: if lang_list:
temp_item["lang"] = lang_list[-1]["lang"] temp_item['lang'] = lang_list[-1]['lang']
elif len(temp_list) > 1: elif len(temp_list) > 1:
temp_item["lang"] = temp_list[1]["lang"] temp_item['lang'] = temp_list[1]['lang']
else: else:
temp_item["lang"] = "zh" temp_item['lang'] = 'zh'
lang_list = merge_lang(lang_list, temp_item) lang_list = merge_lang(lang_list,temp_item)
return lang_list return lang_list
if __name__ == "__main__": if __name__ == "__main__":
text = "MyGO?,你也喜欢まいご吗?" text = "MyGO?,你也喜欢まいご吗?"
@ -178,3 +219,7 @@ if __name__ == "__main__":
text = "ねえ、知ってる?最近、僕は天文学を勉強してるんだ。君の瞳が星空みたいにキラキラしてるからさ。" text = "ねえ、知ってる?最近、僕は天文学を勉強してるんだ。君の瞳が星空みたいにキラキラしてるからさ。"
print(LangSegmenter.getTexts(text)) print(LangSegmenter.getTexts(text))
text = "当时ThinkPad T60刚刚发布一同推出的还有一款名为Advanced Dock的扩展坞配件。这款扩展坞通过连接T60底部的插槽扩展出包括PCIe在内的一大堆接口并且自带电源让T60可以安装桌面显卡来提升性能。"
print(LangSegmenter.getTexts(text,"zh"))
print(LangSegmenter.getTexts(text))

View File

@ -181,20 +181,6 @@ def text_normalize(text):
return dest_text return dest_text
# 不排除英文的文本格式化
def mix_text_normalize(text):
# https://github.com/PaddlePaddle/PaddleSpeech/tree/develop/paddlespeech/t2s/frontend/zh_normalization
tx = TextNormalizer()
sentences = tx.normalize(text)
dest_text = ""
for sentence in sentences:
dest_text += replace_punctuation_with_en(sentence)
# 避免重复标点引起的参考泄露
dest_text = replace_consecutive_punctuation(dest_text)
return dest_text
if __name__ == "__main__": if __name__ == "__main__":
text = "啊——但是《原神》是由,米哈\游自主,研发的一款全.新开放世界.冒险游戏" text = "啊——但是《原神》是由,米哈\游自主,研发的一款全.新开放世界.冒险游戏"
text = "呣呣呣~就是…大人的鼹鼠党吧?" text = "呣呣呣~就是…大人的鼹鼠党吧?"

View File

@ -326,20 +326,6 @@ def text_normalize(text):
return dest_text return dest_text
# 不排除英文的文本格式化
def mix_text_normalize(text):
# https://github.com/PaddlePaddle/PaddleSpeech/tree/develop/paddlespeech/t2s/frontend/zh_normalization
tx = TextNormalizer()
sentences = tx.normalize(text)
dest_text = ""
for sentence in sentences:
dest_text += replace_punctuation_with_en(sentence)
# 避免重复标点引起的参考泄露
dest_text = replace_consecutive_punctuation(dest_text)
return dest_text
if __name__ == "__main__": if __name__ == "__main__":
text = "啊——但是《原神》是由,米哈\游自主,研发的一款全.新开放世界.冒险游戏" text = "啊——但是《原神》是由,米哈\游自主,研发的一款全.新开放世界.冒险游戏"
text = "呣呣呣~就是…大人的鼹鼠党吧?" text = "呣呣呣~就是…大人的鼹鼠党吧?"

View File

@ -93,13 +93,13 @@ class G2PWOnnxConverter:
sess_options.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_ENABLE_ALL sess_options.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_ENABLE_ALL
sess_options.execution_mode = onnxruntime.ExecutionMode.ORT_SEQUENTIAL sess_options.execution_mode = onnxruntime.ExecutionMode.ORT_SEQUENTIAL
sess_options.intra_op_num_threads = 2 if torch.cuda.is_available() else 0 sess_options.intra_op_num_threads = 2 if torch.cuda.is_available() else 0
try: if "CUDAExecutionProvider" in onnxruntime.get_available_providers():
self.session_g2pW = onnxruntime.InferenceSession( self.session_g2pW = onnxruntime.InferenceSession(
os.path.join(uncompress_path, "g2pW.onnx"), os.path.join(uncompress_path, "g2pW.onnx"),
sess_options=sess_options, sess_options=sess_options,
providers=["CUDAExecutionProvider", "CPUExecutionProvider"], providers=["CUDAExecutionProvider", "CPUExecutionProvider"],
) )
except: else:
self.session_g2pW = onnxruntime.InferenceSession( self.session_g2pW = onnxruntime.InferenceSession(
os.path.join(uncompress_path, "g2pW.onnx"), os.path.join(uncompress_path, "g2pW.onnx"),
sess_options=sess_options, sess_options=sess_options,

View File

@ -256,6 +256,24 @@ def replace_to_range(match) -> str:
return result return result
RE_VERSION_NUM = re.compile(r"((\d+)(\.\d+)(\.\d+)?(\.\d+)+)")
def replace_vrsion_num(match) -> str:
"""
Args:
match (re.Match)
Returns:
str
"""
result = ""
for c in match.group(1):
if c == ".":
result += ""
else:
result += num2str(c)
return result
def _get_value(value_string: str, use_zero: bool = True) -> List[str]: def _get_value(value_string: str, use_zero: bool = True) -> List[str]:
stripped = value_string.lstrip("0") stripped = value_string.lstrip("0")
if len(stripped) == 0: if len(stripped) == 0:
@ -308,7 +326,11 @@ def num2str(value_string: str) -> str:
result = verbalize_cardinal(integer) result = verbalize_cardinal(integer)
decimal = decimal.rstrip("0") if decimal.endswith("0"):
decimal = decimal.rstrip("0") + "0"
else:
decimal = decimal.rstrip("0")
if decimal: if decimal:
# '.22' is verbalized as '零点二二' # '.22' is verbalized as '零点二二'
# '3.20' is verbalized as '三点二 # '3.20' is verbalized as '三点二

View File

@ -25,6 +25,7 @@ from .chronology import replace_time
from .constants import F2H_ASCII_LETTERS from .constants import F2H_ASCII_LETTERS
from .constants import F2H_DIGITS from .constants import F2H_DIGITS
from .constants import F2H_SPACE from .constants import F2H_SPACE
from .num import RE_VERSION_NUM
from .num import RE_DECIMAL_NUM from .num import RE_DECIMAL_NUM
from .num import RE_DEFAULT_NUM from .num import RE_DEFAULT_NUM
from .num import RE_FRAC from .num import RE_FRAC
@ -36,6 +37,7 @@ from .num import RE_RANGE
from .num import RE_TO_RANGE from .num import RE_TO_RANGE
from .num import RE_ASMD from .num import RE_ASMD
from .num import RE_POWER from .num import RE_POWER
from .num import replace_vrsion_num
from .num import replace_default_num from .num import replace_default_num
from .num import replace_frac from .num import replace_frac
from .num import replace_negative_num from .num import replace_negative_num
@ -158,6 +160,7 @@ class TextNormalizer:
sentence = RE_RANGE.sub(replace_range, sentence) sentence = RE_RANGE.sub(replace_range, sentence)
sentence = RE_INTEGER.sub(replace_negative_num, sentence) sentence = RE_INTEGER.sub(replace_negative_num, sentence)
sentence = RE_VERSION_NUM.sub(replace_vrsion_num, sentence)
sentence = RE_DECIMAL_NUM.sub(replace_number, sentence) sentence = RE_DECIMAL_NUM.sub(replace_number, sentence)
sentence = RE_POSITIVE_QUANTIFIERS.sub(replace_positive_quantifier, sentence) sentence = RE_POSITIVE_QUANTIFIERS.sub(replace_positive_quantifier, sentence)
sentence = RE_DEFAULT_NUM.sub(replace_default_num, sentence) sentence = RE_DEFAULT_NUM.sub(replace_default_num, sentence)

View File

@ -64,6 +64,14 @@ If you are a Windows user (tested with win>=10), you can [download the integrate
**Users in China can [download the package here](https://www.yuque.com/baicaigongchang1145haoyuangong/ib3g1e/dkxgpiy9zb96hob4#KTvnO).** **Users in China can [download the package here](https://www.yuque.com/baicaigongchang1145haoyuangong/ib3g1e/dkxgpiy9zb96hob4#KTvnO).**
Install the program by running the following commands:
```pwsh
conda create -n GPTSoVits python=3.10
conda activate GPTSoVits
pwsh -F install.ps1 --Device <CU126|CU128|CPU> --Source <HF|HF-Mirror|ModelScope> [--DownloadUVR5]
```
### Linux ### Linux
```bash ```bash

117
api.py
View File

@ -543,66 +543,65 @@ from text import chinese
def get_phones_and_bert(text, language, version, final=False): def get_phones_and_bert(text, language, version, final=False):
if language in {"en", "all_zh", "all_ja", "all_ko", "all_yue"}: text = re.sub(r' {2,}', ' ', text)
formattext = text textlist = []
while " " in formattext: langlist = []
formattext = formattext.replace(" ", " ") if language == "all_zh":
if language == "all_zh": for tmp in LangSegmenter.getTexts(text,"zh"):
if re.search(r"[A-Za-z]", formattext): langlist.append(tmp["lang"])
formattext = re.sub(r"[a-z]", lambda x: x.group(0).upper(), formattext) textlist.append(tmp["text"])
formattext = chinese.mix_text_normalize(formattext) elif language == "all_yue":
return get_phones_and_bert(formattext, "zh", version) for tmp in LangSegmenter.getTexts(text,"zh"):
if tmp["lang"] == "zh":
tmp["lang"] = "yue"
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "all_ja":
for tmp in LangSegmenter.getTexts(text,"ja"):
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "all_ko":
for tmp in LangSegmenter.getTexts(text,"ko"):
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "en":
langlist.append("en")
textlist.append(text)
elif language == "auto":
for tmp in LangSegmenter.getTexts(text):
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "auto_yue":
for tmp in LangSegmenter.getTexts(text):
if tmp["lang"] == "zh":
tmp["lang"] = "yue"
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
else:
for tmp in LangSegmenter.getTexts(text):
if langlist:
if (tmp["lang"] == "en" and langlist[-1] == "en") or (tmp["lang"] != "en" and langlist[-1] != "en"):
textlist[-1] += tmp["text"]
continue
if tmp["lang"] == "en":
langlist.append(tmp["lang"])
else: else:
phones, word2ph, norm_text = clean_text_inf(formattext, language, version) # 因无法区别中日韩文汉字,以用户输入为准
bert = get_bert_feature(norm_text, word2ph).to(device) langlist.append(language)
elif language == "all_yue" and re.search(r"[A-Za-z]", formattext): textlist.append(tmp["text"])
formattext = re.sub(r"[a-z]", lambda x: x.group(0).upper(), formattext) phones_list = []
formattext = chinese.mix_text_normalize(formattext) bert_list = []
return get_phones_and_bert(formattext, "yue", version) norm_text_list = []
else: for i in range(len(textlist)):
phones, word2ph, norm_text = clean_text_inf(formattext, language, version) lang = langlist[i]
bert = torch.zeros( phones, word2ph, norm_text = clean_text_inf(textlist[i], lang, version)
(1024, len(phones)), bert = get_bert_inf(phones, word2ph, norm_text, lang)
dtype=torch.float16 if is_half == True else torch.float32, phones_list.append(phones)
).to(device) norm_text_list.append(norm_text)
elif language in {"zh", "ja", "ko", "yue", "auto", "auto_yue"}: bert_list.append(bert)
textlist = [] bert = torch.cat(bert_list, dim=1)
langlist = [] phones = sum(phones_list, [])
if language == "auto": norm_text = "".join(norm_text_list)
for tmp in LangSegmenter.getTexts(text):
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
elif language == "auto_yue":
for tmp in LangSegmenter.getTexts(text):
if tmp["lang"] == "zh":
tmp["lang"] = "yue"
langlist.append(tmp["lang"])
textlist.append(tmp["text"])
else:
for tmp in LangSegmenter.getTexts(text):
if langlist:
if (tmp["lang"] == "en" and langlist[-1] == "en") or (tmp["lang"] != "en" and langlist[-1] != "en"):
textlist[-1] += tmp["text"]
continue
if tmp["lang"] == "en":
langlist.append(tmp["lang"])
else:
# 因无法区别中日韩文汉字,以用户输入为准
langlist.append(language)
textlist.append(tmp["text"])
phones_list = []
bert_list = []
norm_text_list = []
for i in range(len(textlist)):
lang = langlist[i]
phones, word2ph, norm_text = clean_text_inf(textlist[i], lang, version)
bert = get_bert_inf(phones, word2ph, norm_text, lang)
phones_list.append(phones)
norm_text_list.append(norm_text)
bert_list.append(bert)
bert = torch.cat(bert_list, dim=1)
phones = sum(phones_list, [])
norm_text = "".join(norm_text_list)
if not final and len(phones) < 6: if not final and len(phones) < 6:
return get_phones_and_bert("." + text, language, version, final=True) return get_phones_and_bert("." + text, language, version, final=True)

View File

@ -62,6 +62,12 @@
**中国地区的用户可以[在此处下载整合包](https://www.yuque.com/baicaigongchang1145haoyuangong/ib3g1e/dkxgpiy9zb96hob4#KTvnO).** **中国地区的用户可以[在此处下载整合包](https://www.yuque.com/baicaigongchang1145haoyuangong/ib3g1e/dkxgpiy9zb96hob4#KTvnO).**
```pwsh
conda create -n GPTSoVits python=3.10
conda activate GPTSoVits
pwsh -F install.ps1 --Device <CU126|CU128|CPU> --Source <HF|HF-Mirror|ModelScope> [--DownloadUVR5]
```
### Linux ### Linux
```bash ```bash

View File

@ -58,6 +58,12 @@ https://github.com/RVC-Boss/GPT-SoVITS/assets/129054828/05bee1fa-bdd8-4d85-9350-
Windows 사용자라면 (win>=10에서 테스트됨), [통합 패키지를 다운로드](https://huggingface.co/lj1995/GPT-SoVITS-windows-package/resolve/main/GPT-SoVITS-v3lora-20250228.7z?download=true)한 후 압축을 풀고 _go-webui.bat_ 파일을 더블 클릭하면 GPT-SoVITS-WebUI를 시작할 수 있습니다. Windows 사용자라면 (win>=10에서 테스트됨), [통합 패키지를 다운로드](https://huggingface.co/lj1995/GPT-SoVITS-windows-package/resolve/main/GPT-SoVITS-v3lora-20250228.7z?download=true)한 후 압축을 풀고 _go-webui.bat_ 파일을 더블 클릭하면 GPT-SoVITS-WebUI를 시작할 수 있습니다.
```pwsh
conda create -n GPTSoVits python=3.10
conda activate GPTSoVits
pwsh -F install.ps1 --Device <CU126|CU128|CPU> --Source <HF|HF-Mirror|ModelScope> [--DownloadUVR5]
```
### Linux ### Linux
```bash ```bash

View File

@ -58,6 +58,12 @@ https://github.com/RVC-Boss/GPT-SoVITS/assets/129054828/05bee1fa-bdd8-4d85-9350-
Eğer bir Windows kullanıcısıysanız (win>=10 ile test edilmiştir), [entegre paketi indirin](https://huggingface.co/lj1995/GPT-SoVITS-windows-package/resolve/main/GPT-SoVITS-v3lora-20250228.7z?download=true) ve _go-webui.bat_ dosyasına çift tıklayarak GPT-SoVITS-WebUI'yi başlatın. Eğer bir Windows kullanıcısıysanız (win>=10 ile test edilmiştir), [entegre paketi indirin](https://huggingface.co/lj1995/GPT-SoVITS-windows-package/resolve/main/GPT-SoVITS-v3lora-20250228.7z?download=true) ve _go-webui.bat_ dosyasına çift tıklayarak GPT-SoVITS-WebUI'yi başlatın.
```pwsh
conda create -n GPTSoVits python=3.10
conda activate GPTSoVits
pwsh -F install.ps1 --Device <CU126|CU128|CPU> --Source <HF|HF-Mirror|ModelScope> [--DownloadUVR5]
```
### Linux ### Linux
```bash ```bash

241
install.ps1 Normal file
View File

@ -0,0 +1,241 @@
Param (
[Parameter(Mandatory=$true)][ValidateSet("CU126", "CU128", "CPU")][string]$Device,
[Parameter(Mandatory=$true)][ValidateSet("HF", "HF-Mirror", "ModelScope")][string]$Source,
[switch]$DownloadUVR5
)
$global:ErrorActionPreference = 'Stop'
trap {
Write-ErrorLog $_
}
function Write-ErrorLog {
param (
[System.Management.Automation.ErrorRecord]$ErrorRecord
)
Write-Host "`n[ERROR] Command failed:" -ForegroundColor Red
if (-not $ErrorRecord.Exception.Message){
} else {
Write-Host "Message:" -ForegroundColor Red
$ErrorRecord.Exception.Message -split "`n" | ForEach-Object {
Write-Host " $_"
}
}
Write-Host "Command:" -ForegroundColor Red -NoNewline
Write-Host " $($ErrorRecord.InvocationInfo.Line)".Replace("`r", "").Replace("`n", "")
Write-Host "Location:" -ForegroundColor Red -NoNewline
Write-Host " $($ErrorRecord.InvocationInfo.ScriptName):$($ErrorRecord.InvocationInfo.ScriptLineNumber)"
Write-Host "Call Stack:" -ForegroundColor DarkRed
$ErrorRecord.ScriptStackTrace -split "`n" | ForEach-Object {
Write-Host " $_" -ForegroundColor DarkRed
}
exit 1
}
function Write-Info($msg) {
Write-Host "[INFO]:" -ForegroundColor Green -NoNewline
Write-Host " $msg"
}
function Write-Success($msg) {
Write-Host "[SUCCESS]:" -ForegroundColor Blue -NoNewline
Write-Host " $msg"
}
function Invoke-Conda {
param (
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$Args
)
$output = & conda install -y -q -c conda-forge @Args 2>&1
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0) {
Write-Host "Conda Install $Args Failed" -ForegroundColor Red
$errorMessages = @()
foreach ($item in $output) {
if ($item -is [System.Management.Automation.ErrorRecord]) {
$msg = $item.Exception.Message
Write-Host "$msg" -ForegroundColor Red
$errorMessages += $msg
}
else {
Write-Host $item
$errorMessages += $item
}
}
throw [System.Exception]::new(($errorMessages -join "`n"))
}
}
function Invoke-Pip {
param (
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$Args
)
$output = & pip install @Args 2>&1
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0) {
$errorMessages = @()
Write-Host "Pip Install $Args Failed" -ForegroundColor Red
foreach ($item in $output) {
if ($item -is [System.Management.Automation.ErrorRecord]) {
$msg = $item.Exception.Message
Write-Host "$msg" -ForegroundColor Red
$errorMessages += $msg
}
else {
Write-Host $item
$errorMessages += $item
}
}
throw [System.Exception]::new(($errorMessages -join "`n"))
}
}
function Invoke-Download {
param (
[Parameter(Mandatory = $true)]
[string]$Uri,
[Parameter()]
[string]$OutFile
)
try {
$params = @{
Uri = $Uri
}
if ($OutFile) {
$params["OutFile"] = $OutFile
}
$null = Invoke-WebRequest @params -ErrorAction Stop
} catch {
Write-Host "Failed to download:" -ForegroundColor Red
Write-Host " $Uri"
throw
}
}
function Invoke-Unzip {
param($ZipPath, $DestPath)
Expand-Archive -Path $ZipPath -DestinationPath $DestPath -Force
Remove-Item $ZipPath -Force
}
chcp 65001
Set-Location $PSScriptRoot
Write-Info "Installing FFmpeg & CMake..."
Invoke-Conda ffmpeg cmake
Write-Success "FFmpeg & CMake Installed"
$PretrainedURL = ""
$G2PWURL = ""
$UVR5URL = ""
$NLTKURL = ""
$OpenJTalkURL = ""
switch ($Source) {
"HF" {
Write-Info "Download Model From HuggingFace"
$PretrainedURL = "https://huggingface.co/XXXXRT/GPT-SoVITS-Pretrained/resolve/main/pretrained_models.zip"
$G2PWURL = "https://huggingface.co/XXXXRT/GPT-SoVITS-Pretrained/resolve/main/G2PWModel.zip"
$UVR5URL = "https://huggingface.co/XXXXRT/GPT-SoVITS-Pretrained/resolve/main/uvr5_weights.zip"
$NLTKURL = "https://huggingface.co/XXXXRT/GPT-SoVITS-Pretrained/resolve/main/nltk_data.zip"
$OpenJTalkURL = "https://huggingface.co/XXXXRT/GPT-SoVITS-Pretrained/resolve/main/open_jtalk_dic_utf_8-1.11.tar.gz"
}
"HF-Mirror" {
Write-Info "Download Model From HuggingFace-Mirror"
$PretrainedURL = "https://hf-mirror.com/XXXXRT/GPT-SoVITS-Pretrained/resolve/main/pretrained_models.zip"
$G2PWURL = "https://hf-mirror.com/XXXXRT/GPT-SoVITS-Pretrained/resolve/main/G2PWModel.zip"
$UVR5URL = "https://hf-mirror.com/XXXXRT/GPT-SoVITS-Pretrained/resolve/main/uvr5_weights.zip"
$NLTKURL = "https://hf-mirror.com/XXXXRT/GPT-SoVITS-Pretrained/resolve/main/nltk_data.zip"
$OpenJTalkURL = "https://hf-mirror.com/XXXXRT/GPT-SoVITS-Pretrained/resolve/main/open_jtalk_dic_utf_8-1.11.tar.gz"
}
"ModelScope" {
Write-Info "Download Model From ModelScope"
$PretrainedURL = "https://www.modelscope.cn/models/XXXXRT/GPT-SoVITS-Pretrained/resolve/master/pretrained_models.zip"
$G2PWURL = "https://www.modelscope.cn/models/XXXXRT/GPT-SoVITS-Pretrained/resolve/master/G2PWModel.zip"
$UVR5URL = "https://www.modelscope.cn/models/XXXXRT/GPT-SoVITS-Pretrained/resolve/master/uvr5_weights.zip"
$NLTKURL = "https://www.modelscope.cn/models/XXXXRT/GPT-SoVITS-Pretrained/resolve/master/nltk_data.zip"
$OpenJTalkURL = "https://www.modelscope.cn/models/XXXXRT/GPT-SoVITS-Pretrained/resolve/master/open_jtalk_dic_utf_8-1.11.tar.gz"
}
}
if (-not (Test-Path "GPT_SoVITS/pretrained_models/sv")) {
Write-Info "Downloading Pretrained Models..."
Invoke-Download -Uri $PretrainedURL -OutFile "pretrained_models.zip"
Invoke-Unzip "pretrained_models.zip" "GPT_SoVITS"
Write-Success "Pretrained Models Downloaded"
} else {
Write-Info "Pretrained Model Exists"
Write-Info "Skip Downloading Pretrained Models"
}
if (-not (Test-Path "GPT_SoVITS/text/G2PWModel")) {
Write-Info "Downloading G2PWModel..."
Invoke-Download -Uri $G2PWURL -OutFile "G2PWModel.zip"
Invoke-Unzip "G2PWModel.zip" "GPT_SoVITS/text"
Write-Success "G2PWModel Downloaded"
} else {
Write-Info "G2PWModel Exists"
Write-Info "Skip Downloading G2PWModel"
}
if ($DownloadUVR5) {
if (-not (Test-Path "tools/uvr5/uvr5_weights")) {
Write-Info "Downloading UVR5 Models..."
Invoke-Download -Uri $UVR5URL -OutFile "uvr5_weights.zip"
Invoke-Unzip "uvr5_weights.zip" "tools/uvr5"
Write-Success "UVR5 Models Downloaded"
} else {
Write-Info "UVR5 Models Exists"
Write-Info "Skip Downloading UVR5 Models"
}
}
switch ($Device) {
"CU128" {
Write-Info "Installing PyTorch For CUDA 12.8..."
Invoke-Pip torch torchaudio --index-url "https://download.pytorch.org/whl/cu128"
}
"CU126" {
Write-Info "Installing PyTorch For CUDA 12.6..."
Invoke-Pip torch torchaudio --index-url "https://download.pytorch.org/whl/cu126"
}
"CPU" {
Write-Info "Installing PyTorch For CPU..."
Invoke-Pip torch torchaudio --index-url "https://download.pytorch.org/whl/cpu"
}
}
Write-Success "PyTorch Installed"
Write-Info "Installing Python Dependencies From requirements.txt..."
Invoke-Pip -r extra-req.txt --no-deps
Invoke-Pip -r requirements.txt
Write-Success "Python Dependencies Installed"
Write-Info "Downloading NLTK Data..."
Invoke-Download -Uri $NLTKURL -OutFile "nltk_data.zip"
Invoke-Unzip "nltk_data.zip" (python -c "import sys; print(sys.prefix)").Trim()
Write-Info "Downloading Open JTalk Dict..."
Invoke-Download -Uri $OpenJTalkURL -OutFile "open_jtalk_dic_utf_8-1.11.tar.gz"
$target = (python -c "import os, pyopenjtalk; print(os.path.dirname(pyopenjtalk.__file__))").Trim()
tar -xzf open_jtalk_dic_utf_8-1.11.tar.gz -C $target
Remove-Item "open_jtalk_dic_utf_8-1.11.tar.gz" -Force
Write-Success "Open JTalk Dic Downloaded"
Write-Success "Installation Completed"

View File

@ -48,11 +48,12 @@ run_pip_quiet() {
} }
run_wget_quiet() { run_wget_quiet() {
local output if wget --tries=25 --wait=5 --read-timeout=40 -q --show-progress "$@" 2>&1; then
output=$(wget --tries=25 --wait=5 --read-timeout=40 --retry-on-http-error=404 "$@" 2>&1) || { tput cuu1 && tput el
echo -e "${ERROR} Wget failed:\n$output" else
echo -e "${ERROR} Wget failed"
exit 1 exit 1
} fi
} }
if ! command -v conda &>/dev/null; then if ! command -v conda &>/dev/null; then
@ -170,7 +171,16 @@ if ! $USE_HF && ! $USE_HF_MIRROR && ! $USE_MODELSCOPE; then
exit 1 exit 1
fi fi
# 安装构建工具 case "$(uname -m)" in
x86_64 | amd64) SYSROOT_PKG="sysroot_linux-64>=2.28" ;;
aarch64 | arm64) SYSROOT_PKG="sysroot_linux-aarch64>=2.28" ;;
ppc64le) SYSROOT_PKG="sysroot_linux-ppc64le>=2.28" ;;
*)
echo "Unsupported architecture: $(uname -m)"
exit 1
;;
esac
# Install build tools # Install build tools
echo -e "${INFO}Detected system: $(uname -s) $(uname -r) $(uname -m)" echo -e "${INFO}Detected system: $(uname -s) $(uname -r) $(uname -m)"
if [ "$(uname)" != "Darwin" ]; then if [ "$(uname)" != "Darwin" ]; then
@ -178,10 +188,14 @@ if [ "$(uname)" != "Darwin" ]; then
if [ "$gcc_major_version" -lt 11 ]; then if [ "$gcc_major_version" -lt 11 ]; then
echo -e "${INFO}Installing GCC & G++..." echo -e "${INFO}Installing GCC & G++..."
run_conda_quiet gcc=11 gxx=11 run_conda_quiet gcc=11 gxx=11
run_conda_quiet "$SYSROOT_PKG"
echo -e "${SUCCESS}GCC & G++ Installed..." echo -e "${SUCCESS}GCC & G++ Installed..."
else else
echo -e "${INFO}Detected GCC Version: $gcc_major_version" echo -e "${INFO}Detected GCC Version: $gcc_major_version"
echo -e "${INFO}Skip Installing GCC & G++ From Conda-Forge" echo -e "${INFO}Skip Installing GCC & G++ From Conda-Forge"
echo -e "${INFO}Installing libstdcxx-ng From Conda-Forge"
run_conda_quiet "libstdcxx-ng>=$gcc_major_version"
echo -e "${SUCCESS}libstdcxx-ng=$gcc_major_version Installed..."
fi fi
else else
if ! xcode-select -p &>/dev/null; then if ! xcode-select -p &>/dev/null; then
@ -238,10 +252,7 @@ elif [ "$USE_MODELSCOPE" = "true" ]; then
PYOPENJTALK_URL="https://www.modelscope.cn/models/XXXXRT/GPT-SoVITS-Pretrained/resolve/master/open_jtalk_dic_utf_8-1.11.tar.gz" PYOPENJTALK_URL="https://www.modelscope.cn/models/XXXXRT/GPT-SoVITS-Pretrained/resolve/master/open_jtalk_dic_utf_8-1.11.tar.gz"
fi fi
if find -L "GPT_SoVITS/pretrained_models" -mindepth 1 ! -name '.gitignore' | grep -q .; then if [ ! -d "GPT_SoVITS/pretrained_models/sv" ]; then
echo -e "${INFO}Pretrained Model Exists"
echo -e "${INFO}Skip Downloading Pretrained Models"
else
echo -e "${INFO}Downloading Pretrained Models..." echo -e "${INFO}Downloading Pretrained Models..."
rm -rf pretrained_models.zip rm -rf pretrained_models.zip
run_wget_quiet "$PRETRINED_URL" run_wget_quiet "$PRETRINED_URL"
@ -249,6 +260,9 @@ else
unzip -q -o pretrained_models.zip -d GPT_SoVITS unzip -q -o pretrained_models.zip -d GPT_SoVITS
rm -rf pretrained_models.zip rm -rf pretrained_models.zip
echo -e "${SUCCESS}Pretrained Models Downloaded" echo -e "${SUCCESS}Pretrained Models Downloaded"
else
echo -e "${INFO}Pretrained Model Exists"
echo -e "${INFO}Skip Downloading Pretrained Models"
fi fi
if [ ! -d "GPT_SoVITS/text/G2PWModel" ]; then if [ ! -d "GPT_SoVITS/text/G2PWModel" ]; then