"""Prova de que este processo roda em CPU, em vez de um rótulo que afirma isso. Portado do Space original com uma correção: lá o `cpu_only` era um booleano derivado de uma checagem de filesystem. Aqui ele é derivado da mesma checagem, mas o relatório também é emitido no boot, antes de qualquer requisição, para que um deploy mal configurado apareça no log em vez de só no /status. IMPORTANTE — por que a consulta binária é opt-in ------------------------------------------------- `llama_cpp.llama_supports_gpu_offload()` NÃO pode ser chamada antes de `llama_backend_init()`. Medido no projeto original: chamar primeiro levanta `OSError [WinError -1073741795]`, que é NTSTATUS 0xC000001D STATUS_ILLEGAL_INSTRUCTION — a chamada executa código que a CPU não consegue executar antes do backend estar registrado. No Linux o equivalente é SIGILL, que mata o processo e não pode ser capturado por try/except. A listagem de bibliotecas abaixo não precisa de chamada nativa e já basta: se o wheel não traz backend CUDA/Vulkan/Metal/ROCm, ele estruturalmente não consegue descarregar camada nenhuma. """ from __future__ import annotations import os from pathlib import Path REQUIRED_OFFLOAD_ARGUMENTS = { "n_gpu_layers": 0, "offload_kqv": False, } GPU_LIBRARY_TOKENS = ("cuda", "cublas", "vulkan", "metal", "hip", "rocm") LIBRARY_SUFFIXES = (".so", ".dll", ".dylib") BINARY_PROBE_ENABLED = os.environ.get("LLAMA_BINARY_PROBE", "0") == "1" def backend_libraries() -> list[str]: """Nomes das bibliotecas nativas realmente publicadas com o llama_cpp.""" try: import llama_cpp except ImportError: return [] base = Path(llama_cpp.__file__).resolve().parent return sorted( path.name for path in base.rglob("*") if path.is_file() and path.suffix.lower() in LIBRARY_SUFFIXES ) def binary_offload_support(): """Pergunta ao binário se ele sabe descarregar. Arriscado antes do init.""" try: from llama_cpp import llama_cpp as _backend return bool(_backend.llama_supports_gpu_offload()) except BaseException as exc: # noqa: BLE001 - uma sonda não pode derrubar o processo return f"unavailable: {type(exc).__name__}" def cpu_only_report(probe_binary: bool | None = None) -> dict: if probe_binary is None: probe_binary = BINARY_PROBE_ENABLED libraries = backend_libraries() cuda_libraries = sorted( name for name in libraries if any(token in name.lower() for token in GPU_LIBRARY_TOKENS) ) report = { "gpu_offload_supported": binary_offload_support() if probe_binary else "not probed", "gpu_binary_probe_enabled": probe_binary, "gpu_backend_libraries": libraries, "cuda_libraries_present": cuda_libraries, "n_gpu_layers_requested": REQUIRED_OFFLOAD_ARGUMENTS["n_gpu_layers"], } report["cpu_only"] = ( not cuda_libraries and report["n_gpu_layers_requested"] == 0 ) return report def cpu_only_summary(report: dict) -> str: return ( f"cpu_only={report['cpu_only']} " f"gpu_libs={report['gpu_backend_libraries']} " f"cuda_libs={report['cuda_libraries_present'] or 'none'} " f"n_gpu_layers={report['n_gpu_layers_requested']} " f"binary_probe={report['gpu_offload_supported']}" )