"""GPU load readout via nvidia-smi (present in the container thanks to the NVIDIA Container Toolkit's `utility` capability). Returns None if unavailable — the UI just shows n/a (e.g. CPU-fallback run).""" import subprocess def read_gpu() -> dict | None: try: out = subprocess.run( [ "nvidia-smi", "--query-gpu=utilization.gpu,memory.used,memory.total,temperature.gpu", "--format=csv,noheader,nounits", ], capture_output=True, text=True, timeout=5, check=True, ).stdout.strip().splitlines() except (OSError, subprocess.SubprocessError): return None if not out: return None parts = [p.strip() for p in out[0].split(",")] try: return { "util_pct": int(float(parts[0])), "mem_used_mb": int(float(parts[1])), "mem_total_mb": int(float(parts[2])), "temp_c": int(float(parts[3])), } except (ValueError, IndexError): return None