Spaces:
Running
Running
stouchinglhh
Claude
sync processor from GitLab c697b6e: 版本 1.19.4 / 前端 1.12.4 —— 服务端 i18n(首屏不再闪英文)、推理模块并入模型页、前端抽出 shared/、缓存键改用前端号
bb59211 Download processor/app/training/gpus.py from Stouching-Robotics/DataFlowing: direct link, hf CLI and curl.
- Browser
- Download file 2.71 kB
-
https://huggingface.co/spaces/Stouching-Robotics/DataFlowing/resolve/main/processor/app/training/gpus.py
- Command line
-
hf download hf://spaces/Stouching-Robotics/DataFlowing/processor/app/training/gpus.py
-
curl -L -o gpus.py https://huggingface.co/spaces/Stouching-Robotics/DataFlowing/resolve/main/processor/app/training/gpus.py
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)} | |