"""Carga (y cachea) un modelo GLiNER en el device deseado.""" from __future__ import annotations from typing import Any # Cache global: (model_name, device) -> modelo cargado. _MODEL_CACHE: dict[tuple[str, str], Any] = {} def _resolve_device(device: str) -> str: """Resuelve `device='auto'` a `cuda` o `cpu` segun disponibilidad.""" if device != "auto": return device try: import torch except ImportError: return "cpu" return "cuda" if torch.cuda.is_available() else "cpu" def gliner_load_model( model_name: str = "urchade/gliner_multi-v2.1", device: str = "auto", ) -> Any: """Carga un modelo GLiNER con cache por (model_name, device). La primera llamada descarga el modelo desde HuggingFace (~200 MB para `gliner_multi-v2.1`). Llamadas sucesivas con los mismos parametros devuelven la instancia cacheada. Args: model_name: ID del modelo en HuggingFace Hub. device: 'auto' usa CUDA si esta disponible, o 'cpu'/'cuda'/'cuda:N' de forma explicita. Returns: Instancia del modelo GLiNER lista para `predict_entities`. Raises: ImportError: si la dependencia `gliner` no esta instalada. Solucion: `uv pip install gliner` o instalar el extra `nlp` del proyecto (`uv pip install -e '.[nlp]'`). """ resolved_device = _resolve_device(device) cache_key = (model_name, resolved_device) cached = _MODEL_CACHE.get(cache_key) if cached is not None: return cached try: from gliner import GLiNER except ImportError as exc: raise ImportError( "gliner no esta instalado. Instalalo con " "`uv pip install gliner` o `uv pip install -e '.[nlp]'`." ) from exc model = GLiNER.from_pretrained(model_name) if hasattr(model, "to"): model.to(resolved_device) _MODEL_CACHE[cache_key] = model return model