Refactor: when pyopenjtalk_worker is called without initialization, continue processing without a worker

When using style-bert-vits2 as a library, the requirement to be able to launch it in multiple processes may not be necessary. Also, if the library is embedded and exe-ed using PyInstaller or similar, it is difficult to make pyopenjtalk_worker run in a separate process.
Therefore, we changed it so that the worker is used only when it is explicitly initialized.
This commit is contained in:
tsukumi
2024-03-10 03:04:27 +00:00
parent a79b1910fb
commit b7d7c78203
4 changed files with 45 additions and 25 deletions

View File

@@ -151,7 +151,7 @@ def save_last_download(latest_release):
# pyopenjtalk_worker を起動
## pyopenjtalk_worker は TCP ソケットサーバーのため、ここで起動する
pyopenjtalk.initialize()
pyopenjtalk.initialize_worker()
# pyopenjtalk の辞書を更新
update_dict()

View File

@@ -43,7 +43,7 @@ ln = config.server_config.language
# pyopenjtalk_worker を起動
## pyopenjtalk_worker は TCP ソケットサーバーのため、ここで起動する
pyopenjtalk.initialize()
pyopenjtalk.initialize_worker()
# 事前に BERT モデル/トークナイザーをロードしておく
## ここでロードしなくても必要になった際に自動ロードされるが、時間がかかるため事前にロードしておいた方が体験が良い

View File

@@ -18,38 +18,58 @@ WORKER_CLIENT: Optional[WorkerClient] = None
def run_frontend(text: str) -> list[dict[str, Any]]:
assert WORKER_CLIENT
if WORKER_CLIENT is not None:
ret = WORKER_CLIENT.dispatch_pyopenjtalk("run_frontend", text)
assert isinstance(ret, list)
return ret
else:
# without worker
import pyopenjtalk
return pyopenjtalk.run_frontend(text)
def make_label(njd_features: Any) -> list[str]:
assert WORKER_CLIENT
if WORKER_CLIENT is not None:
ret = WORKER_CLIENT.dispatch_pyopenjtalk("make_label", njd_features)
assert isinstance(ret, list)
return ret
else:
# without worker
import pyopenjtalk
return pyopenjtalk.make_label(njd_features)
def mecab_dict_index(path: str, out_path: str, dn_mecab: Optional[str] = None):
assert WORKER_CLIENT
def mecab_dict_index(path: str, out_path: str, dn_mecab: Optional[str] = None) -> None:
if WORKER_CLIENT is not None:
WORKER_CLIENT.dispatch_pyopenjtalk("mecab_dict_index", path, out_path, dn_mecab)
else:
# without worker
import pyopenjtalk
pyopenjtalk.mecab_dict_index(path, out_path, dn_mecab)
def update_global_jtalk_with_user_dict(path: str):
assert WORKER_CLIENT
def update_global_jtalk_with_user_dict(path: str) -> None:
if WORKER_CLIENT is not None:
WORKER_CLIENT.dispatch_pyopenjtalk("update_global_jtalk_with_user_dict", path)
else:
# without worker
import pyopenjtalk
pyopenjtalk.update_global_jtalk_with_user_dict(path)
def unset_user_dict():
assert WORKER_CLIENT
def unset_user_dict() -> None:
if WORKER_CLIENT is not None:
WORKER_CLIENT.dispatch_pyopenjtalk("unset_user_dict")
else:
# without worker
import pyopenjtalk
pyopenjtalk.unset_user_dict()
# initialize module when imported
def initialize(port: int = WORKER_PORT) -> None:
def initialize_worker(port: int = WORKER_PORT) -> None:
import atexit
import signal
import socket
@@ -99,11 +119,11 @@ def initialize(port: int = WORKER_PORT) -> None:
logger.debug("pyopenjtalk worker server started")
WORKER_CLIENT = client
atexit.register(terminate)
atexit.register(terminate_worker)
# when the process is killed
def signal_handler(signum: int, frame: Any):
terminate()
terminate_worker()
try:
signal.signal(signal.SIGTERM, signal_handler)
@@ -113,13 +133,13 @@ def initialize(port: int = WORKER_PORT) -> None:
# top-level declaration
def terminate() -> None:
def terminate_worker() -> None:
logger.debug("pyopenjtalk worker server terminated")
global WORKER_CLIENT
if not WORKER_CLIENT:
return
# repare for unexpected errors
# prepare for unexpected errors
try:
if WORKER_CLIENT.status() == 1:
WORKER_CLIENT.quit_server()

View File

@@ -28,7 +28,7 @@ from style_bert_vits2.tts_model import ModelHolder
# pyopenjtalk_worker を起動
## pyopenjtalk_worker は TCP ソケットサーバーのため、ここで起動する
pyopenjtalk.initialize()
pyopenjtalk.initialize_worker()
# 事前に BERT モデル/トークナイザーをロードしておく
## ここでロードしなくても必要になった際に自動ロードされるが、時間がかかるため事前にロードしておいた方が体験が良い