📘

Style-Bert-VITS2のpyopenjtalk_workerでのTimeoutErrorを解決する

に公開

はじめに

久しぶりにSBV2のモデルマージ機能を利用したく、SBV2のwebアプリを利用しようと思った時にタイトルの状態になったので、解消までの道のりを備忘録としてまとめます。

なお、SBV2に関しては、過去に使い方の記事を書いているので、使い方を知りたい方はそちらをご覧ください。

https://zenn.dev/asap/articles/f8c0621cdd74cc

SBV2自体は下記です。
https://github.com/litagin02/Style-Bert-VITS2

忙しい人のために

つまりこういうことです。

https://x.com/asap2650/status/1948439970286633381

著者の環境

Macbook Pro M4 Max
RAM 24GB

python 3.11.13
(uvで管理しています)

沼った内容

pyopenjtalk_workerでのTimeoutError

環境構築後、下記コマンドでWebアプリを立ち上げた際に、エラーが発生します。

python app.py
07-26 00:44:05 | DEBUG  | __init__.py:92 | try starting pyopenjtalk worker server
Traceback (most recent call last):
  File "/Users/02/Desktop/workspace/coding/BD/try-ai/Style-Bert-VITS2-26/style_bert_vits2/nlp/japanese/pyopenjtalk_worker/__init__.py", line 90, in initialize_worker
    client = WorkerClient(port)
             ^^^^^^^^^^^^^^^^^^
  File "/Users/02/Desktop/workspace/coding/BD/try-ai/Style-Bert-VITS2-26/style_bert_vits2/nlp/japanese/pyopenjtalk_worker/worker_client.py", line 19, in __init__
    sock.connect((socket.gethostname(), port))
socket.gaierror: [Errno 8] nodename nor servname provided, or not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/02/Desktop/workspace/coding/BD/try-ai/Style-Bert-VITS2-26/style_bert_vits2/nlp/japanese/pyopenjtalk_worker/__init__.py", line 121, in initialize_worker
    client = WorkerClient(port)
             ^^^^^^^^^^^^^^^^^^
  File "/Users/02/Desktop/workspace/coding/BD/try-ai/Style-Bert-VITS2-26/style_bert_vits2/nlp/japanese/pyopenjtalk_worker/worker_client.py", line 19, in __init__
    sock.connect((socket.gethostname(), port))
socket.gaierror: [Errno 8] nodename nor servname provided, or not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/02/Desktop/workspace/coding/BD/try-ai/Style-Bert-VITS2-26/app.py", line 9, in <module>
    from gradio_tabs.inference import create_inference_app
  File "/Users/02/Desktop/workspace/coding/BD/try-ai/Style-Bert-VITS2-26/gradio_tabs/inference.py", line 30, in <module>
    pyopenjtalk.initialize_worker()
  File "/Users/02/Desktop/workspace/coding/BD/try-ai/Style-Bert-VITS2-26/style_bert_vits2/nlp/japanese/pyopenjtalk_worker/__init__.py", line 128, in initialize_worker
    raise TimeoutError("サーバーに接続できませんでした")
TimeoutError: サーバーに接続できませんでした

Webアプリの画面が真っ白になる

上記の課題の解決後、下記コマンドでWebアプリを起動するも、ブラウザの画面が真っ白で何も表示されない。

python app.py

対策

pyopenjtalk_workerでのTimeoutError

原因

PCの何かしらの不具合なのか、PCのウイルス対策ソフトの問題なのかわからないが、Macのローカルホスト名であるはずのMacBook-Pro.localが解決できない状態になっていた。

つまり、

$ ping MacBook-Pro.local
ping: cannot resolve MacBook-Pro.local: Unknown host

という状態になってしまっていた。

その場合、style_bert_vits2/nlp/japanese/pyopenjtalk_worker/worker_client.pyにおける、

    def __init__(self, port: int) -> None:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # timeout: 60 seconds
        sock.settimeout(60)
        sock.connect((socket.gethostname(), port))
        self.sock = sock

の、sock.connect((socket.gethostname(), port))にてsocket.gethostname()で設定されたMacBook-Pro.localに接続することができず、永遠にリトライ&タイムアウトが発生していたようです。

解決策

下記二つのファイルを、下記のように修正してください。
とりあえずローカルで動けばいいので、名前解決の余地をなくします。

一つ目
style_bert_vits2/nlp/japanese/pyopenjtalk_worker/worker_client.py

style_bert_vits2/nlp/japanese/pyopenjtalk_worker/worker_client.py
class WorkerClient:
    """pyopenjtalk worker client"""

    def __init__(self, port: int) -> None:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # timeout: 60 seconds
        sock.settimeout(60)
-       sock.connect((socket.gethostname(), port))
+       sock.connect(("localhost", port))
        self.sock = sock

二つ目
style_bert_vits2/nlp/japanese/pyopenjtalk_worker/worker_server.py

style_bert_vits2/nlp/japanese/pyopenjtalk_worker/worker_server.py

    def start_server(self, port: int, no_client_timeout: int = 30) -> None:
        logger.info("start pyopenjtalk worker server")
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
-           server_socket.bind((socket.gethostname(), port))
+           server_socket.bind(("localhost", port))
            server_socket.listen()
            sockets = [server_socket]

上記の修正で私は、Timeoutエラーが解決しました。

Webアプリの画面が真っ白になる

原因

こちらは、以下のXの投稿により原因がわかりました。ありがとうございます。
https://x.com/mF0tRQ7Y7tD4Nvv/status/1943780201785438298

解決策

gradioの5.36.2バージョンが悪さしているようで、5.34.0に修正することで解決するようです。

requirements.txt

cmudict
cn2an
faster-whisper==0.10.1
g2p_en
GPUtil
-gradio>=4.32
+gradio==5.34.0
jieba
librosa==0.9.2
loguru
num2words
numpy<2
protobuf==4.25
psutil
punctuators
pyannote.audio>=3.1.0
pyloudnorm
pyopenjtalk-dict
pypinyin
pyworld-prebuilt
stable_ts
tensorboard
torch
torchaudio
transformers
umap-learn

結果

ちゃんと動くようになりました。

まとめ

個人的な忘備録のため、今回はこのくらいで。
時間かかりましたが、モデルマージが動くようになって良かったです。

Discussion