Refactor: rename Model / ModelHolder to TTSModel / TTSModelHolder for clarification and add comments to each method

This commit is contained in:
tsukumi
2024-03-10 03:47:17 +00:00
parent b7d7c78203
commit d2fd378b56
7 changed files with 133 additions and 56 deletions

4
app.py
View File

@@ -6,7 +6,7 @@ import torch
import yaml import yaml
from style_bert_vits2.constants import GRADIO_THEME, VERSION from style_bert_vits2.constants import GRADIO_THEME, VERSION
from style_bert_vits2.tts_model import ModelHolder from style_bert_vits2.tts_model import TTSModelHolder
from webui import ( from webui import (
create_dataset_app, create_dataset_app,
create_inference_app, create_inference_app,
@@ -34,7 +34,7 @@ device = args.device
if device == "cuda" and not torch.cuda.is_available(): if device == "cuda" and not torch.cuda.is_available():
device = "cpu" device = "cpu"
model_holder = ModelHolder(Path(assets_root), device) model_holder = TTSModelHolder(Path(assets_root), device)
with gr.Blocks(theme=GRADIO_THEME) as app: with gr.Blocks(theme=GRADIO_THEME) as app:
gr.Markdown(f"# Style-Bert-VITS2 WebUI (version {VERSION})") gr.Markdown(f"# Style-Bert-VITS2 WebUI (version {VERSION})")

View File

@@ -52,7 +52,7 @@ from style_bert_vits2.nlp.japanese.user_dict import (
rewrite_word, rewrite_word,
update_dict, update_dict,
) )
from style_bert_vits2.tts_model import ModelHolder from style_bert_vits2.tts_model import TTSModelHolder
# ---フロントエンド部分に関する処理--- # ---フロントエンド部分に関する処理---
@@ -198,7 +198,7 @@ if device == "cuda" and not torch.cuda.is_available():
model_dir = Path(args.model_dir) model_dir = Path(args.model_dir)
port = int(args.port) port = int(args.port)
model_holder = ModelHolder(model_dir, device) model_holder = TTSModelHolder(model_dir, device)
if len(model_holder.model_names) == 0: if len(model_holder.model_names) == 0:
logger.error(f"Models not found in {model_dir}.") logger.error(f"Models not found in {model_dir}.")
sys.exit(1) sys.exit(1)
@@ -283,7 +283,7 @@ def synthesis(request: SynthesisRequest):
detail=f"1行の文字数は{args.line_length}文字以下にしてください。", detail=f"1行の文字数は{args.line_length}文字以下にしてください。",
) )
try: try:
model = model_holder.load_model( model = model_holder.get_model(
model_name=request.model, model_path_str=request.modelFile model_name=request.model, model_path_str=request.modelFile
) )
except Exception as e: except Exception as e:
@@ -310,7 +310,7 @@ def synthesis(request: SynthesisRequest):
language=request.language, language=request.language,
sdp_ratio=request.sdpRatio, sdp_ratio=request.sdpRatio,
noise=request.noise, noise=request.noise,
noisew=request.noisew, noise_w=request.noisew,
length=1 / request.speed, length=1 / request.speed,
given_tone=tone, given_tone=tone,
style=request.style, style=request.style,
@@ -321,7 +321,7 @@ def synthesis(request: SynthesisRequest):
line_split=False, line_split=False,
pitch_scale=request.pitchScale, pitch_scale=request.pitchScale,
intonation_scale=request.intonationScale, intonation_scale=request.intonationScale,
sid=sid, speaker_id=sid,
) )
with BytesIO() as wavContent: with BytesIO() as wavContent:
@@ -350,7 +350,7 @@ def multi_synthesis(request: MultiSynthesisRequest):
detail=f"1行の文字数は{args.line_length}文字以下にしてください。", detail=f"1行の文字数は{args.line_length}文字以下にしてください。",
) )
try: try:
model = model_holder.load_model( model = model_holder.get_model(
model_name=req.model, model_path_str=req.modelFile model_name=req.model, model_path_str=req.modelFile
) )
except Exception as e: except Exception as e:
@@ -370,7 +370,7 @@ def multi_synthesis(request: MultiSynthesisRequest):
language=req.language, language=req.language,
sdp_ratio=req.sdpRatio, sdp_ratio=req.sdpRatio,
noise=req.noise, noise=req.noise,
noisew=req.noisew, noise_w=req.noisew,
length=1 / req.speed, length=1 / req.speed,
given_tone=tone, given_tone=tone,
style=req.style, style=req.style,

View File

@@ -36,7 +36,7 @@ from style_bert_vits2.constants import (
from style_bert_vits2.logging import logger from style_bert_vits2.logging import logger
from style_bert_vits2.nlp import bert_models from style_bert_vits2.nlp import bert_models
from style_bert_vits2.nlp.japanese import pyopenjtalk_worker as pyopenjtalk from style_bert_vits2.nlp.japanese import pyopenjtalk_worker as pyopenjtalk
from style_bert_vits2.tts_model import Model, ModelHolder from style_bert_vits2.tts_model import TTSModel, TTSModelHolder
ln = config.server_config.language ln = config.server_config.language
@@ -67,16 +67,16 @@ class AudioResponse(Response):
media_type = "audio/wav" media_type = "audio/wav"
def load_models(model_holder: ModelHolder): def load_models(model_holder: TTSModelHolder):
model_holder.models = [] model_holder.models = []
for model_name, model_paths in model_holder.model_files_dict.items(): for model_name, model_paths in model_holder.model_files_dict.items():
model = Model( model = TTSModel(
model_path=model_paths[0], model_path=model_paths[0],
config_path=model_holder.root_dir / model_name / "config.json", config_path=model_holder.root_dir / model_name / "config.json",
style_vec_path=model_holder.root_dir / model_name / "style_vectors.npy", style_vec_path=model_holder.root_dir / model_name / "style_vectors.npy",
device=model_holder.device, device=model_holder.device,
) )
model.load_net_g() model.load()
model_holder.models.append(model) model_holder.models.append(model)
@@ -94,7 +94,7 @@ if __name__ == "__main__":
device = "cuda" if torch.cuda.is_available() else "cpu" device = "cuda" if torch.cuda.is_available() else "cpu"
model_dir = Path(args.dir) model_dir = Path(args.dir)
model_holder = ModelHolder(model_dir, device) model_holder = TTSModelHolder(model_dir, device)
if len(model_holder.model_names) == 0: if len(model_holder.model_names) == 0:
logger.error(f"Models not found in {model_dir}.") logger.error(f"Models not found in {model_dir}.")
sys.exit(1) sys.exit(1)
@@ -194,11 +194,11 @@ if __name__ == "__main__":
sr, audio = model.infer( sr, audio = model.infer(
text=text, text=text,
language=language, language=language,
sid=speaker_id, speaker_id=speaker_id,
reference_audio_path=reference_audio_path, reference_audio_path=reference_audio_path,
sdp_ratio=sdp_ratio, sdp_ratio=sdp_ratio,
noise=noise, noise=noise,
noisew=noisew, noise_w=noisew,
length=length, length=length,
line_split=auto_split, line_split=auto_split,
split_interval=split_interval, split_interval=split_interval,

View File

@@ -12,7 +12,7 @@ from tqdm import tqdm
from config import config from config import config
from style_bert_vits2.logging import logger from style_bert_vits2.logging import logger
from style_bert_vits2.tts_model import Model from style_bert_vits2.tts_model import TTSModel
warnings.filterwarnings("ignore") warnings.filterwarnings("ignore")
@@ -54,7 +54,7 @@ safetensors_files = model_path.glob("*.safetensors")
def get_model(model_file: Path): def get_model(model_file: Path):
return Model( return TTSModel(
model_path=str(model_file), model_path=str(model_file),
config_path=str(model_file.parent / "config.json"), config_path=str(model_file.parent / "config.json"),
style_vec_path=str(model_file.parent / "style_vectors.npy"), style_vec_path=str(model_file.parent / "style_vectors.npy"),

View File

@@ -29,9 +29,9 @@ from style_bert_vits2.logging import logger
from style_bert_vits2.voice import adjust_voice from style_bert_vits2.voice import adjust_voice
class Model: class TTSModel:
""" """
Style-Bert-Vits2 の音声合成モデルを操作するためのクラス。 Style-Bert-Vits2 の音声合成モデルを操作するクラス。
モデル/ハイパーパラメータ/スタイルベクトルのパスとデバイスを指定して初期化し、model.infer() メソッドを呼び出すと音声合成を行える。 モデル/ハイパーパラメータ/スタイルベクトルのパスとデバイスを指定して初期化し、model.infer() メソッドを呼び出すと音声合成を行える。
""" """
@@ -43,6 +43,17 @@ class Model:
style_vec_path: Path, style_vec_path: Path,
device: str, device: str,
) -> None: ) -> None:
"""
Style-Bert-Vits2 の音声合成モデルを初期化する。
この時点ではモデルはロードされていない (明示的にロードしたい場合は model.load() を呼び出す)。
Args:
model_path (Path): モデル (.safetensors) のパス
config_path (Path): ハイパーパラメータ (config.json) のパス
style_vec_path (Path): スタイルベクトル (style_vectors.npy) のパス
device (str): 音声合成時に利用するデバイス (cpu, cuda, mps など)
"""
self.model_path: Path = model_path self.model_path: Path = model_path
self.config_path: Path = config_path self.config_path: Path = config_path
self.style_vec_path: Path = style_vec_path self.style_vec_path: Path = style_vec_path
@@ -71,24 +82,24 @@ class Model:
self.__net_g: Union[SynthesizerTrn, SynthesizerTrnJPExtra, None] = None self.__net_g: Union[SynthesizerTrn, SynthesizerTrnJPExtra, None] = None
def load_net_g(self) -> None: def load(self) -> None:
""" """
net_g をロードする。 音声合成モデルをデバイスにロードする。
""" """
self.__net_g = get_net_g( self.__net_g = get_net_g(
model_path=str(self.model_path), model_path = str(self.model_path),
version=self.hyper_parameters.version, version = self.hyper_parameters.version,
device=self.device, device = self.device,
hps=self.hyper_parameters, hps = self.hyper_parameters,
) )
def get_style_vector(self, style_id: int, weight: float = 1.0) -> NDArray[Any]: def __get_style_vector(self, style_id: int, weight: float = 1.0) -> NDArray[Any]:
""" """
スタイルベクトルを取得する。 スタイルベクトルを取得する。
Args: Args:
style_id (int): スタイル ID style_id (int): スタイル ID (0 から始まるインデックス)
weight (float, optional): スタイルベクトルの重み. Defaults to 1.0. weight (float, optional): スタイルベクトルの重み. Defaults to 1.0.
Returns: Returns:
@@ -100,7 +111,7 @@ class Model:
return style_vec return style_vec
def get_style_vector_from_audio(self, audio_path: str, weight: float = 1.0) -> NDArray[Any]: def __get_style_vector_from_audio(self, audio_path: str, weight: float = 1.0) -> NDArray[Any]:
""" """
音声からスタイルベクトルを推論する。 音声からスタイルベクトルを推論する。
@@ -130,11 +141,11 @@ class Model:
self, self,
text: str, text: str,
language: Languages = Languages.JP, language: Languages = Languages.JP,
sid: int = 0, speaker_id: int = 0,
reference_audio_path: Optional[str] = None, reference_audio_path: Optional[str] = None,
sdp_ratio: float = DEFAULT_SDP_RATIO, sdp_ratio: float = DEFAULT_SDP_RATIO,
noise: float = DEFAULT_NOISE, noise: float = DEFAULT_NOISE,
noisew: float = DEFAULT_NOISEW, noise_w: float = DEFAULT_NOISEW,
length: float = DEFAULT_LENGTH, length: float = DEFAULT_LENGTH,
line_split: bool = DEFAULT_LINE_SPLIT, line_split: bool = DEFAULT_LINE_SPLIT,
split_interval: float = DEFAULT_SPLIT_INTERVAL, split_interval: float = DEFAULT_SPLIT_INTERVAL,
@@ -147,6 +158,33 @@ class Model:
pitch_scale: float = 1.0, pitch_scale: float = 1.0,
intonation_scale: float = 1.0, intonation_scale: float = 1.0,
) -> tuple[int, NDArray[Any]]: ) -> tuple[int, NDArray[Any]]:
"""
テキストから音声を合成する。
Args:
text (str): 読み上げるテキスト
language (Languages, optional): 言語. Defaults to Languages.JP.
speaker_id (int, optional): 話者 ID. Defaults to 0.
reference_audio_path (Optional[str], optional): 音声スタイルの参照元の音声ファイルのパス. Defaults to None.
sdp_ratio (float, optional): SDP レシオ (値を大きくするとより感情豊かになる傾向がある). Defaults to DEFAULT_SDP_RATIO.
noise (float, optional): ノイズの大きさ. Defaults to DEFAULT_NOISE.
noise_w (float, optional): ノイズの大きさの重み. Defaults to DEFAULT_NOISEW.
length (float, optional): 長さ. Defaults to DEFAULT_LENGTH.
line_split (bool, optional): テキストを改行ごとに分割して生成するかどうか. Defaults to DEFAULT_LINE_SPLIT.
split_interval (float, optional): 改行ごとに分割する場合の無音 (秒). Defaults to DEFAULT_SPLIT_INTERVAL.
assist_text (Optional[str], optional): 感情表現の参照元の補助テキスト. Defaults to None.
assist_text_weight (float, optional): 感情表現の補助テキストを適用する強さ. Defaults to DEFAULT_ASSIST_TEXT_WEIGHT.
use_assist_text (bool, optional): 音声合成時に感情表現の補助テキストを使用するかどうか. Defaults to False.
style (str, optional): 音声スタイル (Neutral, Happy など). Defaults to DEFAULT_STYLE.
style_weight (float, optional): 音声スタイルを適用する強さ. Defaults to DEFAULT_STYLE_WEIGHT.
given_tone (Optional[list[int]], optional): アクセントのトーンのリスト. Defaults to None.
pitch_scale (float, optional): ピッチの高さ (1.0 から変更すると若干音質が低下する). Defaults to 1.0.
intonation_scale (float, optional): イントネーションの高さ (1.0 から変更すると若干音質が低下する). Defaults to 1.0.
Returns:
tuple[int, NDArray[Any]]: サンプリングレートと音声データ (16bit PCM)
"""
logger.info(f"Start generating audio data from text:\n{text}") logger.info(f"Start generating audio data from text:\n{text}")
if language != "JP" and self.hyper_parameters.version.endswith("JP-Extra"): if language != "JP" and self.hyper_parameters.version.endswith("JP-Extra"):
raise ValueError( raise ValueError(
@@ -158,13 +196,13 @@ class Model:
assist_text = None assist_text = None
if self.__net_g is None: if self.__net_g is None:
self.load_net_g() self.load()
assert self.__net_g is not None assert self.__net_g is not None
if reference_audio_path is None: if reference_audio_path is None:
style_id = self.style2id[style] style_id = self.style2id[style]
style_vector = self.get_style_vector(style_id, style_weight) style_vector = self.__get_style_vector(style_id, style_weight)
else: else:
style_vector = self.get_style_vector_from_audio( style_vector = self.__get_style_vector_from_audio(
reference_audio_path, style_weight reference_audio_path, style_weight
) )
if not line_split: if not line_split:
@@ -173,9 +211,9 @@ class Model:
text = text, text = text,
sdp_ratio = sdp_ratio, sdp_ratio = sdp_ratio,
noise_scale = noise, noise_scale = noise,
noise_scale_w = noisew, noise_scale_w = noise_w,
length_scale = length, length_scale = length,
sid = sid, sid = speaker_id,
language = language, language = language,
hps = self.hyper_parameters, hps = self.hyper_parameters,
net_g = self.__net_g, net_g = self.__net_g,
@@ -196,9 +234,9 @@ class Model:
text = t, text = t,
sdp_ratio = sdp_ratio, sdp_ratio = sdp_ratio,
noise_scale = noise, noise_scale = noise,
noise_scale_w = noisew, noise_scale_w = noise_w,
length_scale = length, length_scale = length,
sid = sid, sid = speaker_id,
language = language, language = language,
hps = self.hyper_parameters, hps = self.hyper_parameters,
net_g = self.__net_g, net_g = self.__net_g,
@@ -225,24 +263,50 @@ class Model:
return (self.hyper_parameters.data.sampling_rate, audio) return (self.hyper_parameters.data.sampling_rate, audio)
class ModelHolder: class TTSModelHolder:
""" """
Style-Bert-Vits2 の音声合成モデルを管理するためのクラス。 Style-Bert-Vits2 の音声合成モデルを管理するクラス。
model_holder.models_info から指定されたディレクトリ内にある音声合成モデルの一覧を取得できる。
""" """
def __init__(self, model_root_dir: Path, device: str) -> None: def __init__(self, model_root_dir: Path, device: str) -> None:
"""
Style-Bert-Vits2 の音声合成モデルを管理するクラスを初期化する。
音声合成モデルは下記のように配置されていることを前提とする (.safetensors のファイル名は自由) 。
```
model_root_dir
├── model-name-1
│ ├── config.json
│ ├── model-name-1_e160_s14000.safetensors
│ └── style_vectors.npy
├── model-name-2
│ ├── config.json
│ ├── model-name-2_e160_s14000.safetensors
│ └── style_vectors.npy
└── ...
```
Args:
model_root_dir (Path): 音声合成モデルが配置されているディレクトリのパス
device (str): 音声合成時に利用するデバイス (cpu, cuda, mps など)
"""
self.root_dir: Path = model_root_dir self.root_dir: Path = model_root_dir
self.device: str = device self.device: str = device
self.model_files_dict: dict[str, list[Path]] = {} self.model_files_dict: dict[str, list[Path]] = {}
self.current_model: Optional[Model] = None self.current_model: Optional[TTSModel] = None
self.model_names: list[str] = [] self.model_names: list[str] = []
self.models: list[Model] = [] self.models: list[TTSModel] = []
self.models_info: list[dict[str, Union[str, list[str]]]] = [] self.models_info: list[dict[str, Union[str, list[str]]]] = []
self.refresh() self.refresh()
def refresh(self) -> None: def refresh(self) -> None:
"""
音声合成モデルの一覧を更新する。
"""
self.model_files_dict = {} self.model_files_dict = {}
self.model_names = [] self.model_names = []
self.current_model = None self.current_model = None
@@ -279,23 +343,36 @@ class ModelHolder:
}) })
def load_model(self, model_name: str, model_path_str: str) -> Model: def get_model(self, model_name: str, model_path_str: str) -> TTSModel:
"""
指定された音声合成モデルのインスタンスを取得する。
この時点ではモデルはロードされていない (明示的にロードしたい場合は model.load() を呼び出す)。
Args:
model_name (str): 音声合成モデルの名前
model_path_str (str): 音声合成モデルのファイルパス (.safetensors)
Returns:
TTSModel: 音声合成モデルのインスタンス
"""
model_path = Path(model_path_str) model_path = Path(model_path_str)
if model_name not in self.model_files_dict: if model_name not in self.model_files_dict:
raise ValueError(f"Model `{model_name}` is not found") raise ValueError(f"Model `{model_name}` is not found")
if model_path not in self.model_files_dict[model_name]: if model_path not in self.model_files_dict[model_name]:
raise ValueError(f"Model file `{model_path}` is not found") raise ValueError(f"Model file `{model_path}` is not found")
if self.current_model is None or self.current_model.model_path != model_path: if self.current_model is None or self.current_model.model_path != model_path:
self.current_model = Model( self.current_model = TTSModel(
model_path = model_path, model_path = model_path,
config_path = self.root_dir / model_name / "config.json", config_path = self.root_dir / model_name / "config.json",
style_vec_path = self.root_dir / model_name / "style_vectors.npy", style_vec_path = self.root_dir / model_name / "style_vectors.npy",
device = self.device, device = self.device,
) )
return self.current_model return self.current_model
def load_model_for_gradio(self, model_name: str, model_path_str: str) -> tuple[gr.Dropdown, gr.Button, gr.Dropdown]: def get_model_for_gradio(self, model_name: str, model_path_str: str) -> tuple[gr.Dropdown, gr.Button, gr.Dropdown]:
model_path = Path(model_path_str) model_path = Path(model_path_str)
if model_name not in self.model_files_dict: if model_name not in self.model_files_dict:
raise ValueError(f"Model `{model_name}` is not found") raise ValueError(f"Model `{model_name}` is not found")
@@ -313,7 +390,7 @@ class ModelHolder:
gr.Button(interactive=True, value="音声合成"), gr.Button(interactive=True, value="音声合成"),
gr.Dropdown(choices=speakers, value=speakers[0]), # type: ignore gr.Dropdown(choices=speakers, value=speakers[0]), # type: ignore
) )
self.current_model = Model( self.current_model = TTSModel(
model_path = model_path, model_path = model_path,
config_path = self.root_dir / model_name / "config.json", config_path = self.root_dir / model_name / "config.json",
style_vec_path = self.root_dir / model_name / "style_vectors.npy", style_vec_path = self.root_dir / model_name / "style_vectors.npy",

View File

@@ -23,7 +23,7 @@ from style_bert_vits2.nlp import bert_models
from style_bert_vits2.nlp.japanese import pyopenjtalk_worker as pyopenjtalk from style_bert_vits2.nlp.japanese import pyopenjtalk_worker as pyopenjtalk
from style_bert_vits2.nlp.japanese.g2p_utils import g2kata_tone, kata_tone2phone_tone from style_bert_vits2.nlp.japanese.g2p_utils import g2kata_tone, kata_tone2phone_tone
from style_bert_vits2.nlp.japanese.normalizer import normalize_text from style_bert_vits2.nlp.japanese.normalizer import normalize_text
from style_bert_vits2.tts_model import ModelHolder from style_bert_vits2.tts_model import TTSModelHolder
# pyopenjtalk_worker を起動 # pyopenjtalk_worker を起動
@@ -151,7 +151,7 @@ def gr_util(item):
return (gr.update(visible=False), gr.update(visible=True)) return (gr.update(visible=False), gr.update(visible=True))
def create_inference_app(model_holder: ModelHolder) -> gr.Blocks: def create_inference_app(model_holder: TTSModelHolder) -> gr.Blocks:
def tts_fn( def tts_fn(
model_name, model_name,
model_path, model_path,
@@ -175,7 +175,7 @@ def create_inference_app(model_holder: ModelHolder) -> gr.Blocks:
pitch_scale, pitch_scale,
intonation_scale, intonation_scale,
): ):
model_holder.load_model(model_name, model_path) model_holder.get_model(model_name, model_path)
assert model_holder.current_model is not None assert model_holder.current_model is not None
wrong_tone_message = "" wrong_tone_message = ""
@@ -218,7 +218,7 @@ def create_inference_app(model_holder: ModelHolder) -> gr.Blocks:
reference_audio_path=reference_audio_path, reference_audio_path=reference_audio_path,
sdp_ratio=sdp_ratio, sdp_ratio=sdp_ratio,
noise=noise_scale, noise=noise_scale,
noisew=noise_scale_w, noise_w=noise_scale_w,
length=length_scale, length=length_scale,
line_split=line_split, line_split=line_split,
split_interval=split_interval, split_interval=split_interval,
@@ -228,7 +228,7 @@ def create_inference_app(model_holder: ModelHolder) -> gr.Blocks:
style=style, style=style,
style_weight=style_weight, style_weight=style_weight,
given_tone=tone, given_tone=tone,
sid=speaker_id, speaker_id=speaker_id,
pitch_scale=pitch_scale, pitch_scale=pitch_scale,
intonation_scale=intonation_scale, intonation_scale=intonation_scale,
) )
@@ -459,7 +459,7 @@ def create_inference_app(model_holder: ModelHolder) -> gr.Blocks:
) )
load_button.click( load_button.click(
model_holder.load_model_for_gradio, model_holder.get_model_for_gradio,
inputs=[model_name, model_path], inputs=[model_name, model_path],
outputs=[style, tts_button, speaker], outputs=[style, tts_button, speaker],
) )

View File

@@ -11,7 +11,7 @@ from safetensors.torch import save_file
from style_bert_vits2.constants import DEFAULT_STYLE, GRADIO_THEME from style_bert_vits2.constants import DEFAULT_STYLE, GRADIO_THEME
from style_bert_vits2.logging import logger from style_bert_vits2.logging import logger
from style_bert_vits2.tts_model import Model, ModelHolder from style_bert_vits2.tts_model import TTSModel, TTSModelHolder
voice_keys = ["dec"] voice_keys = ["dec"]
@@ -250,11 +250,11 @@ def simple_tts(model_name, text, style=DEFAULT_STYLE, style_weight=1.0):
config_path = os.path.join(assets_root, model_name, "config.json") config_path = os.path.join(assets_root, model_name, "config.json")
style_vec_path = os.path.join(assets_root, model_name, "style_vectors.npy") style_vec_path = os.path.join(assets_root, model_name, "style_vectors.npy")
model = Model(Path(model_path), Path(config_path), Path(style_vec_path), device) model = TTSModel(Path(model_path), Path(config_path), Path(style_vec_path), device)
return model.infer(text, style=style, style_weight=style_weight) return model.infer(text, style=style, style_weight=style_weight)
def update_two_model_names_dropdown(model_holder: ModelHolder): def update_two_model_names_dropdown(model_holder: TTSModelHolder):
new_names, new_files, _ = model_holder.update_model_names_for_gradio() new_names, new_files, _ = model_holder.update_model_names_for_gradio()
return new_names, new_files, new_names, new_files return new_names, new_files, new_names, new_files
@@ -328,7 +328,7 @@ Happy, Surprise, HappySurprise
""" """
def create_merge_app(model_holder: ModelHolder) -> gr.Blocks: def create_merge_app(model_holder: TTSModelHolder) -> gr.Blocks:
model_names = model_holder.model_names model_names = model_holder.model_names
if len(model_names) == 0: if len(model_names) == 0:
logger.error( logger.error(