Spaces:
Paused
Paused
| from __future__ import annotations | |
| import gc | |
| import time | |
| from collections import OrderedDict | |
| from contextlib import contextmanager | |
| from threading import RLock | |
| from typing import Any, Callable, Iterator | |
| class ModelRuntimeManager: | |
| """Lazy, bounded runtime for a single accelerator or CPU-only deployment.""" | |
| def __init__(self, max_resident: int = 2, device: str = "auto") -> None: | |
| self.max_resident = max(1, int(max_resident)) | |
| self.device = self._select_device(device) | |
| self._models: OrderedDict[str, Any] = OrderedDict() | |
| self._health: dict[str, dict[str, Any]] = {} | |
| self._lock = RLock() | |
| def _select_device(requested: str) -> str: | |
| if requested not in {"auto", "cuda", "cpu"}: | |
| raise ValueError(f"Unsupported device: {requested}") | |
| if requested == "cpu": | |
| return "cpu" | |
| try: | |
| import torch | |
| return "cuda" if torch.cuda.is_available() else "cpu" | |
| except ImportError: | |
| return "cpu" | |
| def acquire(self, model_id: str, loader: Callable[[], Any]) -> Iterator[Any]: | |
| started = time.perf_counter() | |
| with self._lock: | |
| try: | |
| if model_id not in self._models: | |
| while len(self._models) >= self.max_resident: | |
| oldest, _ = self._models.popitem(last=False) | |
| self._health.setdefault(oldest, {})["resident"] = False | |
| self._cleanup_device() | |
| self._models[model_id] = loader() | |
| self._models.move_to_end(model_id) | |
| self._health[model_id] = { | |
| "status": "READY", | |
| "resident": True, | |
| "device": self.device, | |
| "load_ms": round((time.perf_counter() - started) * 1000, 2), | |
| } | |
| yield self._models[model_id] | |
| except Exception as exc: | |
| self._models.pop(model_id, None) | |
| self._health[model_id] = {"status": "LOAD_FAILED", "resident": False, "reason": str(exc)} | |
| self._cleanup_device() | |
| raise | |
| def unload(self, model_id: str) -> None: | |
| with self._lock: | |
| self._models.pop(model_id, None) | |
| self._health.setdefault(model_id, {})["resident"] = False | |
| self._cleanup_device() | |
| def _cleanup_device() -> None: | |
| gc.collect() | |
| try: | |
| import torch | |
| if torch.cuda.is_available(): | |
| torch.cuda.empty_cache() | |
| except ImportError: | |
| pass | |
| def snapshot(self) -> dict[str, Any]: | |
| allocated = 0 | |
| try: | |
| import torch | |
| if torch.cuda.is_available(): | |
| allocated = int(torch.cuda.memory_allocated()) | |
| except ImportError: | |
| pass | |
| return { | |
| "device": self.device, | |
| "max_resident": self.max_resident, | |
| "resident_models": list(self._models), | |
| "allocated_vram_bytes": allocated, | |
| "models": dict(self._health), | |
| } | |