服务器脚本——等待显卡可用炼丹
subprocess
模块
subprocess模块概述
subprocess
模块是Python标准库的一部分,它为创建和管理子进程提供了强大的接口。在Python 2.4中引入以取代旧的模块(如os.system
和os.spawn*
等),并提供了更复杂的进程管理功能,比如超时控制、I/O管道通信等
subprocess.check_output
1
| result = subprocess.check_output(['nvidia-smi', '--query-gpu=utilization.gpu', '--format=csv,noheader,nounits'])
|
subprocess.check_output
:
- 这是
subprocess
模块中的一个函数,用于执行一个 shell 命令并捕获其输出。
- 它会等待命令执行完毕,并返回命令的标准输出作为字节串
- 命令参数:
nvidia-smi
: 这是一个用于查询 NVIDIA GPU 信息的工具
--query-gpu=utilization.gpu
: 这个选项告诉 nvidia-smi
只查询 GPU 的利用率。这里的 utilization.gpu
指的是 GPU 的利用率,即 GPU 的活跃程度
--format=csv,noheader,nounits
: 这个选项设置了输出格式。csv
表示输出为逗号分隔的值格式,noheader
表示输出中不包含表头,nounits
表示输出中不包含单位信息
result
变量:
result
是一个字节串,包含从 nvidia-smi
命令获取的 GPU 使用率信息
subprocess.check_output
1
| subprocess.call(["python", "train.py"])
|
subprocess.call()
: 这个函数用来运行一个命令并等待它完成。它返回命令的退出码(如果命令正常结束,通常为0;如果有错误,会是非零值)。
["python", "train.py"]
: 这是一个列表,其中每个元素代表命令行中的一个参数。在这个例子中,“python”是你想要运行的程序,而“train.py”是你希望传递给该程序的文件名。
当你执行 subprocess.call(["python", "train.py"])
时,你的Python脚本会启动一个新的Python解释器进程来运行 train.py
脚本。当前的Python脚本会暂停,等待 train.py
完成执行。一旦 train.py
执行完毕,控制权会返回到调用 subprocess.call
的地方,然后继续执行后续代码
检查服务器是否可用,可用即训练
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| import os import subprocess import time
def check_gpu_memory(): """ 使用 nvidia-smi 获取 GPU 显存使用情况 返回 True 表示至少有一块 GPU 的剩余显存大于 23GB,False 表示没有 同时返回可用 GPU 的 ID """ try: result = subprocess.check_output( ['nvidia-smi', '--query-gpu=index,memory.used,memory.total', '--format=csv,noheader,nounits']) memory_info = result.decode('utf-8').strip().split('\n') print("GPU Memory Info:", memory_info) memory_threshold_gb = 23
max_free_memory_gb = 0 gpu_id_with_max_free_memory = None
for info in memory_info: index, used, total = info.split(',') free = int(total) - int(used) free_gb = free / 1024
if free_gb >= memory_threshold_gb and free_gb > max_free_memory_gb: max_free_memory_gb = free_gb gpu_id_with_max_free_memory = index
if max_free_memory_gb > 0: return True, gpu_id_with_max_free_memory else: return False, None except Exception as e: print(f"Error checking GPU memory usage: {e}") return False, None
def train_network(gpu_id): print(f"Starting training on GPU {gpu_id}...") os.environ["CUDA_VISIBLE_DEVICES"] = gpu_id subprocess.call(["python", "train.py"])
def main(): max_wait_time_seconds = 10 * 60 * 60 start_time = time.time()
while True: can_train, gpu_id = check_gpu_memory() if can_train: train_network(gpu_id) break else: print("No GPU with sufficient memory available. Waiting...") time.sleep(60)
elapsed_time = time.time() - start_time if elapsed_time > max_wait_time_seconds: print("Maximum wait time reached. Exiting.") break
if __name__ == "__main__": main()
|