diff --git a/docs/content/docs/developer/setup.mdx b/docs/content/docs/developer/setup.mdx index 58c79c42..d4a777a5 100644 --- a/docs/content/docs/developer/setup.mdx +++ b/docs/content/docs/developer/setup.mdx @@ -35,7 +35,8 @@ Ensure you have these installed: }> [Download Python](https://python.org) ```bash - python3.12 --version # Should be 3.12.x + python3.12 --version # macOS/Linux — should be 3.12.x + py -3.12 --version # Windows ``` Voicebox pins its venv to 3.12 to match CI, because some dependencies have no 3.13 release yet. On Debian/Ubuntu also install `python3.12-venv`. @@ -216,7 +217,9 @@ This installs dependencies for: cd backend # Create virtual environment (use Python 3.12 — see Prerequisites) -python3.12 -m venv venv +python3.12 -m venv venv # macOS/Linux +# or +py -3.12 -m venv venv # Windows # Activate virtual environment source venv/bin/activate # macOS/Linux diff --git a/docs/content/docs/overview/troubleshooting.mdx b/docs/content/docs/overview/troubleshooting.mdx index 5c2f26ee..dc1eaef1 100644 --- a/docs/content/docs/overview/troubleshooting.mdx +++ b/docs/content/docs/overview/troubleshooting.mdx @@ -295,7 +295,8 @@ This is expected behavior. The first generation downloads the selected TTS engin Ensure Python 3.12: ```bash - python3.12 --version + python3.12 --version # macOS/Linux + py -3.12 --version # Windows ``` Voicebox pins its venv to Python 3.12 because some dependencies have no 3.13 @@ -303,8 +304,10 @@ This is expected behavior. The first generation downloads the selected TTS engin so re-running it is usually the fix. If `just setup` can't find a usable 3.12, install one: `uv python install 3.12` - works anywhere, or use `brew install python@3.12` on macOS and `sudo apt install - python3.12 python3.12-venv` on Debian/Ubuntu. + works anywhere; `brew install python@3.12` on macOS; `sudo apt install + python3.12 python3.12-venv` on Debian/Ubuntu; or on Windows install from + [python.org](https://python.org) / `winget install -e --id Python.Python.3.12` + and use the `py -3.12` launcher. diff --git a/justfile b/justfile index 99eedda8..f83e9c99 100644 --- a/justfile +++ b/justfile @@ -12,7 +12,6 @@ venv := backend_dir / "venv" # Platform-aware paths venv_bin := if os() == "windows" { venv / "Scripts" } else { venv / "bin" } python := if os() == "windows" { venv_bin / "python.exe" } else { venv_bin / "python" } -pip := if os() == "windows" { venv_bin / "pip.exe" } else { venv_bin / "pip" } # Shell selection: use powershell on Windows, bash elsewhere set windows-shell := ["powershell", "-NoProfile", "-Command"] @@ -40,12 +39,12 @@ setup-python: "$1" -c 'import sys; sys.exit(sys.version_info[:2] != tuple(map(int, "{{ python_version }}".split("."))))' 2>/dev/null } - # Testing for an executable file is not enough: console scripts hard-code the - # venv's absolute path in their shebang, so a venv that was built elsewhere and - # moved into place has a pip that exists, is executable, and still dies with - # "cannot execute: required file not found". Running it is the only real check. + # Invoke pip via the venv's python so validation and installs share the same + # interpreter. A copied venv can keep a working `pip` console script whose + # shebang still points at the original tree — that would make `pip --version` + # succeed while later installs land in the wrong environment. pip_works() { - "{{ pip }}" --version >/dev/null 2>&1 + "{{ python }}" -m pip --version >/dev/null 2>&1 } # Every interpreter on PATH that could be the pinned version, plus uv's, which @@ -97,7 +96,7 @@ setup-python: exit 1 fi echo "Installing Python dependencies..." - {{ pip }} install --upgrade pip -q + "{{ python }}" -m pip install --upgrade pip -q if [ "$(uname)" = "Linux" ]; then torch_index="" if [ -e /proc/driver/nvidia/version ] || [ -d /sys/module/nvidia ]; then @@ -115,27 +114,27 @@ setup-python: torch_index="https://download.pytorch.org/whl/rocm${rocm_ver}" fi if [ -n "$torch_index" ]; then - {{ pip }} install torch torchaudio --index-url "$torch_index" + "{{ python }}" -m pip install torch torchaudio --index-url "$torch_index" fi fi - {{ pip }} install -r {{ backend_dir }}/requirements.txt + "{{ python }}" -m pip install -r {{ backend_dir }}/requirements.txt # Chatterbox pins numpy<1.26 / torch==2.6 which break on Python 3.12+ - {{ pip }} install --no-deps chatterbox-tts + "{{ python }}" -m pip install --no-deps chatterbox-tts # HumeAI TADA pins torch>=2.7,<2.8 which conflicts with our torch>=2.1 - {{ pip }} install --no-deps hume-tada + "{{ python }}" -m pip install --no-deps hume-tada # Apple Silicon: install MLX backend if [ "$(uname -m)" = "arm64" ] && [ "$(uname)" = "Darwin" ]; then echo "Detected Apple Silicon — installing MLX dependencies..." - {{ pip }} install -r {{ backend_dir }}/requirements-mlx.txt + "{{ python }}" -m pip install -r {{ backend_dir }}/requirements-mlx.txt # mlx-lm and mlx-audio declare transformers>=5.x, which conflicts with # our transformers<=4.57.x cap, so install them --no-deps (their other # runtime deps are covered by requirements.txt / requirements-mlx.txt — # see the note in requirements-mlx.txt and .github/workflows/release.yml) - {{ pip }} install --no-deps mlx-lm==0.31.1 - {{ pip }} install --no-deps mlx-audio==0.4.1 + "{{ python }}" -m pip install --no-deps mlx-lm==0.31.1 + "{{ python }}" -m pip install --no-deps mlx-audio==0.4.1 fi - {{ pip }} install git+https://github.com/QwenLM/Qwen3-TTS.git - {{ pip }} install pyinstaller ruff pytest pytest-asyncio -q + "{{ python }}" -m pip install git+https://github.com/QwenLM/Qwen3-TTS.git + "{{ python }}" -m pip install pyinstaller ruff pytest pytest-asyncio -q echo "Python environment ready." [windows] @@ -147,8 +146,8 @@ setup-python: return ($LASTEXITCODE -eq 0 -and $v -eq $target); \ }; \ function Test-Pip { \ - if (-not (Test-Path "{{ pip }}")) { return $false }; \ - & "{{ pip }}" --version *> $null; \ + if (-not (Test-Path "{{ python }}")) { return $false }; \ + & "{{ python }}" -m pip --version *> $null; \ return ($LASTEXITCODE -eq 0); \ }; \ $py = $null; \ @@ -183,22 +182,22 @@ setup-python: $hasIntelArc = ($gpus | Where-Object { $_ -match 'Arc' }).Count -gt 0; \ if ($hasNvidia) { \ Write-Host "NVIDIA GPU detected — installing PyTorch with CUDA support..."; \ - & "{{ pip }}" install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128; \ + & "{{ python }}" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128; \ } elseif ($hasIntelArc) { \ Write-Host "Intel Arc GPU detected — installing PyTorch with XPU support..."; \ - & "{{ pip }}" install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/xpu; \ - & "{{ pip }}" install intel-extension-for-pytorch --index-url https://download.pytorch.org/whl/xpu; \ + & "{{ python }}" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/xpu; \ + & "{{ python }}" -m pip install intel-extension-for-pytorch --index-url https://download.pytorch.org/whl/xpu; \ } else { \ Write-Host "No NVIDIA or Intel Arc GPU detected — using CPU-only PyTorch."; \ Write-Host "If you have an Intel Arc GPU, install XPU support manually:"; \ - Write-Host " pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/xpu"; \ - Write-Host " pip install intel-extension-for-pytorch --index-url https://download.pytorch.org/whl/xpu"; \ + Write-Host " python -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/xpu"; \ + Write-Host " python -m pip install intel-extension-for-pytorch --index-url https://download.pytorch.org/whl/xpu"; \ } - & "{{ pip }}" install -r {{ backend_dir }}/requirements.txt - & "{{ pip }}" install --no-deps chatterbox-tts - & "{{ pip }}" install --no-deps hume-tada - & "{{ pip }}" install git+https://github.com/QwenLM/Qwen3-TTS.git - & "{{ pip }}" install pyinstaller ruff pytest pytest-asyncio -q + & "{{ python }}" -m pip install -r {{ backend_dir }}/requirements.txt + & "{{ python }}" -m pip install --no-deps chatterbox-tts + & "{{ python }}" -m pip install --no-deps hume-tada + & "{{ python }}" -m pip install git+https://github.com/QwenLM/Qwen3-TTS.git + & "{{ python }}" -m pip install pyinstaller ruff pytest pytest-asyncio -q Write-Host "Python environment ready." # Install JavaScript dependencies