Unify webui to single webui
This commit is contained in:
@@ -1,14 +1,9 @@
|
||||
import argparse
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import gradio as gr
|
||||
import torch
|
||||
import yaml
|
||||
|
||||
from common.constants import (
|
||||
DEFAULT_ASSIST_TEXT_WEIGHT,
|
||||
@@ -21,7 +16,6 @@ from common.constants import (
|
||||
DEFAULT_STYLE,
|
||||
DEFAULT_STYLE_WEIGHT,
|
||||
GRADIO_THEME,
|
||||
LATEST_VERSION,
|
||||
Languages,
|
||||
)
|
||||
from common.log import logger
|
||||
@@ -29,119 +23,9 @@ from common.tts_model import ModelHolder
|
||||
from infer import InvalidToneError
|
||||
from text.japanese import g2kata_tone, kata_tone2phone_tone, text_normalize
|
||||
|
||||
# Get path settings
|
||||
with open(os.path.join("configs", "paths.yml"), "r", encoding="utf-8") as f:
|
||||
path_config: dict[str, str] = yaml.safe_load(f.read())
|
||||
# dataset_root = path_config["dataset_root"]
|
||||
assets_root = path_config["assets_root"]
|
||||
|
||||
languages = [l.value for l in Languages]
|
||||
|
||||
|
||||
def tts_fn(
|
||||
model_name,
|
||||
model_path,
|
||||
text,
|
||||
language,
|
||||
reference_audio_path,
|
||||
sdp_ratio,
|
||||
noise_scale,
|
||||
noise_scale_w,
|
||||
length_scale,
|
||||
line_split,
|
||||
split_interval,
|
||||
assist_text,
|
||||
assist_text_weight,
|
||||
use_assist_text,
|
||||
style,
|
||||
style_weight,
|
||||
kata_tone_json_str,
|
||||
use_tone,
|
||||
speaker,
|
||||
pitch_scale,
|
||||
intonation_scale,
|
||||
):
|
||||
model_holder.load_model_gr(model_name, model_path)
|
||||
|
||||
wrong_tone_message = ""
|
||||
kata_tone: Optional[list[tuple[str, int]]] = None
|
||||
if use_tone and kata_tone_json_str != "":
|
||||
if language != "JP":
|
||||
logger.warning("Only Japanese is supported for tone generation.")
|
||||
wrong_tone_message = "アクセント指定は現在日本語のみ対応しています。"
|
||||
if line_split:
|
||||
logger.warning("Tone generation is not supported for line split.")
|
||||
wrong_tone_message = (
|
||||
"アクセント指定は改行で分けて生成を使わない場合のみ対応しています。"
|
||||
)
|
||||
try:
|
||||
kata_tone = []
|
||||
json_data = json.loads(kata_tone_json_str)
|
||||
# tupleを使うように変換
|
||||
for kana, tone in json_data:
|
||||
assert isinstance(kana, str) and tone in (0, 1), f"{kana}, {tone}"
|
||||
kata_tone.append((kana, tone))
|
||||
except Exception as e:
|
||||
logger.warning(f"Error occurred when parsing kana_tone_json: {e}")
|
||||
wrong_tone_message = f"アクセント指定が不正です: {e}"
|
||||
kata_tone = None
|
||||
|
||||
# toneは実際に音声合成に代入される際のみnot Noneになる
|
||||
tone: Optional[list[int]] = None
|
||||
if kata_tone is not None:
|
||||
phone_tone = kata_tone2phone_tone(kata_tone)
|
||||
tone = [t for _, t in phone_tone]
|
||||
|
||||
speaker_id = model_holder.current_model.spk2id[speaker]
|
||||
|
||||
start_time = datetime.datetime.now()
|
||||
|
||||
assert model_holder.current_model is not None
|
||||
|
||||
try:
|
||||
sr, audio = model_holder.current_model.infer(
|
||||
text=text,
|
||||
language=language,
|
||||
reference_audio_path=reference_audio_path,
|
||||
sdp_ratio=sdp_ratio,
|
||||
noise=noise_scale,
|
||||
noisew=noise_scale_w,
|
||||
length=length_scale,
|
||||
line_split=line_split,
|
||||
split_interval=split_interval,
|
||||
assist_text=assist_text,
|
||||
assist_text_weight=assist_text_weight,
|
||||
use_assist_text=use_assist_text,
|
||||
style=style,
|
||||
style_weight=style_weight,
|
||||
given_tone=tone,
|
||||
sid=speaker_id,
|
||||
pitch_scale=pitch_scale,
|
||||
intonation_scale=intonation_scale,
|
||||
)
|
||||
except InvalidToneError as e:
|
||||
logger.error(f"Tone error: {e}")
|
||||
return f"Error: アクセント指定が不正です:\n{e}", None, kata_tone_json_str
|
||||
except ValueError as e:
|
||||
logger.error(f"Value error: {e}")
|
||||
return f"Error: {e}", None, kata_tone_json_str
|
||||
|
||||
end_time = datetime.datetime.now()
|
||||
duration = (end_time - start_time).total_seconds()
|
||||
|
||||
if tone is None and language == "JP":
|
||||
# アクセント指定に使えるようにアクセント情報を返す
|
||||
norm_text = text_normalize(text)
|
||||
kata_tone = g2kata_tone(norm_text)
|
||||
kata_tone_json_str = json.dumps(kata_tone, ensure_ascii=False)
|
||||
elif tone is None:
|
||||
kata_tone_json_str = ""
|
||||
message = f"Success, time: {duration} seconds."
|
||||
if wrong_tone_message != "":
|
||||
message = wrong_tone_message + "\n" + message
|
||||
return message, (sr, audio), kata_tone_json_str
|
||||
|
||||
|
||||
initial_text = "こんにちは、初めまして。あなたの名前はなんていうの?"
|
||||
|
||||
examples = [
|
||||
@@ -202,9 +86,7 @@ examples = [
|
||||
]
|
||||
|
||||
initial_md = f"""
|
||||
# Style-Bert-VITS2 ver {LATEST_VERSION} 音声合成
|
||||
|
||||
- Ver 2.3で追加されたエディターのほうが実際に読み上げさせるには使いやすいかもしれません。`Editor.bat`か`python server_editor.py`で起動できます。
|
||||
- Ver 2.3で追加されたエディターのほうが実際に読み上げさせるには使いやすいかもしれません。`Editor.bat`か`python server_editor.py --inbrowser`で起動できます。
|
||||
|
||||
- 初期からある[jvnvのモデル](https://huggingface.co/litagin/style_bert_vits2_jvnv)は、[JVNVコーパス(言語音声と非言語音声を持つ日本語感情音声コーパス)](https://sites.google.com/site/shinnosuketakamichi/research-topics/jvnv_corpus)で学習されたモデルです。ライセンスは[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.ja)です。
|
||||
"""
|
||||
@@ -254,43 +136,119 @@ def gr_util(item):
|
||||
return (gr.update(visible=False), gr.update(visible=True))
|
||||
|
||||
|
||||
def create_inference_app():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--cpu", action="store_true", help="Use CPU instead of GPU")
|
||||
parser.add_argument(
|
||||
"--dir", "-d", type=str, help="Model directory", default=assets_root
|
||||
)
|
||||
parser.add_argument(
|
||||
"--share", action="store_true", help="Share this app publicly", default=False
|
||||
)
|
||||
parser.add_argument(
|
||||
"--server-name",
|
||||
type=str,
|
||||
default=None,
|
||||
help="Server name for Gradio app",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-autolaunch",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Do not launch app automatically",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
model_dir = Path(args.dir)
|
||||
def create_inference_app(model_holder: ModelHolder) -> gr.Blocks:
|
||||
def tts_fn(
|
||||
model_name,
|
||||
model_path,
|
||||
text,
|
||||
language,
|
||||
reference_audio_path,
|
||||
sdp_ratio,
|
||||
noise_scale,
|
||||
noise_scale_w,
|
||||
length_scale,
|
||||
line_split,
|
||||
split_interval,
|
||||
assist_text,
|
||||
assist_text_weight,
|
||||
use_assist_text,
|
||||
style,
|
||||
style_weight,
|
||||
kata_tone_json_str,
|
||||
use_tone,
|
||||
speaker,
|
||||
pitch_scale,
|
||||
intonation_scale,
|
||||
):
|
||||
model_holder.load_model(model_name, model_path)
|
||||
assert model_holder.current_model is not None
|
||||
|
||||
if args.cpu:
|
||||
device = "cpu"
|
||||
else:
|
||||
device = "cuda" if torch.cuda.is_available() else "cpu"
|
||||
wrong_tone_message = ""
|
||||
kata_tone: Optional[list[tuple[str, int]]] = None
|
||||
if use_tone and kata_tone_json_str != "":
|
||||
if language != "JP":
|
||||
logger.warning("Only Japanese is supported for tone generation.")
|
||||
wrong_tone_message = "アクセント指定は現在日本語のみ対応しています。"
|
||||
if line_split:
|
||||
logger.warning("Tone generation is not supported for line split.")
|
||||
wrong_tone_message = (
|
||||
"アクセント指定は改行で分けて生成を使わない場合のみ対応しています。"
|
||||
)
|
||||
try:
|
||||
kata_tone = []
|
||||
json_data = json.loads(kata_tone_json_str)
|
||||
# tupleを使うように変換
|
||||
for kana, tone in json_data:
|
||||
assert isinstance(kana, str) and tone in (0, 1), f"{kana}, {tone}"
|
||||
kata_tone.append((kana, tone))
|
||||
except Exception as e:
|
||||
logger.warning(f"Error occurred when parsing kana_tone_json: {e}")
|
||||
wrong_tone_message = f"アクセント指定が不正です: {e}"
|
||||
kata_tone = None
|
||||
|
||||
model_holder = ModelHolder(model_dir, device)
|
||||
# toneは実際に音声合成に代入される際のみnot Noneになる
|
||||
tone: Optional[list[int]] = None
|
||||
if kata_tone is not None:
|
||||
phone_tone = kata_tone2phone_tone(kata_tone)
|
||||
tone = [t for _, t in phone_tone]
|
||||
|
||||
speaker_id = model_holder.current_model.spk2id[speaker]
|
||||
|
||||
start_time = datetime.datetime.now()
|
||||
|
||||
try:
|
||||
sr, audio = model_holder.current_model.infer(
|
||||
text=text,
|
||||
language=language,
|
||||
reference_audio_path=reference_audio_path,
|
||||
sdp_ratio=sdp_ratio,
|
||||
noise=noise_scale,
|
||||
noisew=noise_scale_w,
|
||||
length=length_scale,
|
||||
line_split=line_split,
|
||||
split_interval=split_interval,
|
||||
assist_text=assist_text,
|
||||
assist_text_weight=assist_text_weight,
|
||||
use_assist_text=use_assist_text,
|
||||
style=style,
|
||||
style_weight=style_weight,
|
||||
given_tone=tone,
|
||||
sid=speaker_id,
|
||||
pitch_scale=pitch_scale,
|
||||
intonation_scale=intonation_scale,
|
||||
)
|
||||
except InvalidToneError as e:
|
||||
logger.error(f"Tone error: {e}")
|
||||
return f"Error: アクセント指定が不正です:\n{e}", None, kata_tone_json_str
|
||||
except ValueError as e:
|
||||
logger.error(f"Value error: {e}")
|
||||
return f"Error: {e}", None, kata_tone_json_str
|
||||
|
||||
end_time = datetime.datetime.now()
|
||||
duration = (end_time - start_time).total_seconds()
|
||||
|
||||
if tone is None and language == "JP":
|
||||
# アクセント指定に使えるようにアクセント情報を返す
|
||||
norm_text = text_normalize(text)
|
||||
kata_tone = g2kata_tone(norm_text)
|
||||
kata_tone_json_str = json.dumps(kata_tone, ensure_ascii=False)
|
||||
elif tone is None:
|
||||
kata_tone_json_str = ""
|
||||
message = f"Success, time: {duration} seconds."
|
||||
if wrong_tone_message != "":
|
||||
message = wrong_tone_message + "\n" + message
|
||||
return message, (sr, audio), kata_tone_json_str
|
||||
|
||||
model_names = model_holder.model_names
|
||||
if len(model_names) == 0:
|
||||
logger.error(
|
||||
f"モデルが見つかりませんでした。{model_dir}にモデルを置いてください。"
|
||||
f"モデルが見つかりませんでした。{model_holder.root_dir}にモデルを置いてください。"
|
||||
)
|
||||
sys.exit(1)
|
||||
with gr.Blocks() as app:
|
||||
gr.Markdown(
|
||||
f"Error: モデルが見つかりませんでした。{model_holder.root_dir}にモデルを置いてください。"
|
||||
)
|
||||
return app
|
||||
initial_id = 0
|
||||
initial_pth_files = model_holder.model_files_dict[model_names[initial_id]]
|
||||
|
||||
@@ -497,8 +455,4 @@ def create_inference_app():
|
||||
outputs=[style, ref_audio_path],
|
||||
)
|
||||
|
||||
# app.launch(
|
||||
# inbrowser=not args.no_autolaunch, share=args.share, server_name=args.server_name
|
||||
# )
|
||||
|
||||
return app
|
||||
|
||||
Reference in New Issue
Block a user