From 34e17bd469b02d9957676f76743cee64245336a3 Mon Sep 17 00:00:00 2001 From: James Pine Date: Sun, 15 Mar 2026 16:02:09 -0700 Subject: [PATCH] Fix LuxTTS + Chatterbox in prod: bundle espeak/perth data, fix multiprocessing - collect-all piper_phonemize to bundle espeak-ng-data for LuxTTS phonemization - Set ESPEAK_DATA_PATH in frozen builds so the C library finds bundled data - collect-all perth to bundle pretrained watermark model for Chatterbox - Add multiprocessing.freeze_support() to fix resource_tracker subprocess crash --- backend/build_binary.py | 6 ++++++ backend/server.py | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/backend/build_binary.py b/backend/build_binary.py index cf587dc2..db413b99 100644 --- a/backend/build_binary.py +++ b/backend/build_binary.py @@ -111,6 +111,12 @@ def build_server(cuda=False): # inflect uses typeguard @typechecked which calls inspect.getsource() # at import time — needs .py source files, not just .pyc bytecode '--collect-all', 'inflect', + # perth ships pretrained watermark model files (hparams.yaml, .pth.tar) + # in perth/perth_net/pretrained/ — needed by chatterbox at runtime + '--collect-all', 'perth', + # piper_phonemize ships espeak-ng-data/ (phoneme tables, language dicts) + # needed by LuxTTS for text-to-phoneme conversion + '--collect-all', 'piper_phonemize', ]) # Add CUDA-specific hidden imports diff --git a/backend/server.py b/backend/server.py index 8dd970b3..bc6a81b2 100644 --- a/backend/server.py +++ b/backend/server.py @@ -26,6 +26,20 @@ if not _is_writable(sys.stdout): if not _is_writable(sys.stderr): sys.stderr = open(os.devnull, 'w') +# PyInstaller + multiprocessing: child processes re-execute the frozen binary +# with internal arguments. freeze_support() handles this and exits early. +import multiprocessing +multiprocessing.freeze_support() + +# In frozen builds, piper_phonemize's espeak-ng C library falls back to +# /usr/share/espeak-ng-data/ which doesn't exist. Point it at the bundled +# data directory instead. +if getattr(sys, 'frozen', False): + _meipass = getattr(sys, '_MEIPASS', os.path.dirname(sys.executable)) + _espeak_data = os.path.join(_meipass, 'piper_phonemize', 'espeak-ng-data') + if os.path.isdir(_espeak_data): + os.environ.setdefault('ESPEAK_DATA_PATH', _espeak_data) + # Fast path: handle --version before any heavy imports so the Rust # version check doesn't block for 30+ seconds loading torch etc. if "--version" in sys.argv: