aboutsummaryrefslogtreecommitdiff
path: root/app/backends/faster.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-27 00:04:16 -0400
committerhistoria <historiavg@proton.me>2026-08-27 00:04:16 -0400
commit5b98993b13dafe9a85495e4c68ad9b42863ef2bf (patch)
tree57db1566deb5351ec6bfb8c70de4126bbc5fc2da /app/backends/faster.py
parentf18f421d9180ae0e3bff9496b1fdaf53d3624a75 (diff)
downloadtts-audiobook-generator-5b98993b13dafe9a85495e4c68ad9b42863ef2bf.tar.gz
feat: separate venvs for qwen-tts and faster, manage (un)installs
Diffstat (limited to 'app/backends/faster.py')
-rwxr-xr-xapp/backends/faster.py36
1 files changed, 23 insertions, 13 deletions
diff --git a/app/backends/faster.py b/app/backends/faster.py
index 6cfa53e..3631153 100755
--- a/app/backends/faster.py
+++ b/app/backends/faster.py
@@ -5,9 +5,11 @@ faster-qwen3-tts is an OpenAI-compatible Qwen3-TTS server with CUDA-graph
inference (NVIDIA GPU required). It always uses voice cloning, with the
reference voice configured on the server through a ``voices.json``. This
module sets the whole backend up end-to-end as a TUI: pip-install the
-package, clone the repo (for ``examples/openai_server.py``), build a
-``voices.json`` from a directory of .wav references (transcribed with
-Whisper), sync ``app/converter/config.py``, and print the launch command. It is
+package into its own managed venv (``app/envs/faster`` — separate from the
+app venv and from qwen-tts's: both stacks ship a ``qwen_tts`` module whose
+transformers requirements conflict), clone the repo (for
+``examples/openai_server.py``), build a ``voices.json`` from a directory of
+.wav references (transcribed with Whisper), sync ``app/converter/config.py``, and print the launch command. It is
driven by ``audiobook.py``'s hub but can also be run directly with flags.
Usage:
@@ -57,6 +59,10 @@ from ui import taskview, tui
FASTER_DIR_NAME = "faster-qwen3-tts"
FASTER_GIT_URL = "https://github.com/andimarafioti/faster-qwen3-tts"
FASTER_PIP_PKG = "faster-qwen3-tts[demo]"
+# The dedicated venv faster-qwen3-tts is installed into (never the app env
+# or the qwen backend's; the wheel pulls its own qwen-tts-hf dependency,
+# which ships the same qwen_tts module upstream qwen-tts does).
+FASTER_ENV = envs.FASTER_ENV_DIR
WHISPER_MODELS = ("tiny", "base", "small", "medium", "large-v3")
@@ -65,7 +71,7 @@ def _checkout() -> Path:
def _is_installed() -> bool:
- return envs.module_available("faster_qwen3_tts")
+ return envs.module_available("faster_qwen3_tts", FASTER_ENV)
def _is_cloned() -> bool:
@@ -297,7 +303,8 @@ def _execute_steps(settings: dict) -> List[taskview.TaskStep]:
if settings["do_install"]:
def install(emit, cancel):
- rc = common.pip_install([FASTER_PIP_PKG], emit=emit, cancel=cancel)
+ rc = common.pip_install([FASTER_PIP_PKG], emit=emit,
+ cancel=cancel, env_dir=FASTER_ENV)
if rc != 0:
print(f"[WARNING] pip install failed (exit {rc}); install "
f"{FASTER_PIP_PKG} manually")
@@ -446,7 +453,8 @@ def build_parser() -> argparse.ArgumentParser:
"prompting; in the TUI, re-transcribe every "
"voice instead of reusing the existing file")
parser.add_argument("--skip-install", action="store_true",
- help="Do not pip install faster-qwen3-tts[demo]")
+ help="Do not pip install faster-qwen3-tts[demo] "
+ "into app/envs/faster")
parser.add_argument("--skip-clone", action="store_true",
help="Do not clone the faster-qwen3-tts repo")
return parser
@@ -468,7 +476,7 @@ def detect() -> BackendStatus:
launch = ""
specs: List[ServerSpec] = []
if cloned and voices_json.exists():
- argv = [str(envs.env_python()),
+ argv = [str(envs.env_python(FASTER_ENV)),
str(_checkout() / "examples" / "openai_server.py"),
"--voices", str(voices_json), "--port", str(_config_port())]
# identity: /health must report model_loaded before the server is
@@ -506,10 +514,11 @@ def _detect_remote(managed: bool = False):
def uninstall(*, emit=None, cancel=None) -> int:
"""Remove the faster-qwen3-tts backend entirely.
- Uninstalls the pip package (``faster-qwen3-tts``) from the managed venv
- and deletes the cloned checkout (``app/faster-qwen3-tts``, which holds
- examples/openai_server.py and voices.json). A running server this tool
- started is stopped first (best-effort).
+ Uninstalls the pip package (``faster-qwen3-tts``) from its managed venv
+ (``app/envs/faster``, FASTER_ENV — never the app env or the qwen
+ backend's) and deletes the cloned checkout (``app/faster-qwen3-tts``,
+ which holds examples/openai_server.py and voices.json). A running server
+ this tool started is stopped first (best-effort).
With EMIT given (the in-TUI task view) pip runs piped, streaming into
EMIT, so its output never touches the terminal behind curses. CANCEL is
@@ -525,10 +534,11 @@ def uninstall(*, emit=None, cancel=None) -> int:
servers.stop("faster")
if common.cancel_requested(cancel):
return 130
- rc = common.pip_uninstall(["faster-qwen3-tts"], emit=emit)
+ rc = common.pip_uninstall(["faster-qwen3-tts"], emit=emit,
+ env_dir=FASTER_ENV)
if rc != 0:
print("[WARNING] pip uninstall failed (exit "
- f"{rc}); remove faster-qwen3-tts from the managed venv manually")
+ f"{rc}); remove faster-qwen3-tts from {FASTER_ENV} manually")
else:
print("[OK] faster-qwen3-tts removed.")
if common.cancel_requested(cancel):