Download code/bench/telemetry.py from ProprietaryLegal/dsv41-longctx-bench-tools: direct link, hf CLI and curl.
- Browser
- Download file 6.77 kB
-
https://huggingface.co/ProprietaryLegal/dsv41-longctx-bench-tools/resolve/main/code/bench/telemetry.py
- Command line
-
hf download hf://ProprietaryLegal/dsv41-longctx-bench-tools/code/bench/telemetry.py
-
curl -L -o telemetry.py https://huggingface.co/ProprietaryLegal/dsv41-longctx-bench-tools/resolve/main/code/bench/telemetry.py
6.77 kB
| """Read-only, bounded SSH telemetry; no CUDA contexts or service changes.""" | |
| from __future__ import annotations | |
| import json | |
| import shlex | |
| import subprocess | |
| import sys | |
| import threading | |
| import time | |
| import urllib.request | |
| from concurrent.futures import ThreadPoolExecutor | |
| from typing import TypeAlias, cast | |
| JSON: TypeAlias = dict[str, "JSON"] | list["JSON"] | str | int | float | bool | None | |
| Object: TypeAlias = dict[str, JSON] | |
| REMOTE = r''' | |
| import json, os, pathlib, re, subprocess, sys | |
| cfg=json.loads(sys.stdin.read()) | |
| out={"errors": []} | |
| mem={k:int(v) for k,v in re.findall(r'^(MemAvailable|SwapTotal|SwapFree):\s+(\d+)', pathlib.Path('/proc/meminfo').read_text(), re.M)} | |
| out['memory_kib']=mem | |
| out['swap_used_kib']=mem['SwapTotal']-mem['SwapFree'] | |
| query=['uuid','temperature.gpu','clocks.gr','power.draw','memory.used','utilization.gpu'] | |
| cmd=['nvidia-smi', '--query-gpu='+','.join(query), '--format=csv,noheader,nounits'] | |
| if cfg['x86host']: | |
| # Resolve the assigned UUID prefixes on each probe; never rely on ordinal indices. | |
| inv=subprocess.run(['nvidia-smi','--query-gpu=uuid','--format=csv,noheader'],capture_output=True,text=True) | |
| if inv.returncode: | |
| out['errors'].append('GPU inventory: '+inv.stderr) | |
| uuids=[] | |
| else: | |
| uuids=[u.strip() for u in inv.stdout.splitlines() if u.startswith(('GPU-DRAFTER0','GPU-DRAFTER1'))] | |
| if len(uuids)!=2: out['errors'].append('expected assigned GPU UUIDs, got '+str(uuids)) | |
| cmd+=['--id='+','.join(uuids)] if uuids else ['--id=missing-assigned-GPU'] | |
| r=subprocess.run(cmd,capture_output=True,text=True,timeout=3) | |
| if r.returncode: out['errors'].append('nvidia-smi: '+r.stderr) | |
| else: out['gpu_csv']=r.stdout.strip(); out['gpu_columns']=query | |
| if cfg['x86host']: | |
| out['processes']=[] | |
| for p in pathlib.Path('/proc').iterdir(): | |
| if not p.name.isdigit() or int(p.name)==os.getpid(): continue | |
| try: | |
| name=(p/'comm').read_text().strip() | |
| argv=(p/'cmdline').read_bytes().split(b'\0') | |
| executable=os.path.basename(argv[0].decode(errors='replace')) | |
| if name not in cfg['names'] and executable not in cfg['names']: continue | |
| stat=(p/'stat').read_text().rsplit(')',1)[1].split() | |
| out['processes'].append({'pid':int(p.name),'name':name,'start_ticks':int(stat[19]),'rss_bytes':int(stat[21])*os.sysconf('SC_PAGE_SIZE'),'major_faults':int(stat[9])}) | |
| except FileNotFoundError: pass # process exited during observation | |
| except PermissionError as e: out['errors'].append(str(e)) | |
| out['nics']={} | |
| for nic in cfg['nics']: | |
| r=subprocess.run(['ethtool','-S',nic],capture_output=True,text=True,timeout=3) | |
| if r.returncode: out['errors'].append('ethtool '+nic+': '+r.stderr); continue | |
| out['nics'][nic]={k:int(v) for k,v in re.findall(r'^\s+([\w]+):\s+(\d+)\s*$',r.stdout,re.M) if any(x in k.lower() for x in ('byte','retrans','error','discard','drop','retry'))} | |
| print(json.dumps(out)) | |
| ''' | |
| class Telemetry(threading.Thread): | |
| def __init__(self, sparks: list[str], x86host: str, names: list[str], extra: list[str], | |
| nics: list[str] | None = None) -> None: | |
| super().__init__(daemon=True) | |
| self.sparks, self.x86host, self.names, self.extra = sparks, x86host, names, extra | |
| self.nics = nics or ["enp130s0f0np0", "enp130s0f1np1"] | |
| self.stopped = threading.Event() | |
| self.samples: list[JSON] = [] | |
| self.errors: list[JSON] = [] | |
| self.previous_nics: dict[str, dict[str, int]] = {} | |
| def host_sample(self, host: str, x86host: bool) -> Object: | |
| command = "python3 -c " + shlex.quote(REMOTE) | |
| config = {"x86host": x86host, "names": self.names, "nics": self.nics} | |
| process = subprocess.run(["ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=3", host, command], | |
| input=json.dumps(config), capture_output=True, text=True, timeout=9, check=False) | |
| if process.returncode: | |
| raise RuntimeError(f"{host} telemetry exit {process.returncode}: {process.stderr.strip()}") | |
| result = cast(Object, json.loads(process.stdout)) | |
| if x86host: | |
| current = cast(dict[str, dict[str, int]], result.get("nics", {})) | |
| result["nic_delta"] = {nic: {key: value - self.previous_nics[nic][key] | |
| for key, value in counters.items() | |
| if key in self.previous_nics.get(nic, {})} | |
| for nic, counters in current.items()} | |
| self.previous_nics = current | |
| return result | |
| def sample(self) -> None: | |
| started = time.monotonic() | |
| row: Object = {"ts": time.time()} | |
| with ThreadPoolExecutor(max_workers=len(self.sparks) + 1) as pool: | |
| futures = {host: pool.submit(self.host_sample, host, False) for host in self.sparks} | |
| futures[self.x86host] = pool.submit(self.host_sample, self.x86host, True) | |
| for host, future in futures.items(): | |
| try: | |
| row[host] = future.result() | |
| result = cast(Object, row[host]) | |
| for error in cast(list[JSON], result.get("errors", [])): | |
| self.record_error(f"{host}: {error}") | |
| except Exception as exc: # noqa: BLE001 -- telemetry failures are printed and retained | |
| self.record_error(f"{host}: {type(exc).__name__}: {exc}") | |
| for url in self.extra: | |
| try: | |
| with urllib.request.urlopen(url, timeout=3) as response: | |
| row[url] = response.read().decode() | |
| except Exception as exc: # noqa: BLE001 -- telemetry failures are printed and retained | |
| self.record_error(f"{url}: {type(exc).__name__}: {exc}") | |
| row["sample_duration_s"] = time.monotonic() - started | |
| self.samples.append(row) | |
| def record_error(self, error: str) -> None: | |
| self.errors.append({"ts": time.time(), "error": error}) | |
| print(f"telemetry error: {error}", file=sys.stderr, flush=True) | |
| def run(self) -> None: | |
| while not self.stopped.is_set(): | |
| begin = time.monotonic() | |
| try: | |
| self.sample() | |
| except Exception as exc: # noqa: BLE001 -- telemetry failures are printed and retained | |
| self.record_error(f"sampler: {type(exc).__name__}: {exc}") | |
| self.stopped.wait(max(0, 2 - (time.monotonic() - begin))) | |
| def finish(self) -> None: | |
| self.stopped.set() | |
| self.join(timeout=30) | |
| if self.is_alive(): | |
| raise RuntimeError("telemetry sampler did not stop within 30 seconds") | |
| self.sample() # terminal counters cover the last sampling interval | |