Download hf_space/runtime.py from gexinh/SlideBank: direct link, hf CLI and curl.
- Browser
- Download file 3.85 kB
-
https://huggingface.co/spaces/gexinh/SlideBank/resolve/main/hf_space/runtime.py
- Command line
-
hf download hf://spaces/gexinh/SlideBank/hf_space/runtime.py
-
curl -L -o runtime.py https://huggingface.co/spaces/gexinh/SlideBank/resolve/main/hf_space/runtime.py
3.85 kB
| """ZeroGPU allocation around the complete, unchanged V5 answer flow. | |
| Importing this module never downloads a model or initializes CUDA. CPU Spaces | |
| retain evidence browsing, and cannot fall through to local CPU inference. | |
| """ | |
| from __future__ import annotations | |
| import os | |
| from typing import Any, Dict | |
| def _enabled(value: str) -> bool: | |
| return str(value).strip().lower() in {"1", "true", "yes"} | |
| HOSTED_MODE = _enabled(os.environ.get("SLIDEBANK_HOSTED", "")) | |
| GPU_DURATION = max(15, min(120, int(os.environ.get("SLIDEBANK_GPU_DURATION", "60")))) | |
| _spaces = None | |
| _sdk_error = "" | |
| _model_error = "" | |
| if _enabled(os.environ.get("SPACES_ZERO_GPU", "")): | |
| try: | |
| import spaces as _spaces | |
| from spaces.config import Config as _SpacesConfig | |
| if not _SpacesConfig.zero_gpu: | |
| _sdk_error = "The Spaces SDK has not enabled ZeroGPU." | |
| except Exception as exc: | |
| _sdk_error = f"The ZeroGPU SDK could not start ({type(exc).__name__})." | |
| def availability_error() -> str: | |
| if not _enabled(os.environ.get("SPACES_ZERO_GPU", "")): | |
| return "Live QA requires ZeroGPU. Evidence browsing remains available on CPU." | |
| if _sdk_error: | |
| return _sdk_error + " Evidence browsing remains available." | |
| if _spaces is None: | |
| return "The Spaces SDK is unavailable. Evidence browsing remains available." | |
| if _model_error: | |
| return _model_error | |
| return "" | |
| def hosted_runtime(defaults: Dict[str, Any]) -> Dict[str, Any]: | |
| """Server-owned model selection; visitors cannot choose an API or endpoint.""" | |
| cfg = defaults.get("vlm", {}) | |
| return { | |
| "hosted": True, | |
| "model_backend": "Local Model", | |
| "local_model": str(cfg.get("model_path", "Qwen/Qwen2.5-VL-3B-Instruct")), | |
| "api_provider": "", | |
| "api_model": "", | |
| "custom_api_model": "", | |
| "api_key": "", | |
| "api_base_url": "", | |
| } | |
| def prepare_hosted_model(defaults: Dict[str, Any]) -> bool: | |
| """Explicit launcher startup phase using ZeroGPU's CUDA emulation. | |
| This is never called during module import, and returns without importing a | |
| model library on CPU hardware. Preloading lets the SDK preserve CUDA state | |
| for its GPU workers instead of loading weights inside every allocation. | |
| """ | |
| global _model_error | |
| if availability_error(): | |
| return False | |
| try: | |
| from slidebank.interactive_agent import get_vlm_client, make_vlm_config | |
| config = make_vlm_config(hosted_runtime(defaults), defaults) | |
| get_vlm_client(config).load() | |
| print(f"Hosted demonstration model ready: {config.model_path}", flush=True) | |
| return True | |
| except Exception as exc: | |
| _model_error = "The hosted model could not be prepared. Evidence browsing remains available." | |
| print(f"Hosted model preparation failed: {type(exc).__name__}: {exc}", flush=True) | |
| return False | |
| def _answer_on_gpu(*, message, bank, runtime, defaults, previous_messages): | |
| unavailable = availability_error() | |
| if unavailable: | |
| raise RuntimeError(unavailable) | |
| # This check runs after GPU allocation, never during CPU startup. | |
| import torch | |
| if not torch.cuda.is_available(): | |
| raise RuntimeError("ZeroGPU did not allocate CUDA. Please retry when GPU capacity is available.") | |
| from slidebank.agent_inference_v5 import answer_question_v5 | |
| return answer_question_v5( | |
| message=message, | |
| bank=bank, | |
| runtime=runtime, | |
| defaults=defaults, | |
| previous_messages=previous_messages, | |
| ) | |
| # The SDK decorator is otherwise a no-op on cpu-basic; an explicit availability | |
| # gate prevents that no-op from accidentally running a multi-billion model on CPU. | |
| answer_on_gpu = ( | |
| _spaces.GPU(duration=GPU_DURATION)(_answer_on_gpu) | |
| if _spaces is not None and not _sdk_error | |
| else _answer_on_gpu | |
| ) | |