Download tools/runmem.py from HelloSun/fint-epqv2: direct link, hf CLI and curl.
- Browser
- Download file 2.73 kB
-
https://huggingface.co/HelloSun/fint-epqv2/resolve/main/tools/runmem.py
- Command line
-
hf download hf://HelloSun/fint-epqv2/tools/runmem.py
-
curl -L -o runmem.py https://huggingface.co/HelloSun/fint-epqv2/resolve/main/tools/runmem.py
2.73 kB
| #!/usr/bin/env python3 | |
| """Sample process-tree RSS/swap while running a command.""" | |
| import argparse | |
| import json | |
| import signal | |
| import subprocess | |
| import sys | |
| import time | |
| def process_tree(root): | |
| output = subprocess.check_output(["ps", "-e", "-o", "pid=,ppid="], text=True) | |
| children = {} | |
| for line in output.splitlines(): | |
| pid, ppid = map(int, line.split()) | |
| children.setdefault(ppid, []).append(pid) | |
| result, todo = [], [root] | |
| while todo: | |
| pid = todo.pop() | |
| result.append(pid) | |
| todo.extend(children.get(pid, ())) | |
| return result | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--interval", type=float, default=0.25) | |
| parser.add_argument("--timeout", type=float, default=7200) | |
| parser.add_argument("--rss-limit-gib", type=float) | |
| parser.add_argument("command", nargs=argparse.REMAINDER) | |
| args = parser.parse_args() | |
| command = args.command[1:] if args.command[:1] == ["--"] else args.command | |
| if not command: | |
| parser.error("missing command") | |
| started = time.monotonic() | |
| process = subprocess.Popen(command) | |
| peak_rss = peak_swap = 0 | |
| exceeded = False | |
| while process.poll() is None: | |
| rss = swap = 0 | |
| for pid in process_tree(process.pid): | |
| try: | |
| with open(f"/proc/{pid}/status", encoding="ascii") as status: | |
| for line in status: | |
| if line.startswith("VmRSS:"): | |
| rss += int(line.split()[1]) | |
| elif line.startswith("VmSwap:"): | |
| swap += int(line.split()[1]) | |
| except (FileNotFoundError, ProcessLookupError): | |
| pass | |
| peak_rss = max(peak_rss, rss) | |
| peak_swap = max(peak_swap, swap) | |
| # VmRSS 以 kB 為單位,門檻須換算成 kB(1 GiB = 1024 * 1024 kB) | |
| if args.rss_limit_gib is not None and rss > args.rss_limit_gib * (1024 ** 2): | |
| exceeded = True | |
| process.send_signal(signal.SIGKILL) | |
| break | |
| if time.monotonic() - started > args.timeout: | |
| process.kill() | |
| break | |
| time.sleep(args.interval) | |
| result = process.wait() | |
| print("RUNMEM " + json.dumps({ | |
| "peak_kb": peak_rss, | |
| "peak_gib": round(peak_rss / 1048576, 3), | |
| "limit_gib": args.rss_limit_gib, | |
| "limit_exceeded": exceeded, | |
| "swap_kb": peak_swap, | |
| "wall_s": round(time.monotonic() - started, 2), | |
| "exit": result, | |
| "cmd": command, | |
| "method": "procfs-rss-watchdog", | |
| })) | |
| return 0 if args.rss_limit_gib is None else (1 if exceeded else result) | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |