stouchinglhh
Claude
sync processor from GitLab c697b6e: 版本 1.19.4 / 前端 1.12.4 —— 服务端 i18n(首屏不再闪英文)、推理模块并入模型页、前端抽出 shared/、缓存键改用前端号
bb59211
Raw History Blame Contribute Delete
2.71 kB
"""本机 GPU 读取 —— 直接问 ``nvidia-smi``。
这一层**不认识 HTTP**:它返回普通 dict,由 ``app/routes/training.py`` 直接
交给 FastAPI 序列化。所以它可以被将来任何地方复用(比如训练 runner 起子进程
前先确认显卡可用),而不必绕道走一遍路由。
"""
from __future__ import annotations
import shutil
import subprocess
# nvidia-smi 的查询字段 —— 顺序即解析顺序,改这里必须同步改 _parse 的索引。
_QUERY = "index,name,memory.used,memory.total,utilization.gpu,temperature.gpu"
def _parse(stdout: str) -> list[dict]:
gpus: list[dict] = []
for line in stdout.strip().splitlines():
parts = [p.strip() for p in line.split(",")]
if len(parts) < 6:
continue
try:
gpus.append({
"index": int(parts[0]),
"name": parts[1],
"memory_used_mb": int(float(parts[2])),
"memory_total_mb": int(float(parts[3])),
"utilization": int(float(parts[4])),
"temperature": int(float(parts[5])),
})
except ValueError:
continue # 单卡读不出来不该让整张列表失败
return gpus
def list_gpus() -> dict:
"""``{"available": bool, "error": str, "gpus": [...]}``。
**驱动没起来时如实报错,不要返回一排 0。** 实测这台机器上 ``nvidia-smi``
会以 "couldn't communicate with the NVIDIA driver" 失败;若把它当成
"利用率 0%、显存 0" 渲染出去,看起来是"显卡闲着可以训",而真相是"根本
问不到显卡"。前端据此显示明确的错误条 —— `available` 这个字段存在的唯一
理由就是让调用方**必须**区分这两种情况。
"""
nvidia_smi = shutil.which("nvidia-smi")
if not nvidia_smi:
return {"available": False, "error": "nvidia-smi not found", "gpus": []}
try:
proc = subprocess.run(
[nvidia_smi, f"--query-gpu={_QUERY}", "--format=csv,noheader,nounits"],
capture_output=True, text=True, timeout=10, check=False,
)
except (OSError, subprocess.SubprocessError) as exc:
return {"available": False, "error": str(exc), "gpus": []}
if proc.returncode != 0:
# 驱动没起来走的就是这条 —— nvidia-smi 把原因写在 stderr。
lines = (proc.stderr or proc.stdout or "").strip().splitlines()
return {
"available": False,
"error": lines[0] if lines else f"nvidia-smi exited {proc.returncode}",
"gpus": [],
}
return {"available": True, "error": "", "gpus": _parse(proc.stdout)}