Spaces:
Running
Running
Upload app.py
Browse files
app.py
CHANGED
|
@@ -9,25 +9,10 @@ logging.getLogger("charset_normalizer").setLevel(logging.ERROR)
|
|
| 9 |
logging.getLogger("torchaudio._extension").setLevel(logging.ERROR)
|
| 10 |
import pdb
|
| 11 |
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
"gpt_path", gweight_data)
|
| 17 |
-
else:
|
| 18 |
-
gpt_path = os.environ.get(
|
| 19 |
-
"gpt_path", "GPT_SoVITS/pretrained_models/s1bert25hz-2kh-longer-epoch=68e-step=50232.ckpt")
|
| 20 |
-
|
| 21 |
-
if os.path.exists("./sweight.txt"):
|
| 22 |
-
with open("./sweight.txt", 'r',encoding="utf-8") as file:
|
| 23 |
-
sweight_data = file.read()
|
| 24 |
-
sovits_path = os.environ.get("sovits_path", sweight_data)
|
| 25 |
-
else:
|
| 26 |
-
sovits_path = os.environ.get("sovits_path", "GPT_SoVITS/pretrained_models/s2G488k.pth")
|
| 27 |
-
# gpt_path = os.environ.get(
|
| 28 |
-
# "gpt_path", "pretrained_models/s1bert25hz-2kh-longer-epoch=68e-step=50232.ckpt"
|
| 29 |
-
# )
|
| 30 |
-
# sovits_path = os.environ.get("sovits_path", "pretrained_models/s2G488k.pth")
|
| 31 |
cnhubert_base_path = os.environ.get(
|
| 32 |
"cnhubert_base_path", "pretrained_models/chinese-hubert-base"
|
| 33 |
)
|
|
@@ -36,8 +21,6 @@ bert_path = os.environ.get(
|
|
| 36 |
)
|
| 37 |
infer_ttswebui = os.environ.get("infer_ttswebui", 9872)
|
| 38 |
infer_ttswebui = int(infer_ttswebui)
|
| 39 |
-
is_share = os.environ.get("is_share", "False")
|
| 40 |
-
is_share=eval(is_share)
|
| 41 |
if "_CUDA_VISIBLE_DEVICES" in os.environ:
|
| 42 |
os.environ["CUDA_VISIBLE_DEVICES"] = os.environ["_CUDA_VISIBLE_DEVICES"]
|
| 43 |
is_half = eval(os.environ.get("is_half", "True"))
|
|
@@ -47,6 +30,10 @@ import numpy as np
|
|
| 47 |
import librosa,torch
|
| 48 |
from feature_extractor import cnhubert
|
| 49 |
cnhubert.cnhubert_base_path=cnhubert_base_path
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
from module.models import SynthesizerTrn
|
| 52 |
from AR.models.t2s_lightning_module import Text2SemanticLightningModule
|
|
@@ -55,17 +42,12 @@ from text.cleaner import clean_text
|
|
| 55 |
from time import time as ttime
|
| 56 |
from module.mel_processing import spectrogram_torch
|
| 57 |
from my_utils import load_audio
|
| 58 |
-
from tools.i18n.i18n import I18nAuto
|
| 59 |
-
i18n = I18nAuto()
|
| 60 |
|
| 61 |
-
|
| 62 |
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
device = "mps"
|
| 67 |
-
else:
|
| 68 |
-
device = "cpu"
|
| 69 |
|
| 70 |
tokenizer = AutoTokenizer.from_pretrained(bert_path)
|
| 71 |
bert_model = AutoModelForMaskedLM.from_pretrained(bert_path)
|
|
@@ -74,11 +56,12 @@ if is_half == True:
|
|
| 74 |
else:
|
| 75 |
bert_model = bert_model.to(device)
|
| 76 |
|
|
|
|
| 77 |
def get_bert_feature(text, word2ph):
|
| 78 |
with torch.no_grad():
|
| 79 |
inputs = tokenizer(text, return_tensors="pt")
|
| 80 |
for i in inputs:
|
| 81 |
-
inputs[i] = inputs[i].to(device)
|
| 82 |
res = bert_model(**inputs, output_hidden_states=True)
|
| 83 |
res = torch.cat(res["hidden_states"][-3:-2], -1)[0].cpu()[1:-1]
|
| 84 |
assert len(word2ph) == len(text)
|
|
@@ -116,7 +99,6 @@ class DictToAttrRecursive(dict):
|
|
| 116 |
except KeyError:
|
| 117 |
raise AttributeError(f"Attribute {item} not found")
|
| 118 |
|
| 119 |
-
|
| 120 |
ssl_model = cnhubert.get_model()
|
| 121 |
if is_half == True:
|
| 122 |
ssl_model = ssl_model.half().to(device)
|
|
@@ -143,7 +125,6 @@ def change_sovits_weights(sovits_path):
|
|
| 143 |
vq_model = vq_model.to(device)
|
| 144 |
vq_model.eval()
|
| 145 |
print(vq_model.load_state_dict(dict_s2["weight"], strict=False))
|
| 146 |
-
with open("./sweight.txt","w",encoding="utf-8")as f:f.write(sovits_path)
|
| 147 |
change_sovits_weights(sovits_path)
|
| 148 |
|
| 149 |
def change_gpt_weights(gpt_path):
|
|
@@ -160,9 +141,9 @@ def change_gpt_weights(gpt_path):
|
|
| 160 |
t2s_model.eval()
|
| 161 |
total = sum([param.nelement() for param in t2s_model.parameters()])
|
| 162 |
print("Number of parameter: %.2fM" % (total / 1e6))
|
| 163 |
-
with open("./gweight.txt","w",encoding="utf-8")as f:f.write(gpt_path)
|
| 164 |
change_gpt_weights(gpt_path)
|
| 165 |
|
|
|
|
| 166 |
def get_spepc(hps, filename):
|
| 167 |
audio = load_audio(filename, int(hps.data.sampling_rate))
|
| 168 |
audio = torch.FloatTensor(audio)
|
|
@@ -211,8 +192,6 @@ def clean_text_inf(text, language):
|
|
| 211 |
phones = cleaned_text_to_sequence(phones)
|
| 212 |
|
| 213 |
return phones, word2ph, norm_text
|
| 214 |
-
|
| 215 |
-
|
| 216 |
def get_bert_inf(phones, word2ph, norm_text, language):
|
| 217 |
if language == "zh":
|
| 218 |
bert = get_bert_feature(norm_text, word2ph).to(device)
|
|
@@ -292,7 +271,7 @@ def get_tts_wav(ref_wav_path, prompt_text, prompt_language, text, text_language,
|
|
| 292 |
t1 = ttime()
|
| 293 |
prompt_language = dict_language[prompt_language]
|
| 294 |
text_language = dict_language[text_language]
|
| 295 |
-
|
| 296 |
if prompt_language == "en":
|
| 297 |
phones1, word2ph1, norm_text1 = clean_text_inf(prompt_text, prompt_language)
|
| 298 |
else:
|
|
@@ -309,7 +288,7 @@ def get_tts_wav(ref_wav_path, prompt_text, prompt_language, text, text_language,
|
|
| 309 |
bert1 = get_bert_inf(phones1, word2ph1, norm_text1, prompt_language)
|
| 310 |
else:
|
| 311 |
bert1 = nonen_get_bert_inf(prompt_text, prompt_language)
|
| 312 |
-
|
| 313 |
for text in texts:
|
| 314 |
# 解决输入目标文本的空行导致报错的问题
|
| 315 |
if (len(text.strip()) == 0):
|
|
@@ -323,7 +302,6 @@ def get_tts_wav(ref_wav_path, prompt_text, prompt_language, text, text_language,
|
|
| 323 |
bert2 = get_bert_inf(phones2, word2ph2, norm_text2, text_language)
|
| 324 |
else:
|
| 325 |
bert2 = nonen_get_bert_inf(text, text_language)
|
| 326 |
-
|
| 327 |
bert = torch.cat([bert1, bert2], 1)
|
| 328 |
|
| 329 |
all_phoneme_ids = torch.LongTensor(phones1 + phones2).to(device).unsqueeze(0)
|
|
@@ -446,96 +424,86 @@ def cut2(inp):
|
|
| 446 |
def cut3(inp):
|
| 447 |
inp = inp.strip("\n")
|
| 448 |
return "\n".join(["%s。" % item for item in inp.strip("。").split("。")])
|
| 449 |
-
|
| 450 |
-
|
| 451 |
-
|
| 452 |
-
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
def get_weights_names():
|
| 471 |
-
SoVITS_names = [pretrained_sovits_name]
|
| 472 |
-
for name in os.listdir(SoVITS_weight_root):
|
| 473 |
-
if name.endswith(".pth"):SoVITS_names.append("%s/%s"%(SoVITS_weight_root,name))
|
| 474 |
-
GPT_names = [pretrained_gpt_name]
|
| 475 |
-
for name in os.listdir(GPT_weight_root):
|
| 476 |
-
if name.endswith(".ckpt"): GPT_names.append("%s/%s"%(GPT_weight_root,name))
|
| 477 |
-
return SoVITS_names,GPT_names
|
| 478 |
-
SoVITS_names,GPT_names = get_weights_names()
|
| 479 |
|
| 480 |
with gr.Blocks(title="GPT-SoVITS WebUI") as app:
|
| 481 |
-
gr.Markdown(
|
| 482 |
-
|
| 483 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 484 |
with gr.Group():
|
| 485 |
-
gr.Markdown(value=
|
| 486 |
-
with gr.Row():
|
| 487 |
-
GPT_dropdown = gr.Dropdown(label=i18n("GPT模型列表"), choices=sorted(GPT_names, key=custom_sort_key), value=gpt_path,interactive=True)
|
| 488 |
-
SoVITS_dropdown = gr.Dropdown(label=i18n("SoVITS模型列表"), choices=sorted(SoVITS_names, key=custom_sort_key), value=sovits_path,interactive=True)
|
| 489 |
-
refresh_button = gr.Button(i18n("刷新模型路径"), variant="primary")
|
| 490 |
-
refresh_button.click(fn=change_choices, inputs=[], outputs=[SoVITS_dropdown, GPT_dropdown])
|
| 491 |
-
SoVITS_dropdown.change(change_sovits_weights,[SoVITS_dropdown],[])
|
| 492 |
-
GPT_dropdown.change(change_gpt_weights,[GPT_dropdown],[])
|
| 493 |
-
gr.Markdown(value=i18n("*请上传并填写参考信息"))
|
| 494 |
with gr.Row():
|
| 495 |
-
|
| 496 |
-
|
| 497 |
-
|
| 498 |
-
|
| 499 |
-
|
| 500 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 501 |
with gr.Row():
|
| 502 |
-
text = gr.Textbox(label=
|
| 503 |
text_language = gr.Dropdown(
|
| 504 |
-
label=
|
| 505 |
-
)
|
| 506 |
-
how_to_cut = gr.Radio(
|
| 507 |
-
label=i18n("怎么切"),
|
| 508 |
-
choices=[i18n("不切"),i18n("凑五句一切"),i18n("凑50字一切"),i18n("按中文句号。切"),i18n("按英文句号.切"),],
|
| 509 |
-
value=i18n("凑50字一切"),
|
| 510 |
-
interactive=True,
|
| 511 |
)
|
| 512 |
-
inference_button = gr.Button(
|
| 513 |
-
output = gr.Audio(label=
|
| 514 |
-
|
| 515 |
inference_button.click(
|
| 516 |
get_tts_wav,
|
| 517 |
-
[
|
| 518 |
[output],
|
| 519 |
)
|
| 520 |
|
| 521 |
-
|
| 522 |
-
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
app.queue(concurrency_count=511, max_size=1022).launch(
|
| 536 |
-
server_name="0.0.0.0",
|
| 537 |
-
inbrowser=True,
|
| 538 |
-
share=is_share,
|
| 539 |
-
server_port=infer_ttswebui,
|
| 540 |
-
quiet=True,
|
| 541 |
-
)
|
|
|
|
| 9 |
logging.getLogger("torchaudio._extension").setLevel(logging.ERROR)
|
| 10 |
import pdb
|
| 11 |
|
| 12 |
+
gpt_path = os.environ.get(
|
| 13 |
+
"gpt_path", "models/Taffy/Taffy-e5.ckpt"
|
| 14 |
+
)
|
| 15 |
+
sovits_path = os.environ.get("sovits_path", "models/Taffy/Taffy_e20_s1020.pth")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
cnhubert_base_path = os.environ.get(
|
| 17 |
"cnhubert_base_path", "pretrained_models/chinese-hubert-base"
|
| 18 |
)
|
|
|
|
| 21 |
)
|
| 22 |
infer_ttswebui = os.environ.get("infer_ttswebui", 9872)
|
| 23 |
infer_ttswebui = int(infer_ttswebui)
|
|
|
|
|
|
|
| 24 |
if "_CUDA_VISIBLE_DEVICES" in os.environ:
|
| 25 |
os.environ["CUDA_VISIBLE_DEVICES"] = os.environ["_CUDA_VISIBLE_DEVICES"]
|
| 26 |
is_half = eval(os.environ.get("is_half", "True"))
|
|
|
|
| 30 |
import librosa,torch
|
| 31 |
from feature_extractor import cnhubert
|
| 32 |
cnhubert.cnhubert_base_path=cnhubert_base_path
|
| 33 |
+
import ssl
|
| 34 |
+
ssl._create_default_https_context = ssl._create_unverified_context
|
| 35 |
+
import nltk
|
| 36 |
+
nltk.download('cmudict')
|
| 37 |
|
| 38 |
from module.models import SynthesizerTrn
|
| 39 |
from AR.models.t2s_lightning_module import Text2SemanticLightningModule
|
|
|
|
| 42 |
from time import time as ttime
|
| 43 |
from module.mel_processing import spectrogram_torch
|
| 44 |
from my_utils import load_audio
|
|
|
|
|
|
|
| 45 |
|
| 46 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 47 |
|
| 48 |
+
is_half = eval(
|
| 49 |
+
os.environ.get("is_half", "True" if torch.cuda.is_available() else "False")
|
| 50 |
+
)
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
tokenizer = AutoTokenizer.from_pretrained(bert_path)
|
| 53 |
bert_model = AutoModelForMaskedLM.from_pretrained(bert_path)
|
|
|
|
| 56 |
else:
|
| 57 |
bert_model = bert_model.to(device)
|
| 58 |
|
| 59 |
+
|
| 60 |
def get_bert_feature(text, word2ph):
|
| 61 |
with torch.no_grad():
|
| 62 |
inputs = tokenizer(text, return_tensors="pt")
|
| 63 |
for i in inputs:
|
| 64 |
+
inputs[i] = inputs[i].to(device) #####输入是long不用管精度问题,精度随bert_model
|
| 65 |
res = bert_model(**inputs, output_hidden_states=True)
|
| 66 |
res = torch.cat(res["hidden_states"][-3:-2], -1)[0].cpu()[1:-1]
|
| 67 |
assert len(word2ph) == len(text)
|
|
|
|
| 99 |
except KeyError:
|
| 100 |
raise AttributeError(f"Attribute {item} not found")
|
| 101 |
|
|
|
|
| 102 |
ssl_model = cnhubert.get_model()
|
| 103 |
if is_half == True:
|
| 104 |
ssl_model = ssl_model.half().to(device)
|
|
|
|
| 125 |
vq_model = vq_model.to(device)
|
| 126 |
vq_model.eval()
|
| 127 |
print(vq_model.load_state_dict(dict_s2["weight"], strict=False))
|
|
|
|
| 128 |
change_sovits_weights(sovits_path)
|
| 129 |
|
| 130 |
def change_gpt_weights(gpt_path):
|
|
|
|
| 141 |
t2s_model.eval()
|
| 142 |
total = sum([param.nelement() for param in t2s_model.parameters()])
|
| 143 |
print("Number of parameter: %.2fM" % (total / 1e6))
|
|
|
|
| 144 |
change_gpt_weights(gpt_path)
|
| 145 |
|
| 146 |
+
|
| 147 |
def get_spepc(hps, filename):
|
| 148 |
audio = load_audio(filename, int(hps.data.sampling_rate))
|
| 149 |
audio = torch.FloatTensor(audio)
|
|
|
|
| 192 |
phones = cleaned_text_to_sequence(phones)
|
| 193 |
|
| 194 |
return phones, word2ph, norm_text
|
|
|
|
|
|
|
| 195 |
def get_bert_inf(phones, word2ph, norm_text, language):
|
| 196 |
if language == "zh":
|
| 197 |
bert = get_bert_feature(norm_text, word2ph).to(device)
|
|
|
|
| 271 |
t1 = ttime()
|
| 272 |
prompt_language = dict_language[prompt_language]
|
| 273 |
text_language = dict_language[text_language]
|
| 274 |
+
|
| 275 |
if prompt_language == "en":
|
| 276 |
phones1, word2ph1, norm_text1 = clean_text_inf(prompt_text, prompt_language)
|
| 277 |
else:
|
|
|
|
| 288 |
bert1 = get_bert_inf(phones1, word2ph1, norm_text1, prompt_language)
|
| 289 |
else:
|
| 290 |
bert1 = nonen_get_bert_inf(prompt_text, prompt_language)
|
| 291 |
+
|
| 292 |
for text in texts:
|
| 293 |
# 解决输入目标文本的空行导致报错的问题
|
| 294 |
if (len(text.strip()) == 0):
|
|
|
|
| 302 |
bert2 = get_bert_inf(phones2, word2ph2, norm_text2, text_language)
|
| 303 |
else:
|
| 304 |
bert2 = nonen_get_bert_inf(text, text_language)
|
|
|
|
| 305 |
bert = torch.cat([bert1, bert2], 1)
|
| 306 |
|
| 307 |
all_phoneme_ids = torch.LongTensor(phones1 + phones2).to(device).unsqueeze(0)
|
|
|
|
| 424 |
def cut3(inp):
|
| 425 |
inp = inp.strip("\n")
|
| 426 |
return "\n".join(["%s。" % item for item in inp.strip("。").split("。")])
|
| 427 |
+
|
| 428 |
+
def scan_audio_files(folder_path):
|
| 429 |
+
""" 扫描指定文件夹获取音频文件列表 """
|
| 430 |
+
return [f for f in os.listdir(folder_path) if f.endswith('.wav')]
|
| 431 |
+
|
| 432 |
+
def load_audio_text_mappings(folder_path, list_file_name):
|
| 433 |
+
text_to_audio_mappings = {}
|
| 434 |
+
audio_to_text_mappings = {}
|
| 435 |
+
with open(os.path.join(folder_path, list_file_name), 'r', encoding='utf-8') as file:
|
| 436 |
+
for line in file:
|
| 437 |
+
parts = line.strip().split('|')
|
| 438 |
+
if len(parts) >= 4:
|
| 439 |
+
audio_file_name = parts[0]
|
| 440 |
+
text = parts[3]
|
| 441 |
+
audio_file_path = os.path.join(folder_path, audio_file_name)
|
| 442 |
+
text_to_audio_mappings[text] = audio_file_path
|
| 443 |
+
audio_to_text_mappings[audio_file_path] = text
|
| 444 |
+
return text_to_audio_mappings, audio_to_text_mappings
|
| 445 |
+
|
| 446 |
+
audio_folder_path = 'audio/Taffy'
|
| 447 |
+
text_to_audio_mappings, audio_to_text_mappings = load_audio_text_mappings(audio_folder_path, 'Taffy.list')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 448 |
|
| 449 |
with gr.Blocks(title="GPT-SoVITS WebUI") as app:
|
| 450 |
+
gr.Markdown(value="""
|
| 451 |
+
# <center>【AI塔菲】在线语音生成(GPT-SoVITS)\n
|
| 452 |
+
|
| 453 |
+
### <center>模型作者:Xz乔希 https://space.bilibili.com/5859321\n
|
| 454 |
+
### <center>GPT-SoVITS在线合集:https://www.modelscope.cn/studios/xzjosh/GPT-SoVITS\n
|
| 455 |
+
### <center>数据集下载:https://huggingface.co/datasets/XzJosh/audiodataset\n
|
| 456 |
+
### <center>声音归属:永雏塔菲 https://space.bilibili.com/1265680561\n
|
| 457 |
+
### <center>GPT-SoVITS项目:https://github.com/RVC-Boss/GPT-SoVITS\n
|
| 458 |
+
### <center>使用本模型请严格遵守法律法规!发布二创作品请标注本项目作者及链接、作品使用GPT-SoVITS AI生成!\n
|
| 459 |
+
### <center>⚠️在线端不稳定且生成速度较慢,强烈建议下载模型本地推理!\n
|
| 460 |
+
""")
|
| 461 |
+
# with gr.Tabs():
|
| 462 |
+
# with gr.TabItem(i18n("伴奏人声分离&去混响&去回声")):
|
| 463 |
with gr.Group():
|
| 464 |
+
gr.Markdown(value="*参考音频选择(必选)")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 465 |
with gr.Row():
|
| 466 |
+
audio_select = gr.Dropdown(label="选择参考音频(不建议选较长的)", choices=list(text_to_audio_mappings.keys()))
|
| 467 |
+
ref_audio = gr.Audio(label="参考音频试听")
|
| 468 |
+
ref_text = gr.Textbox(label="参考音频文本")
|
| 469 |
+
|
| 470 |
+
# 定义更新参考文本的函数
|
| 471 |
+
def update_ref_text_and_audio(selected_text):
|
| 472 |
+
audio_path = text_to_audio_mappings.get(selected_text, "")
|
| 473 |
+
return selected_text, audio_path
|
| 474 |
+
|
| 475 |
+
# 绑定下拉菜单的变化到更新函数
|
| 476 |
+
audio_select.change(update_ref_text_and_audio, [audio_select], [ref_text, ref_audio])
|
| 477 |
+
|
| 478 |
+
# 其他 Gradio 组件和功能
|
| 479 |
+
prompt_language = gr.Dropdown(
|
| 480 |
+
label="参考音频语种", choices=["中文", "英文", "日文"], value="中文"
|
| 481 |
+
)
|
| 482 |
+
gr.Markdown(value="*请填写需要合成的目标文本")
|
| 483 |
with gr.Row():
|
| 484 |
+
text = gr.Textbox(label="需要合成的文本", value="")
|
| 485 |
text_language = gr.Dropdown(
|
| 486 |
+
label="需要合成的语种", choices=["中文", "英文", "日文"], value="中文"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 487 |
)
|
| 488 |
+
inference_button = gr.Button("合成语音", variant="primary")
|
| 489 |
+
output = gr.Audio(label="输出的语音")
|
|
|
|
| 490 |
inference_button.click(
|
| 491 |
get_tts_wav,
|
| 492 |
+
[audio_select, ref_text, prompt_language, text, text_language],
|
| 493 |
[output],
|
| 494 |
)
|
| 495 |
|
| 496 |
+
|
| 497 |
+
gr.Markdown(value="文本切分工具。太长的文本合成出来效果不一定好,所以太长建议先切。合成会根据文本的换行分开合成再拼起来。")
|
| 498 |
+
with gr.Row():
|
| 499 |
+
text_inp = gr.Textbox(label="需要合成的切分前文本", value="")
|
| 500 |
+
button1 = gr.Button("凑五句一切", variant="primary")
|
| 501 |
+
button2 = gr.Button("凑50字一切", variant="primary")
|
| 502 |
+
button3 = gr.Button("按中文句号。切", variant="primary")
|
| 503 |
+
text_opt = gr.Textbox(label="切分后文本", value="")
|
| 504 |
+
button1.click(cut1, [text_inp], [text_opt])
|
| 505 |
+
button2.click(cut2, [text_inp], [text_opt])
|
| 506 |
+
button3.click(cut3, [text_inp], [text_opt])
|
| 507 |
+
|
| 508 |
+
app.queue(max_size=10)
|
| 509 |
+
app.launch(inbrowser=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|