PyTorch/CUDA 多GPU环境管理:从nvidia-smi到pynvml的5个高级脚本

📅 2026/7/5 1:42:05
PyTorch/CUDA 多GPU环境管理:从nvidia-smi到pynvml的5个高级脚本
PyTorch/CUDA 多GPU环境管理从nvidia-smi到pynvml的5个高级脚本在共享GPU集群的开发环境中高效管理多GPU资源往往比单纯的技术实现更具挑战性。当多个研究团队共用有限的GPU设备时开发者常面临三大痛点无法快速识别空闲GPU、难以监控长期任务的显存泄漏、以及僵尸进程导致的资源死锁。传统解决方案依赖人工执行nvidia-smi命令这种被动响应模式在复杂场景下显得力不从心。1. 智能GPU选择器动态分配空闲设备常规的CUDA_VISIBLE_DEVICES指定方式存在明显局限——它要求开发者预先知道哪些GPU可用。我们开发的自适应选择脚本能实时分析设备状态自动分配符合计算需求的GPU资源。import pynvml import torch def select_idle_gpu(min_memory1024, max_retry3): pynvml.nvmlInit() for _ in range(max_retry): available_gpus [] for i in range(pynvml.nvmlDeviceGetCount()): handle pynvml.nvmlDeviceGetHandleByIndex(i) mem_info pynvml.nvmlDeviceGetMemoryInfo(handle) util pynvml.nvmlDeviceGetUtilizationRates(handle) if mem_info.free/1024**2 min_memory and util.gpu 50: available_gpus.append(str(i)) if available_gpus: torch.cuda.set_device(int(available_gpus[0])) return fCUDA_VISIBLE_DEVICES{,.join(available_gpus)} raise RuntimeError(No available GPU meets the criteria) # 使用示例 os.environ.update(eval(select_idle_gpu(min_memory2048)))该脚本实现了三个关键功能动态阈值筛选同时考虑显存余量默认1GB和GPU利用率50%优先级策略返回满足条件的首个设备避免随机选择的不确定性异常重试机制在竞争激烈的环境中自动进行多次尝试提示将min_memory参数设置为模型预估显存占用的1.2倍可有效防止内存不足错误2. 显存监控器实时追踪进程内存变化长期运行的训练任务可能出现显存缓慢增长的问题。以下脚本以1秒间隔记录指定进程的显存变化帮助开发者定位内存泄漏。import time from collections import deque def monitor_gpu_memory(pid, duration3600, interval1): pynvml.nvmlInit() history deque(maxlenduration//interval) try: while True: current_mem 0 for i in range(pynvml.nvmlDeviceGetCount()): handle pynvml.nvmlDeviceGetHandleByIndex(i) procs pynvml.nvmlDeviceGetComputeRunningProcesses(handle) for p in procs: if p.pid pid: current_mem p.usedGpuMemory/1024**2 timestamp time.strftime(%Y-%m-%d %H:%M:%S) history.append((timestamp, current_mem)) print(f[{timestamp}] PID {pid} using {current_mem:.2f}MB) if len(history) 1 and current_mem - history[0][1] 500: print(fWarning: Memory increased by {current_mem-history[0][1]:.2f}MB) time.sleep(interval) except KeyboardInterrupt: return list(history)该监控器具有以下特点功能实现方式典型应用场景多GPU聚合累加进程在所有设备上的显存使用分布式训练监控趋势预警滑动窗口比较内存变化量早期发现内存泄漏时间戳记录标准化时间格式输出与日志系统集成3. GPU压力测试工具模拟高负载场景在部署新模型前需要验证GPU在极端条件下的稳定性。下面的脚本可以模拟不同级别的显存和计算负载def gpu_stress_test(device_index, mem_percent0.8, duration60): device torch.device(fcuda:{device_index}) total_mem torch.cuda.get_device_properties(device).total_memory block_size int(total_mem * mem_percent / 10) # 创建内存压力 blocks [] try: for i in range(10): blocks.append(torch.randn(block_size, devicedevice)) # 创建计算压力 start time.time() while time.time() - start duration: x torch.randn(10000, 10000, devicedevice) torch.mm(x, x.t()) finally: del blocks torch.cuda.empty_cache()参数调节建议mem_percent0.5-0.9模拟不同内存占用率duration测试持续时间秒block_size将内存分配拆分为多个块避免单次分配失败4. 僵尸进程清理工具被异常终止的PyTorch进程可能继续占用GPU资源。以下脚本自动识别并清理这些僵尸def clean_zombie_processes(): pynvml.nvmlInit() zombie_found False for i in range(pynvml.nvmlDeviceGetCount()): handle pynvml.nvmlDeviceGetHandleByIndex(i) procs pynvml.nvmlDeviceGetComputeRunningProcesses(handle) for p in procs: try: os.kill(p.pid, 0) except OSError: print(fKilling zombie process {p.pid} on GPU {i}) os.kill(p.pid, 9) zombie_found True if not zombie_found: print(No zombie processes detected) return zombie_found清理策略说明遍历所有GPU设备上运行的进程尝试向进程发送信号0无操作检测存活状态对无响应的进程发送SIGKILL(9)返回是否发现僵尸进程的布尔值5. GPU使用报告生成器定期生成资源使用报告有助于优化集群调度策略。这个脚本生成包含关键指标的HTML报告def generate_gpu_report(output_filegpu_report.html): pynvml.nvmlInit() timestamp time.strftime(%Y-%m-%d %H:%M:%S) gpu_data [] for i in range(pynvml.nvmlDeviceGetCount()): handle pynvml.nvmlDeviceGetHandleByIndex(i) name pynvml.nvmlDeviceGetName(handle) mem_info pynvml.nvmlDeviceGetMemoryInfo(handle) util pynvml.nvmlDeviceGetUtilizationRates(handle) temp pynvml.nvmlDeviceGetTemperature(handle, pynvml.NVML_TEMPERATURE_GPU) gpu_data.append({ index: i, name: name.decode(), mem_used: mem_info.used/1024**3, mem_total: mem_info.total/1024**3, util_gpu: util.gpu, util_mem: util.memory, temp: temp }) # 生成HTML报告 html fhtmlheadtitleGPU Report {timestamp}/title styletable {{border-collapse: collapse;}} td, th {{border: 1px solid #ddd; padding: 8px;}}/style/head bodyh1GPU Utilization Report/h1pGenerated at {timestamp}/p tabletrthGPU/ththName/ththMem Used/ththUtil %/ththTemp °C/th/tr for gpu in gpu_data: mem_pct gpu[mem_used] / gpu[mem_total] * 100 html ftrtd{gpu[index]}/tdtd{gpu[name]}/td td{gpu[mem_used]:.1f}G/{gpu[mem_total]:.1f}G ({mem_pct:.1f}%)/td tdGPU: {gpu[util_gpu]}% | Mem: {gpu[util_mem]}%/td td{gpu[temp]}/td/tr html /table/body/html with open(output_file, w) as f: f.write(html) return output_file报告包含的关键指标设备基本信息GPU索引、型号名称内存使用已用/总量GB及百分比利用率计算单元和显存带宽使用率温度监控当前GPU核心温度在实际项目中这些脚本通常需要根据具体环境进行调整。例如在Kubernetes集群中运行时需要额外考虑容器化环境下的进程隔离特性。一个实用的经验是将选择器和监控器集成到训练脚本的初始化阶段形成资源管理的闭环方案。