upgrade CUDA backend from cu126 to cu128 and fix GPU settings UI

Upgrade CUDA toolkit from 12.6 (cu126) to 12.8 (cu128) for proper
RTX 50-series (Blackwell) GPU support. Users with RTX 5070/5080/5090
were reporting CUDA detection failures with cu126.

Also fix the GPU Acceleration settings panel where the 'Switch to CPU
Backend' button was unreachable — it was inside a conditional block
that required !isCurrentlyCuda, making it impossible to switch back
to CPU once running on CUDA.

Closes #315
This commit is contained in:
James Pine
2026-03-18 07:47:39 -07:00
parent c9f38dd496
commit fc5ed1ff40
8 changed files with 54 additions and 40 deletions
+7 -7
View File
@@ -191,10 +191,10 @@ jobs:
pip install --no-deps chatterbox-tts pip install --no-deps chatterbox-tts
pip install --no-deps hume-tada pip install --no-deps hume-tada
- name: Install PyTorch with CUDA 12.6 - name: Install PyTorch with CUDA 12.8
run: | run: |
pip install torch --index-url https://download.pytorch.org/whl/cu126 --force-reinstall --no-deps pip install torch --index-url https://download.pytorch.org/whl/cu128 --force-reinstall --no-deps
pip install torchaudio --index-url https://download.pytorch.org/whl/cu126 --force-reinstall --no-deps pip install torchaudio --index-url https://download.pytorch.org/whl/cu128 --force-reinstall --no-deps
- name: Verify CUDA support in torch - name: Verify CUDA support in torch
run: | run: |
@@ -211,8 +211,8 @@ jobs:
python scripts/package_cuda.py \ python scripts/package_cuda.py \
backend/dist/voicebox-server-cuda/ \ backend/dist/voicebox-server-cuda/ \
--output release-assets/ \ --output release-assets/ \
--cuda-libs-version cu126-v1 \ --cuda-libs-version cu128-v1 \
--torch-compat ">=2.6.0,<2.11.0" --torch-compat ">=2.7.0,<2.11.0"
- name: Upload archives to GitHub Release - name: Upload archives to GitHub Release
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
@@ -221,8 +221,8 @@ jobs:
files: | files: |
release-assets/voicebox-server-cuda.tar.gz release-assets/voicebox-server-cuda.tar.gz
release-assets/voicebox-server-cuda.tar.gz.sha256 release-assets/voicebox-server-cuda.tar.gz.sha256
release-assets/cuda-libs-cu126-v1.tar.gz release-assets/cuda-libs-cu128-v1.tar.gz
release-assets/cuda-libs-cu126-v1.tar.gz.sha256 release-assets/cuda-libs-cu128-v1.tar.gz.sha256
release-assets/cuda-libs.json release-assets/cuda-libs.json
draft: true draft: true
env: env:
@@ -243,7 +243,40 @@ export function GpuAcceleration() {
{/* Native GPU detected - no CUDA download needed */} {/* Native GPU detected - no CUDA download needed */}
{/* CUDA download section - only show when no GPU is active (native or CUDA) */} {/* Currently running CUDA - show switch back to CPU */}
{isCurrentlyCuda && platform.metadata.isTauri && (
<>
{restartPhase !== 'idle' ? (
<div className="flex items-center gap-2 p-3 rounded-lg bg-primary/5 border">
<Loader2 className="h-4 w-4 animate-spin" />
<span className="text-sm">
{restartPhase === 'stopping' && 'Stopping server...'}
{restartPhase === 'waiting' && 'Restarting server...'}
{restartPhase === 'ready' && 'Server restarted successfully!'}
</span>
</div>
) : (
<div className="space-y-3">
<p className="text-sm text-muted-foreground">
Running with CUDA GPU acceleration. Switch back to CPU if needed (you can
re-download later).
</p>
<Button onClick={handleSwitchToCpu} variant="outline" className="w-full" size="sm">
<RotateCw className="h-4 w-4 mr-2" />
Switch to CPU Backend
</Button>
</div>
)}
{error && (
<div className="flex items-center gap-2 text-sm text-destructive">
<AlertCircle className="h-4 w-4 shrink-0" />
<span>{error}</span>
</div>
)}
</>
)}
{/* CUDA download/manage section - show when no native GPU and not currently running CUDA */}
{!hasNativeGpu && !isCurrentlyCuda && ( {!hasNativeGpu && !isCurrentlyCuda && (
<> <>
{/* Download progress (manual download or auto-update) */} {/* Download progress (manual download or auto-update) */}
@@ -315,7 +348,7 @@ export function GpuAcceleration() {
)} )}
{/* Downloaded but not active - show switch button */} {/* Downloaded but not active - show switch button */}
{cudaAvailable && !isCurrentlyCuda && platform.metadata.isTauri && ( {cudaAvailable && platform.metadata.isTauri && (
<div className="space-y-3"> <div className="space-y-3">
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
CUDA backend is downloaded and ready. Restart the server to enable GPU CUDA backend is downloaded and ready. Restart the server to enable GPU
@@ -328,27 +361,8 @@ export function GpuAcceleration() {
</div> </div>
)} )}
{/* Currently active - show switch back to CPU */}
{isCurrentlyCuda && platform.metadata.isTauri && (
<div className="space-y-3">
<p className="text-sm text-muted-foreground">
Running with CUDA GPU acceleration. Switch back to CPU if needed (you can
re-download later).
</p>
<Button
onClick={handleSwitchToCpu}
variant="outline"
className="w-full"
size="sm"
>
<RotateCw className="h-4 w-4 mr-2" />
Switch to CPU Backend
</Button>
</div>
)}
{/* Delete option when downloaded (and not active) */} {/* Delete option when downloaded (and not active) */}
{cudaAvailable && !isCurrentlyCuda && ( {cudaAvailable && (
<Button <Button
onClick={handleDelete} onClick={handleDelete}
variant="ghost" variant="ghost"
+1 -1
View File
@@ -370,7 +370,7 @@ def build_server(cuda=False):
"torchvision", "torchvision",
"torchaudio", "torchaudio",
"--index-url", "--index-url",
"https://download.pytorch.org/whl/cu126", "https://download.pytorch.org/whl/cu128",
"--force-reinstall", "--force-reinstall",
"-q", "-q",
], ],
+1 -1
View File
@@ -8,7 +8,7 @@ sqlalchemy>=2.0.0
alembic>=1.13.0 alembic>=1.13.0
# ML models # ML models
torch>=2.1.0 torch>=2.7.0
transformers>=4.36.0,<=4.57.6 transformers>=4.36.0,<=4.57.6
accelerate>=0.26.0 accelerate>=0.26.0
huggingface_hub>=0.20.0 huggingface_hub>=0.20.0
+1 -1
View File
@@ -32,7 +32,7 @@ PROGRESS_KEY = "cuda-backend"
# The current expected CUDA libs version. Bump this when we change the # The current expected CUDA libs version. Bump this when we change the
# CUDA toolkit version or torch's CUDA dependency changes (e.g. cu126 -> cu128). # CUDA toolkit version or torch's CUDA dependency changes (e.g. cu126 -> cu128).
CUDA_LIBS_VERSION = "cu126-v1" CUDA_LIBS_VERSION = "cu128-v1"
def get_backends_dir() -> Path: def get_backends_dir() -> Path:
+2 -2
View File
@@ -159,11 +159,11 @@ Tauri looks for `voicebox-server-${PLATFORM}` in `src-tauri/binaries/` and bundl
The `build-cuda-windows` job runs separately: The `build-cuda-windows` job runs separately:
1. Install PyTorch with CUDA 12.6 1. Install PyTorch with CUDA 12.8
2. Build with `build_binary.py --cuda` (produces `--onedir` output) 2. Build with `build_binary.py --cuda` (produces `--onedir` output)
3. Package with `scripts/package_cuda.py` into two archives: 3. Package with `scripts/package_cuda.py` into two archives:
- `voicebox-server-cuda.tar.gz` — server core (~945 MB) - `voicebox-server-cuda.tar.gz` — server core (~945 MB)
- `cuda-libs-cu126-v1.tar.gz` — NVIDIA runtime libraries (~1.7 GB, cached independently) - `cuda-libs-cu128-v1.tar.gz` — NVIDIA runtime libraries (~1.7 GB, cached independently)
4. Upload archives as release artifacts 4. Upload archives as release artifacts
This binary is downloaded on-demand by users who enable CUDA in settings. The CUDA libs archive is only re-downloaded when the CUDA toolkit version changes, not on every app update. This binary is downloaded on-demand by users who enable CUDA in settings. The CUDA libs archive is only re-downloaded when the CUDA toolkit version changes, not on every app update.
+1 -1
View File
@@ -72,7 +72,7 @@ setup-python:
$hasNvidia = $null -ne (Get-WmiObject Win32_VideoController | Where-Object { $_.Name -match 'NVIDIA' }) $hasNvidia = $null -ne (Get-WmiObject Win32_VideoController | Where-Object { $_.Name -match 'NVIDIA' })
if ($hasNvidia) { \ if ($hasNvidia) { \
Write-Host "NVIDIA GPU detected — installing PyTorch with CUDA support..."; \ Write-Host "NVIDIA GPU detected — installing PyTorch with CUDA support..."; \
& "{{ pip }}" install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126; \ & "{{ pip }}" install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128; \
} }
& "{{ pip }}" install -r {{ backend_dir }}/requirements.txt & "{{ pip }}" install -r {{ backend_dir }}/requirements.txt
& "{{ pip }}" install --no-deps chatterbox-tts & "{{ pip }}" install --no-deps chatterbox-tts
+5 -5
View File
@@ -3,13 +3,13 @@ Package the PyInstaller --onedir CUDA build into two archives.
Takes the PyInstaller --onedir output directory and splits it into: Takes the PyInstaller --onedir output directory and splits it into:
1. voicebox-server-cuda.tar.gz server core (exe + non-NVIDIA deps) 1. voicebox-server-cuda.tar.gz server core (exe + non-NVIDIA deps)
2. cuda-libs-cu126.tar.gz NVIDIA runtime libraries only 2. cuda-libs-cu128.tar.gz NVIDIA runtime libraries only
3. cuda-libs.json version manifest for the CUDA libs 3. cuda-libs.json version manifest for the CUDA libs
Usage: Usage:
python scripts/package_cuda.py backend/dist/voicebox-server-cuda/ python scripts/package_cuda.py backend/dist/voicebox-server-cuda/
python scripts/package_cuda.py backend/dist/voicebox-server-cuda/ --output release-assets/ python scripts/package_cuda.py backend/dist/voicebox-server-cuda/ --output release-assets/
python scripts/package_cuda.py backend/dist/voicebox-server-cuda/ --cuda-libs-version cu126-v1 python scripts/package_cuda.py backend/dist/voicebox-server-cuda/ --cuda-libs-version cu128-v1
""" """
import argparse import argparse
@@ -208,13 +208,13 @@ def main():
parser.add_argument( parser.add_argument(
"--cuda-libs-version", "--cuda-libs-version",
type=str, type=str,
default="cu126-v1", default="cu128-v1",
help="Version string for the CUDA libs archive (default: cu126-v1)", help="Version string for the CUDA libs archive (default: cu128-v1)",
) )
parser.add_argument( parser.add_argument(
"--torch-compat", "--torch-compat",
type=str, type=str,
default=">=2.6.0,<2.11.0", default=">=2.7.0,<2.11.0",
help="Torch version compatibility range (default: >=2.6.0,<2.11.0)", help="Torch version compatibility range (default: >=2.6.0,<2.11.0)",
) )
args = parser.parse_args() args = parser.parse_args()