Дашборд: карточка загрузки GPU (util/Вт/°C из results/gpustat.json)
Веб в Docker без nvidia-smi: хост-сервис gausse-gpustat пишет JSON рядом с базой, /api/overview отдаёт поле gpu (протухшее >30с — честно null). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,7 @@ PAGE_HTML = r"""<!doctype html>
|
||||
<div class="card"><div class="k">Нереализуемо</div><div class="v" id="c-infeas">—</div></div>
|
||||
<div class="card"><div class="k">Доля реализуемых</div><div class="v" id="c-pct">—</div></div>
|
||||
<div class="card"><div class="k">Лучший КПД / скорость</div><div class="v" id="c-best" style="font-size:20px">—</div></div>
|
||||
<div class="card"><div class="k">GPU (GTX 1070)</div><div class="v" id="c-gpu" style="font-size:20px">—</div></div>
|
||||
</div>
|
||||
|
||||
<div class="grid2">
|
||||
@@ -131,6 +132,10 @@ async function refresh(){
|
||||
let best = (o.top && o.top.length) ? o.top[0].efficiency : null;
|
||||
let bestV = (o.top_by_velocity && o.top_by_velocity.length) ? o.top_by_velocity[0].exit_velocity_mps : null;
|
||||
document.getElementById('c-best').textContent = fmtPct(best) + (bestV!=null ? ' / '+fmt(bestV,0)+' м/с' : '');
|
||||
const g = o.gpu;
|
||||
document.getElementById('c-gpu').textContent = g
|
||||
? `${g.util_pct}% · ${fmt(g.power_w,0)}Вт · ${g.temp_c}°C`
|
||||
: 'нет данных';
|
||||
renderTop(o);
|
||||
|
||||
const hist=document.getElementById('hist'); hist.innerHTML='';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""Агрегаты по таблице `runs` для веб-морды — считаются запросами к SQLite."""
|
||||
|
||||
import json
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
from gausse.storage.database import fetch_run_by_id, fetch_runs, open_connection
|
||||
@@ -13,6 +14,23 @@ def _tail_log(log_path: Path, n_lines: int = 40) -> list[str]:
|
||||
return lines[-n_lines:]
|
||||
|
||||
|
||||
def _gpu_stat(db_path: Path) -> dict | None:
|
||||
"""Загрузка GPU из gpustat.json рядом с базой (пишет gausse-gpustat на хосте).
|
||||
|
||||
Веб живёт в Docker без доступа к nvidia-smi, поэтому хост-сервис раз в
|
||||
несколько секунд кладёт JSON в каталог результатов. Протухшие данные
|
||||
(>30с — писатель умер/GPU нет) честно не показываем.
|
||||
"""
|
||||
p = db_path.parent / "gpustat.json"
|
||||
try:
|
||||
stat = json.loads(p.read_text(encoding="utf-8"))
|
||||
if time.time() - float(stat.get("ts", 0)) > 30:
|
||||
return None
|
||||
return stat
|
||||
except (OSError, ValueError):
|
||||
return None
|
||||
|
||||
|
||||
def overview(db_path: Path, log_path: Path | None = None, top_n: int = 15) -> dict:
|
||||
"""Сводка для дашборда: счётчики, гистограмма КПД, топ конфигураций, хвост лога."""
|
||||
conn = open_connection(db_path)
|
||||
@@ -71,6 +89,7 @@ def overview(db_path: Path, log_path: Path | None = None, top_n: int = 15) -> di
|
||||
"top": top,
|
||||
"top_by_velocity": top_by_velocity,
|
||||
"log_tail": _tail_log(log_path, 40) if log_path else [],
|
||||
"gpu": _gpu_stat(db_path),
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user