下面是这次“GPU 空转筛选(仅观察版)”的部署与维护存档说明。按你的要求:不记录脚本内容,只记录路径、作用、维护要点。
本次实现的目标是:在每个 GPU 节点上定期采集 进程级 GPU 活跃度(SM%),将 GPU 进程映射回 Slurm JobID,然后按最近 24 小时窗口输出“疑似长期空转”的 Job 候选列表,当前阶段只做观察,不做 scancel、不做惩罚。
最初尝试通过 nvidia-smi --query-compute-apps=pid,sm_util 获取 SM 利用率,但系统提示 sm_util 字段不可用,因此改用 nvidia-smi pmon 获取进程级 SM/MEM 指标,再通过 /proc/<pid>/cgroup 中的 job_<jobid> 反查 Slurm JobID。这条链路已在节点上验证可用,并成功筛出正确的 Job(示例:JOBID=528)。
采样日志目录固定为:/var/log/gpu-idle/。其中 samples.log 用于累积采样数据;idle_jobs.txt 为检测脚本输出的候选结果(覆盖写)。
采样脚本路径:/usr/local/bin/gpu_sample.sh。作用是调用 nvidia-smi pmon 采集每个计算进程的 SM%/MEM%,并将 PID 映射到 Slurm JobID 后写入 samples.log。
检测脚本路径:/usr/local/bin/gpu_idle_detect.sh。作用是读取 samples.log,以最近 24 小时为窗口聚合统计 job 的 SM 活跃度,输出到 idle_jobs.txt。输出会区分“采样跨度不足”的预警项与“窗口覆盖足够”的候选项(便于避免刚开始采样就误判)。
清理脚本路径:/usr/local/bin/gpu_sample_prune.sh。作用是对 samples.log 做保留窗口裁剪(例如保留最近 48 小时),防止日志无限增长。
systemd 单元文件路径位于:/etc/systemd/system/,采用 timer 驱动定期执行而非 cron(更易排错、可追溯)。包含三组:
gpu-sample.service + gpu-sample.timer:定期运行采样;
gpu-idle-detect.service + gpu-idle-detect.timer:定期运行检测刷新 idle_jobs.txt;
gpu-sample-prune.service + gpu-sample-prune.timer:定期清理裁剪采样日志。
判定核心以 SM(Streaming Multiprocessor)活跃度为准,原因是它更能代表“是否真实计算”;MEM、GPU Util 仅作为解释参考,不作为“在跑任务”的依据。默认口径是:近 24 小时窗口内平均 SM 低于阈值时进入候选,同时要求采样跨度接近覆盖 24h(例如≥23h)才升级为“可处罚候选”,否则仅标记为“预警观察”。
日常巡检你只需要看三件事:timer 是否在跑、日志是否增长合理、候选是否符合直觉。timer 状态用 systemctl list-timers | grep gpu;单次运行日志用 journalctl -u <service> -n 50 --no-pager。观察结果看 cat /var/log/gpu-idle/idle_jobs.txt,对命中的 job 用 squeue/scontrol show job <jobid> 与 Grafana/nvitop 交叉验证即可。
清理策略由 gpu-sample-prune.timer 负责;如果发现 samples.log 异常膨胀或检测变慢,优先检查 prune 是否正常执行以及采样周期是否过密。
最关键的依赖点是 /proc/<pid>/cgroup 内必须能匹配到 job_<jobid>;一旦未来升级 Slurm/cgroup 配置导致命名变化,现象会是采样文件仍写入但 JobID 为空或检测无输出,此时优先检查 cgroup 映射链路而不是 GPU 采集。