fix(monitor): CPU 占用读数改为后台每秒独立采样(此前在请求里算差值,网页 1 秒轮询会把窗口压成几毫秒 → 恒为 0);CPU 并进 GPU 同一个卡(上 GPU 环+显存/温度/功耗,下 CPU 环+28 核逐核条)

实测:空闲 16.8% → 14 个满载循环 71.7% → 结束 19.1%,随负载单调;截图复核合并卡排版正常。
This commit is contained in:
cbb
2026-10-18 15:13:37 +08:00
parent 9ed213417b
commit 83dcc1c3ee
2 changed files with 38 additions and 32 deletions
+20 -12
View File
@@ -68,21 +68,28 @@ def read_log(name, offset):
return {'records': recs, 'offset': offset + end, 'size': size, 'reset': offset == 0, 'mtime': os.path.getmtime(f)}
_CPU_CACHE = {'t': 0.0, 'v': {}}
_CPU = {'v': {}}
class CpuSampler(threading.Thread):
"""后台每秒阻塞采样一次 CPU。cpu_percent 是"距上次调用"的差值:放在请求里算,窗口取决于两次
HTTP 请求的间隔(网页 1 秒轮询 + 手动 curl 会把它压成几毫秒,读数恒为 0)——所以单独一个线程按固定
1 秒窗口取,status 只读最近一次。"""
def __init__(self): super().__init__(daemon=True); self.start()
def run(self):
try:
import psutil
psutil.cpu_percent(interval=None, percpu=True) # 打桩:第一次恒为 0,丢掉
while True:
per = psutil.cpu_percent(interval=1.0, percpu=True)
_CPU['v'] = {'total': round(sum(per) / max(1, len(per)), 1), 'per': [round(x) for x in per], 'n': len(per)}
except Exception:
_CPU['v'] = {}
def cpu():
"""CPU 占用:总百分比 + 每核(psutil 已装;没装就返回空,页面不显示这块)。"""
if time.time() - _CPU_CACHE['t'] < 1.0: return _CPU_CACHE['v']
try:
import psutil
per = psutil.cpu_percent(interval=None, percpu=True)
out = {'total': round(sum(per) / max(1, len(per)), 1), 'per': [round(x, 0) for x in per], 'n': len(per),
'load1': round(os.getloadavg()[0], 2) if hasattr(os, 'getloadavg') else None}
except Exception:
out = {}
_CPU_CACHE.update(t=time.time(), v=out)
return out
return _CPU['v']
_GPU_CACHE = {'t': 0.0, 'v': []}
@@ -465,6 +472,7 @@ def main():
a = ap.parse_args()
global CHECK
CHECK = SelfCheck()
CPUS = CpuSampler() # 每秒采一次 CPU(线程常驻,status 只读最近一次)
srv = ThreadingHTTPServer((a.host, a.port), H); srv.remote_control = a.remote_control
url = f'http://localhost:{a.port}/'
print(f'训练控制台:{url} (关闭本窗口只关控制台,已开始的训练继续跑;重新打开控制台即可接着看、可停止)', flush=True)