From d2083c8737084b4a8deb4f4baa0c4252a47a5a8c Mon Sep 17 00:00:00 2001 From: Thales Pereira <31625914+thcp@users.noreply.github.com> Date: Tue, 30 Jun 2026 00:11:37 +0100 Subject: [PATCH] fix(desktop): Blackwell GPU (RTX 5000) falls back to CPU silently (#239) Three changes to address NVIDIA RTX 5000 series (sm_120, cu128) running stem separation on CPU instead of GPU: - Bump cu128 torch from 2.7.1 to 2.8.0: 2.7.1 shipped incomplete sm_120 kernels for Blackwell, causing verify_cuda_torch to fail. 2.8.0+cu128 wheels are available and include full sm_120 support. - Log verify_cuda_torch stderr to logs/setup.log: previously silenced with Stdio::null(), so there was no diagnostic path when Blackwell kernel verification failed. - Show a visible error in setup.js when gpu_detected but cuda_verified is false: the previous status-line message was easy to miss. Now calls showError() so the user knows their GPU was found but CUDA setup failed and where to look for details. --- desktop/src-tauri/src/main.rs | 42 +++++++++++++++++++++++++++++------ desktop/ui/setup.js | 5 +++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/desktop/src-tauri/src/main.rs b/desktop/src-tauri/src/main.rs index d79f2c0..3bd526c 100644 --- a/desktop/src-tauri/src/main.rs +++ b/desktop/src-tauri/src/main.rs @@ -1093,9 +1093,11 @@ fn install_cuda_torch(python: &Path, index_url: &str, state: &BackendState) -> R // // Blackwell (cu128) only has wheels for torch 2.7+; every other tag stays // on the validated 2.6.0 line (#217). torchaudio.save() routes through - // soundfile here, so the 2.7 torchaudio codec change doesn't affect us. + // soundfile here, so minor torchaudio codec changes don't affect us. + // cu128 uses 2.8.0: 2.7.1 shipped incomplete sm_120 kernels for Blackwell + // (RTX 5000 series), causing verify_cuda_torch to fail (#239). let tag = cuda_tag_from_url(index_url); - let torch_version = if tag == "cu128" { "2.7.1" } else { "2.6.0" }; + let torch_version = if tag == "cu128" { "2.8.0" } else { "2.6.0" }; let torch_spec = format!("torch=={torch_version}+{tag}"); let torchaudio_spec = format!("torchaudio=={torch_version}+{tag}"); // --ignore-installed: overwrites even a corrupted/partial install that @@ -1168,7 +1170,7 @@ fn verify_cuda_torch(python: &Path) -> bool { // build), which then crashes mid-extraction with "no kernel image is // available" (#217). Force a real kernel launch so an incompatible wheel is // caught here and the app falls back to CPU cleanly. - Command::new(python) + let result = Command::new(python) .args([ "-c", "import torch; \ @@ -1178,10 +1180,36 @@ fn verify_cuda_torch(python: &Path) -> bool { exit(0)", ]) .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .map(|s| s.success()) - .unwrap_or(false) + .stderr(Stdio::piped()) + .output(); + + match result { + Ok(out) if out.status.success() => true, + Ok(out) => { + let stderr = String::from_utf8_lossy(&out.stderr); + if !stderr.trim().is_empty() { + if let Ok(data_dir) = local_data_dir() { + let log_path = data_dir.join("logs").join("setup.log"); + if let Some(parent) = log_path.parent() { + let _ = fs::create_dir_all(parent); + } + if let Ok(mut f) = fs::OpenOptions::new() + .create(true) + .append(true) + .open(&log_path) + { + let _ = writeln!( + f, + "[stemdeck] CUDA verify failed. stderr:\n{}", + stderr.trim() + ); + } + } + } + false + } + Err(_) => false, + } } /// Opens an http/https URL in the system browser. Rejects non-http schemes. diff --git a/desktop/ui/setup.js b/desktop/ui/setup.js index 1ef824b..8e13e97 100644 --- a/desktop/ui/setup.js +++ b/desktop/ui/setup.js @@ -348,6 +348,11 @@ async function runSetup() { ? `${gpu.gpuName} acceleration enabled` : "MPS acceleration unavailable - stem separation will use CPU"; } else { + if (gpu.gpuDetected && !gpu.cudaVerified) { + showError( + `GPU detected (${gpu.gpuName}) but CUDA setup failed - stem separation will use CPU.\nCheck logs/setup.log in the StemDeck data folder for details.` + ); + } gpuSummary = gpu.gpuDetected ? gpu.cudaVerified ? `${gpu.gpuName} - CUDA ${gpu.cudaVersion} enabled`