The product could only reach a GPU through one hard-coded route: `wsl.exe -d Ubuntu`, a device named "RTX 4090", and launch scripts that existed only as PowerShell. On this machine `WSL_DISTRO_NAME` is already set, so the local shell is Linux and the wsl.exe hop was unnecessary; on any other Linux host it is impossible. Every SGLang, vLLM and KTransformers profile was reported "missing" here even with a working 4090. profiles.py now asks the host what it is instead of assuming: `uses_wsl()` is false inside WSL and only true when wsl.exe is actually on PATH, `host_shell()` runs `bash -lc` directly or through `wsl.exe -d settings.wsl_distro`, `gpu_available()` replaced `wsl_gpu_available()`, and `launch_script()` picks the .sh twin on a Linux host and the .ps1 on a Windows one. The schema field `wsl_gpu` became `gpu_available` because the old name lied on Linux. Training no longer fails on a card name. `cuda_bf16_training()` gates on cuda_available plus bf16_supported, which the training environment already records, so an RTX 5090 or a 4080 passes and a non-BF16 4090 still fails. Fourteen .sh twins cover the six launch profiles plus install, verify, serve, download and finetune; the six WSL-hopping .ps1 files read ELY_EYE_WSL_DISTRO instead of Ubuntu. PowerShell parsing is not verified here because no pwsh exists on this host. ci.yml runs pytest, ruff, go build/vet/test/gofmt, the Vite build and a docker build-plus-curl on every push. To make that lint gate mean anything, the 17 pre-existing ruff findings across backend/src are cleared: 14 mechanical fixes plus three probe handlers that now name the failure families they absorb (OSError, SubprocessError, ValueError) instead of catching Exception. Verification: pytest 239 passed; ruff check backend/src bench clean (17 at HEAD); mypy on the 12 touched files 14 errors, identical at HEAD; pyright on the same files 8 errors, identical at HEAD; bash -n clean on all 15 .sh.
103 lines
4.5 KiB
Python
103 lines
4.5 KiB
Python
"""The launch layer must describe the machine it runs on, not the one it was written on."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import stat
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from ely_eye import profiles
|
|
from ely_eye.config import Settings
|
|
from ely_eye.proofs.training_trace import cuda_bf16_training
|
|
from ely_eye.training import require_cuda_bf16
|
|
|
|
|
|
def _stub_nvidia_smi(tmp_path: Path, monkeypatch, output: str, exit_code: int = 0) -> None:
|
|
bin_dir = tmp_path / "bin"
|
|
bin_dir.mkdir()
|
|
stub = bin_dir / "nvidia-smi"
|
|
stub.write_text(f"#!/bin/sh\nprintf '%s\\n' '{output}'\nexit {exit_code}\n", encoding="utf-8")
|
|
stub.chmod(stub.stat().st_mode | stat.S_IEXEC)
|
|
monkeypatch.setenv("PATH", f"{bin_dir}{os.pathsep}{os.environ['PATH']}")
|
|
|
|
|
|
def test_a_gpu_that_is_not_the_written_down_card_still_counts(tmp_path: Path, monkeypatch) -> None:
|
|
_stub_nvidia_smi(tmp_path, monkeypatch, "GPU 0: NVIDIA GeForce RTX 5090 (UUID: GPU-1234)")
|
|
monkeypatch.setattr(profiles, "uses_wsl", lambda: False)
|
|
assert profiles.gpu_available(Settings(home=tmp_path / "home")) is True
|
|
|
|
|
|
def test_a_machine_the_driver_cannot_see_reports_no_gpu(tmp_path: Path, monkeypatch) -> None:
|
|
_stub_nvidia_smi(tmp_path, monkeypatch, "nvidia-smi: command not found", exit_code=127)
|
|
monkeypatch.setattr(profiles, "uses_wsl", lambda: False)
|
|
assert profiles.gpu_available(Settings(home=tmp_path / "home")) is False
|
|
|
|
|
|
def test_the_distro_name_comes_from_settings(monkeypatch) -> None:
|
|
monkeypatch.setattr(profiles, "uses_wsl", lambda: True)
|
|
command = profiles.host_shell("true", Settings(home=Path("/tmp"), wsl_distro="Ubuntu-24.04"))
|
|
assert command == ["wsl.exe", "-d", "Ubuntu-24.04", "bash", "-lc", "true"]
|
|
|
|
|
|
def test_inside_wsl_the_local_shell_runs(monkeypatch, tmp_path: Path) -> None:
|
|
monkeypatch.setenv("WSL_DISTRO_NAME", "Ubuntu")
|
|
monkeypatch.setattr(profiles.shutil, "which", lambda name: "/mnt/c/WINDOWS/system32/wsl.exe")
|
|
assert profiles.uses_wsl() is False
|
|
monkeypatch.delenv("WSL_DISTRO_NAME")
|
|
assert profiles.uses_wsl() is True
|
|
assert profiles.host_shell("true", Settings(home=tmp_path / "home", wsl_distro="Ubuntu"))[0] == "wsl.exe"
|
|
|
|
|
|
def test_a_linux_host_is_pointed_at_the_shell_twin(monkeypatch) -> None:
|
|
monkeypatch.setattr(profiles, "uses_wsl", lambda: False)
|
|
assert profiles.launch_script("scripts/launch-sglang-live.ps1") == "scripts/launch-sglang-live.sh"
|
|
monkeypatch.setattr(profiles, "uses_wsl", lambda: True)
|
|
assert profiles.launch_script("scripts/launch-sglang-live.ps1") == "scripts/launch-sglang-live.ps1"
|
|
|
|
|
|
def test_the_training_verdict_does_not_name_a_card() -> None:
|
|
newer = {"cuda_available": True, "bf16_supported": True, "device_name": "NVIDIA GeForce RTX 5090"}
|
|
assert cuda_bf16_training(newer) is True
|
|
older = {"cuda_available": True, "bf16_supported": True, "device_name": "NVIDIA GeForce RTX 4080"}
|
|
assert cuda_bf16_training(older) is True
|
|
without_bf16 = {"cuda_available": True, "bf16_supported": False, "device_name": "NVIDIA GeForce RTX 4090"}
|
|
assert cuda_bf16_training(without_bf16) is False
|
|
|
|
|
|
class _FakeCuda:
|
|
def __init__(self, available: bool, bf16: bool) -> None:
|
|
self._available = available
|
|
self._bf16 = bf16
|
|
|
|
def is_available(self) -> bool:
|
|
return self._available
|
|
|
|
def is_bf16_supported(self) -> bool:
|
|
return self._bf16
|
|
|
|
|
|
class _FakeTorch:
|
|
def __init__(self, available: bool, bf16: bool) -> None:
|
|
self.cuda = _FakeCuda(available, bf16)
|
|
|
|
|
|
def test_training_refuses_a_machine_without_cuda_by_capability_not_card() -> None:
|
|
with pytest.raises(RuntimeError) as refused:
|
|
require_cuda_bf16(_FakeTorch(available=False, bf16=False))
|
|
assert "4090" not in str(refused.value)
|
|
require_cuda_bf16(_FakeTorch(available=True, bf16=True))
|
|
|
|
|
|
def test_every_profile_ships_a_script_for_this_host(tmp_path: Path, monkeypatch) -> None:
|
|
root = Path(__file__).resolve().parents[2]
|
|
monkeypatch.setattr(profiles, "uses_wsl", lambda: False)
|
|
linux = profiles.runtime_profile_report(Settings(home=tmp_path / "home"), root)
|
|
assert [item.name for item in linux.validations if not item.script_exists] == []
|
|
assert all(item.script.endswith(".sh") for item in linux.profiles), linux.profiles
|
|
monkeypatch.setattr(profiles, "uses_wsl", lambda: True)
|
|
windows = profiles.runtime_profile_report(Settings(home=tmp_path / "home"), root)
|
|
assert [item.name for item in windows.validations if not item.script_exists] == []
|
|
assert all(item.script.endswith(".ps1") for item in windows.profiles), windows.profiles
|