Mine / cpu_backend.py
Erinaldordso's picture
Atualiza cpu_backend.py
584fcab verified
Raw History Blame Contribute Delete
3.36 kB
"""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']}"
)