训练模型过程中优雅的指定GPU

本文介绍了如何使用Python库pynvml监控NVIDIA显卡,自动检测并选择剩余显存最多的GPU进行模型训练,避免手动指定GPU导致的不便。作者提供了基础用法和高级教程,包括设置显卡工作模式以及在程序中集成自动选择GPU的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前训练模型大部分在单机多卡的环境下,我们通常会指定一个GPU来训练模型。在不指定GPU情况下,默认使用GPU0来训练,但是很不巧GPU0被别人占了一半显存,导致OOM错误。每次跑模型都要去看下哪张卡显存最大,然后再来修改代码,指定GPU,是不是超级烦人呢!😶‍🌫️,今天就介绍一个每次都由程序自动选择剩余最大的显存的GPU来训练。

1. Quick Start

  • step1: 安装依赖包
    安装管理NVIDIA显卡的python依赖包pynvml
    pip install nvidia-ml-py
    
  • 使用pynvml监控GPU
    import psutil
    import pynvml #导包
    
    
    UNIT = 1024 * 1024
    
    
    pynvml.nvmlInit() #初始化
    gpuDeriveInfo = pynvml.nvmlSystemGetDriverVersion()
    print("Drive版本: ", str(gpuDeriveInfo, encoding='utf-8')) #显示驱动信息
    
    
    gpuDeviceCount = pynvml.nvmlDeviceGetCount()#获取Nvidia GPU块数
    print("GPU个数:", gpuDeviceCount )
    
    
    for i in range(gpuDeviceCount):
        handle = pynvml.nvmlDeviceGetHandleByIndex(i)#获取GPU i的handle,后续通过handle来处理
    
        memoryInfo = pynvml.nvmlDeviceGetMemoryInfo(handle)#通过handle获取GPU i的信息
    
        gpuName = str(pynvml.nvmlDeviceGetName(handle), encoding='utf-8')
    
        gpuTemperature = pynvml.nvmlDeviceGetTemperature(handle, 0)
    
        gpuFanSpeed = pynvml.nvmlDeviceGetFanSpeed(handle)
    
        gpuPowerState = pynvml.nvmlDeviceGetPowerState(handle)
    
        gpuUtilRate = pynvml.nvmlDeviceGetUtilizationRates(handle).gpu
        gpuMemoryRate = pynvml.nvmlDeviceGetUtilizationRates(handle).memory
    
        print("第 %d 张卡:"%i, "-"*30)
        print("显卡名:", gpuName)
        print("内存总容量:", memoryInfo.total/UNIT, "MB")
        print("使用容量:", memoryInfo.used/UNIT, "MB")
        print("剩余容量:", memoryInfo.free/UNIT, "MB")
        print("显存空闲率:", memoryInfo.free/memoryInfo.total)
        print("温度:", gpuTemperature, "摄氏度")
        print("风扇速率:", gpuFanSpeed)
        print("供电水平:", gpuPowerState)
        print("gpu计算核心满速使用率:", gpuUtilRate)
        print("gpu内存读写满速使用率:", gpuMemoryRate)
        print("内存占用率:", memoryInfo.used/memoryInfo.total)
    
        """
        # 设置显卡工作模式
        # 设置完显卡驱动模式后,需要重启才能生效
        # 0 为 WDDM模式,1为TCC 模式
        gpuMode = 0     # WDDM
        gpuMode = 1     # TCC
        pynvml.nvmlDeviceSetDriverModel(handle, gpuMode)
        # 很多显卡不支持设置模式,会报错
        # pynvml.nvml.NVMLError_NotSupported: Not Supported
        """
    
        # 对pid的gpu消耗进行统计
        pidAllInfo = pynvml.nvmlDeviceGetComputeRunningProcesses(handle)#获取所有GPU上正在运行的进程信息
        for pidInfo in pidAllInfo:
            pidUser = psutil.Process(pidInfo.pid).username()
            print("进程pid:", pidInfo.pid, "用户名:", pidUser, 
                "显存占有:", pidInfo.usedGpuMemory/UNIT, "Mb") # 统计某pid使用的显存
    
    
    pynvml.nvmlShutdown() #最后关闭管理工具
    

2. Advanced Tutorial

使用 pynvml 写一个自动化脚本,使其在程序开始时自动选择显存最大的GPU

def select_best_gpu():
    import pynvml
    pynvml.nvmlInit()  # 初始化
    gpu_count = pynvml.nvmlDeviceGetCount()
    if gpu_count == 0:
        device = "cpu"
    else:
        gpu_id, max_free_mem = 0, 0.
        for i in range(gpu_count):
            handle = pynvml.nvmlDeviceGetHandleByIndex(i)
            memory_free = round(pynvml.nvmlDeviceGetMemoryInfo(handle).free/(1024*1024*1024), 3)  # 单位GB
            if memory_free > max_free_mem:
                gpu_id = i
                max_free_mem = memory_free
        device = f"cuda:{gpu_id}"
        print(f"total have {gpu_count} gpus, max gpu free memory is {max_free_mem}, which gpu id is {gpu_id}")
    return device


available_device = select_best_gpu()

# 方法1:直接通过os全局设置GPU
import os
if available_device.startswith("cuda"):
    os.environ['CUDA_VISIBLE_DEVICES'] = available_device.split(":")[1]
    
# 方法2:在模型处指定
model = Model()   # 初始化模型
model.to(available_device)

注意:以上方法一定放到程序最开始处,否则指定GPU可能会失败,通常在import torch后,通过os指定GPU就会失败

3. REFERENCE

python查看gpu信息

<think>好的,我需要帮助用户解决在OpenPCDet中暂停正在进行的训练过程的问题。首先,我得了解用户的需求。用户可能在训练模型时想要中途暂停,可能是因为需要调整参数、释放资源或者处理其他任务。接下来,我需要回忆OpenPCDet的框架结构,看看是否有内置的功能支持暂停训练。 根据之前的知识,OpenPCDet是基于PyTorch的,而PyTorch本身并没有直接提供暂停训练的函数。不过,用户可以通过修改代码来实现类似的功能。常见的做法包括捕获键盘中断信号,比如Ctrl+C,或者在训练循环中添加检查点,定期保存模型状态,这样下次可以从该检查点继续训练。 用户可能需要两种方法:一种是手动暂停,比如按下某个键;另一种是自动保存检查点。我需要分别考虑这两种方法的实现方式。手动暂停可以通过Python的signal模块来处理SIGINT信号,当用户按下Ctrl+C时,触发保存当前模型和优化器状态,并退出训练。自动检查点则需要在每个epoch结束后保存模型,这样即使训练中断,也可以从最近的epoch恢复。 同时,我需要确保提供的代码示例正确,并且符合OpenPCDet的结构。比如,检查点的保存路径应该与OpenPCDet的输出目录一致,通常是在output目录下。另外,恢复训练时需要加载之前的检查点,并调整学习率等参数,可能需要修改配置文件或训练脚本的参数。 还要注意用户可能对如何修改现有代码不太熟悉,所以步骤需要详细。比如,在训练脚本中添加信号处理函数,或者在训练循环中插入保存检查点的代码。此外,要提醒用户确保有足够的存储空间来保存检查点文件,特别是当模型较大时,频繁保存可能会占用大量空间。 最后,需要验证这些方法的可行性。比如,在捕获信号后,是否能够正确保存模型,而不会导致数据损坏。另外,恢复训练时是否能够正确加载模型和优化器状态,并继续训练过程。可能需要参考OpenPCDet的文档或社区讨论,看看是否有推荐的最佳实践。 总结来说,解决方案包括手动暂停和自动检查点两种方法,用户可以根据需求选择。需要提供具体的代码示例和步骤,并指出注意事项,如文件路径和恢复训练的方法。</think>在OpenPCDet中暂停正在运行的训练代码,可通过以下两种方式实现: ### 方法一:键盘中断+检查点恢复 1. **手动暂停训练** 在终端运行训练命令时,直接按下`Ctrl+C`发送`SIGINT`信号终止进程。此时需要注意: - 若代码中已实现检查点保存功能,会自动保存最新训练状态到`output/.../checkpoint`目录下 - 可通过修改`train.py`捕获中断信号,实现优雅退出: ```python import signal def handler(signum, frame): print("捕获中断信号,正在保存检查点...") # 调用OpenPCDet的保存函数 model.save_params_to_file(checkpoint_path) exit(0) signal.signal(signal.SIGINT, handler) ``` 2. **恢复训练** 在配置文件中指定`--resume`参数: ```bash python train.py --cfg_file cfgs/your_config.yaml --resume /path/to/checkpoint.pth ``` ### 方法二:周期性保存检查点(推荐) 在OpenPCDet的训练逻辑中,默认每1个epoch自动保存检查点。可通过修改`tools/train_utils/train_utils.py`中的保存频率: ```python # 修改保存间隔(例如每0.5小时保存一次) self.save_checkpoint( epoch=cur_epoch, save_interval=0.5, # 单位:小时 ckpt_name=f'checkpoint_epoch_{cur_epoch}' ) ``` ### 注意事项 1. **检查点文件结构** 完整训练状态保存在`.pth`文件中,包含: ```python { 'epoch': current_epoch, 'model_state': model.state_dict(), 'optimizer_state': optimizer.state_dict(), 'scheduler_state': lr_scheduler.state_dict() } ``` 2. **恢复训练配置** 需在配置文件中设置`RESUME_PATH`参数: ```yaml TRAIN: RESUME_PATH: "output/your_model/default/checkpoint_epoch_10.pth" START_EPOCH: 10 # 从指定epoch继续 ``` 3. **分布式训练暂停** 如果使用多GPU训练,需要确保所有进程同步退出: ```python if torch.distributed.is_initialized(): torch.distributed.barrier() ``` [^1]: 关于OpenPCDet训练流程的详细说明,参考模型代码解析文档 [^2]: 数据集配置和训练参数设置方法详见官方训练指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值