From d3ab3fa460fbd14a98d8f887c277023820938350 Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Wed, 25 Feb 2026 21:58:28 -0800 Subject: [PATCH] fix: GPU detection + pdfplumber + pass GPU env vars into app container - preflight.py now writes PEREGRINE_GPU_COUNT and PEREGRINE_GPU_NAMES to .env so the app container gets GPU info without needing nvidia-smi access - compose.yml passes PEREGRINE_GPU_COUNT, PEREGRINE_GPU_NAMES, and RECOMMENDED_PROFILE as env vars to the app service - 0_Setup.py _detect_gpus() reads PEREGRINE_GPU_NAMES env var first; falls back to nvidia-smi (bare / GPU-passthrough environments) - 0_Setup.py _suggest_profile() reads RECOMMENDED_PROFILE env var first - requirements.txt: add pdfplumber (needed for resume PDF parsing) --- app/pages/0_Setup.py | 13 +++++++++++++ compose.yml | 3 +++ requirements.txt | 1 + scripts/preflight.py | 3 +++ 4 files changed, 20 insertions(+) diff --git a/app/pages/0_Setup.py b/app/pages/0_Setup.py index 637c468..a31bf4b 100644 --- a/app/pages/0_Setup.py +++ b/app/pages/0_Setup.py @@ -40,7 +40,15 @@ def _save_yaml(updates: dict) -> None: def _detect_gpus() -> list[str]: + """Detect GPUs. Prefers env vars written by preflight (works inside Docker).""" + import os import subprocess + # Preflight writes PEREGRINE_GPU_NAMES to .env; compose passes it to the container. + # This is the reliable path when running inside Docker without nvidia-smi access. + env_names = os.environ.get("PEREGRINE_GPU_NAMES", "").strip() + if env_names: + return [n.strip() for n in env_names.split(",") if n.strip()] + # Fallback: try nvidia-smi directly (works when running bare or with GPU passthrough) try: out = subprocess.check_output( ["nvidia-smi", "--query-gpu=name", "--format=csv,noheader"], @@ -52,6 +60,11 @@ def _detect_gpus() -> list[str]: def _suggest_profile(gpus: list[str]) -> str: + import os + # If preflight already ran and wrote a profile recommendation, use it. + recommended = os.environ.get("RECOMMENDED_PROFILE", "").strip() + if recommended: + return recommended if len(gpus) >= 2: return "dual-gpu" if len(gpus) == 1: diff --git a/compose.yml b/compose.yml index d2b7b08..b262cdb 100644 --- a/compose.yml +++ b/compose.yml @@ -16,6 +16,9 @@ services: - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} - OPENAI_COMPAT_URL=${OPENAI_COMPAT_URL:-} - OPENAI_COMPAT_KEY=${OPENAI_COMPAT_KEY:-} + - PEREGRINE_GPU_COUNT=${PEREGRINE_GPU_COUNT:-0} + - PEREGRINE_GPU_NAMES=${PEREGRINE_GPU_NAMES:-} + - RECOMMENDED_PROFILE=${RECOMMENDED_PROFILE:-remote} depends_on: searxng: condition: service_healthy diff --git a/requirements.txt b/requirements.txt index 30b7078..cbb703f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -45,6 +45,7 @@ notion-client>=3.0 # ── Document handling ───────────────────────────────────────────────────── pypdf pdfminer-six +pdfplumber pyyaml>=6.0 python-dotenv diff --git a/scripts/preflight.py b/scripts/preflight.py index 7687474..08c5dc7 100644 --- a/scripts/preflight.py +++ b/scripts/preflight.py @@ -423,6 +423,9 @@ def main() -> None: env_updates["RECOMMENDED_PROFILE"] = profile if offload_gb > 0: env_updates["CPU_OFFLOAD_GB"] = str(offload_gb) + # GPU info for the app container (which lacks nvidia-smi access) + env_updates["PEREGRINE_GPU_COUNT"] = str(len(gpus)) + env_updates["PEREGRINE_GPU_NAMES"] = ",".join(g["name"] for g in gpus) write_env(env_updates) update_llm_yaml(ports) write_compose_override(ports)