From c259fe6cbe3fa17002b79eef393d3f8115dcd126 Mon Sep 17 00:00:00 2001 From: Lilith Date: Sun, 15 Feb 2026 10:32:47 -0800 Subject: [PATCH] =?UTF-8?q?chore(lilith=5Fservice=5Ffastapi):=20?= =?UTF-8?q?=F0=9F=94=A7=20Update=20FastAPI=20lifespan=20configuration=20in?= =?UTF-8?q?=20lifespan.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../lifespan.py | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/lilith_service_fastapi_bootstrap/lifespan.py b/src/lilith_service_fastapi_bootstrap/lifespan.py index 43fd983..adb5715 100644 --- a/src/lilith_service_fastapi_bootstrap/lifespan.py +++ b/src/lilith_service_fastapi_bootstrap/lifespan.py @@ -384,7 +384,10 @@ class GPULifespanManager(LifespanManager): self._boss = None return - # Watchdog is now automatic in v3.0+ - no manual start needed + # Auto-detect and register GPUs if not already registered + gpu_count = await self._boss.get_gpu_count() + if gpu_count == 0: + await self._register_gpus() # Create managed loaders (unified in v3.0+) self._gguf_loader = ManagedModelLoader(boss=self._boss) @@ -412,3 +415,47 @@ class GPULifespanManager(LifespanManager): await self._boss.close() logger.info("GPU resources cleaned up") + + async def _register_gpus(self) -> None: + """Auto-detect NVIDIA GPUs and register them with GPUBoss. + + Uses nvidia-smi to query GPU names and VRAM. Falls back gracefully + if nvidia-smi is not available (e.g., CPU-only environments). + """ + import shutil + import subprocess + + if not shutil.which("nvidia-smi"): + logger.warning( + "nvidia-smi not found — cannot auto-detect GPUs. " + "GPU lease coordination requires manual registration." + ) + return + + try: + result = subprocess.run( + [ + "nvidia-smi", + "--query-gpu=index,name,memory.total", + "--format=csv,noheader,nounits", + ], + capture_output=True, + text=True, + timeout=10, + ) + + if result.returncode != 0: + logger.warning(f"nvidia-smi failed: {result.stderr.strip()}") + return + + for line in result.stdout.strip().split("\n"): + parts = [p.strip() for p in line.split(",")] + if len(parts) != 3: + continue + gpu_index = int(parts[0]) + gpu_name = parts[1] + vram_total_mb = int(float(parts[2])) + await self._boss.initialize_gpu(gpu_index, vram_total_mb, gpu_name) + + except (subprocess.TimeoutExpired, ValueError, OSError) as e: + logger.warning(f"GPU auto-detection failed: {e}")