Fix Canary-Qwen CUDA-tag skew + cdifflib header build#517
Conversation
PyPI ships torch 2.8.x as +cu129 but torchaudio 2.8.x as +cu128, so a clean install of the Canary-Qwen subprocess venv fails at torchaudio import with "PyTorch has CUDA 12.9 whereas TorchAudio has CUDA 12.8". After ensure_venv completes, force-reinstall both from the cu128 PyTorch index with --no-deps so the two wheels share a CUDA tag while NeMo and the nvidia-*-cu12 runtime libs already installed by the main resolver pass stay in place. cu128 runtime is forward-compatible with cu12+ and cu13 host drivers. A marker file in the venv gates this to first-build only. Also pass --managed-python to `uv venv` so canary's Python 3.12 environment uses uv's managed interpreter (which ships Python.h) instead of a system/spack Python that may lack dev headers — needed for cdifflib's source build on HPC hosts without header-bearing Pythons. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@wilke0818 - did you see #516 |
There was a problem hiding this comment.
Code Review
This pull request implements a CUDA version fixup for the Canary-Qwen speech-to-text task to resolve a runtime mismatch between Torch and TorchAudio, and updates the virtual environment creation to use uv's --managed-python flag. Feedback indicates that the fixup logic is susceptible to race conditions in multi-process environments and recommends using a file lock for synchronization. Additionally, it is suggested to allow subprocess output to be visible to the user for better progress tracking during the large download.
| if not cuda_fixup_marker.is_file(): | ||
| subprocess.run( | ||
| [ | ||
| _find_uv(), | ||
| "pip", | ||
| "install", | ||
| "--python", | ||
| venv_python(venv_dir), | ||
| "--force-reinstall", | ||
| "--no-deps", | ||
| "--index-url", | ||
| "https://download.pytorch.org/whl/cu128", | ||
| "torch>=2.8,<2.9", | ||
| "torchaudio>=2.8,<2.9", | ||
| ], | ||
| check=True, | ||
| capture_output=True, | ||
| text=True, | ||
| ) | ||
| cuda_fixup_marker.touch() |
There was a problem hiding this comment.
The CUDA fixup block is susceptible to a race condition. Since ensure_venv releases its lock before this block executes, multiple concurrent processes might attempt to run the uv pip install command simultaneously if the marker file hasn't been created yet. This could lead to virtual environment corruption or redundant heavy downloads in multi-process environments.
Additionally, using capture_output=True hides progress and error details for a potentially slow operation (downloading ~600MB of wheels). It is better to let the output stream to the console so the user can see progress and diagnose failures easily.
if not cuda_fixup_marker.is_file():
from filelock import FileLock
lock_path = venv_dir.parent / f"{venv_dir.name}.lock"
with FileLock(str(lock_path), timeout=600):
# Re-check marker inside the lock to prevent race conditions
if not cuda_fixup_marker.is_file():
subprocess.run(
[
_find_uv(),
"pip",
"install",
"--python",
venv_python(venv_dir),
"--force-reinstall",
"--no-deps",
"--index-url",
"https://download.pytorch.org/whl/cu128",
"torch>=2.8,<2.9",
"torchaudio>=2.8,<2.9",
],
check=True,
)
cuda_fixup_marker.touch()
nope. will test that one instead |
|
use #516 instead |
Summary
The Canary-Qwen subprocess venv currently fails to come up on a clean install for two unrelated reasons. This PR fixes both with the minimum-footprint changes that don't
disturb other subprocess venvs (Sortformer, Conformer-CTC, Coqui, PPGs, etc.) or alter the resolver behavior for environments where things already work.
Problem 1: torchaudio CUDA-tag skew
PyPI ships torch 2.8.x as +cu129 but torchaudio 2.8.x as +cu128. A fresh ensure_venv install of the Canary-Qwen requirements therefore produces a venv where torch is linked
against CUDA 12.9 and torchaudio against CUDA 12.8. The first torchaudio import then raises:
RuntimeError: Detected that PyTorch and TorchAudio were compiled with
different CUDA versions. PyTorch has CUDA version 12.9 whereas TorchAudio
has CUDA version 12.8.
Fix. After ensure_venv returns, run a one-shot uv pip install --force-reinstall --no-deps --index-url https://download.pytorch.org/whl/cu128 torch>=2.8,<2.9
torchaudio>=2.8,<2.9. The PyTorch cu128 wheel index always publishes torch + torchaudio together with matching +cu128 tags, so the two wheels are guaranteed to align. A
marker file (.senselab-canary-cuda-fixup) inside the venv directory gates this to first-build only — subsequent calls reuse the venv as-is with zero overhead.
Why this doesn't break other systems
PPGs, etc. continue resolving exactly as before.
transitive dependencies stay in place. cu128 torch links against libcudart.so.12 (provided by the nvidia-cuda-runtime-cu12 already present from the main install).
execute code compiled for cu12.8. The fix works on any of those host drivers — no host-CUDA mirroring required.
Problem 2: cdifflib source build fails on HPC hosts
cdifflib is a transitive dep of NeMo that lacks pre-built wheels for some Python/platform pairs and falls back to a C source build. Spack-built Pythons on HPC clusters (e.g.,
MIT ORCD) are typically installed without development headers, so the build fails with fatal error: Python.h: No such file or directory.
Fix. Pass --managed-python to uv venv when creating subprocess venvs. uv's managed Python downloads ship standalone Python builds that include development headers, so C
extensions compile cleanly.
Why this doesn't break other systems
pick a managed Python (the common case when the requested version isn't on PATH), the flag is a no-op. On machines where the system Python does have headers (most laptops,
most CI runners), the managed Python is functionally equivalent.
subprocess venvs.
Test plan
model, confirm it fails on import torchaudio.
Diff size
2 files changed, 37 insertions(+), 2 deletions(-) — 1 line in subprocess_venv.py, ~28 in canary_qwen.py (the gated fixup block + multi-line import).