如何检查PyTorch是否使用GPU?

547

我该如何检查PyTorch是否正在使用GPU?nvidia-smi命令可以检测GPU活动,但我想直接从Python脚本内部进行检查。


3
有没有一种方法可以获取当前所有可用的GPU列表?类似于 devices = torch.get_all_devices() # [0, 1, 2] 或者它们的名字 - Charlie Parker
2
请参见 https://dev59.com/SVIG5IYBdhLWcg3whAQW: [torch.cuda.device(i) for i in range(torch.cuda.device_count())] - vvvvv
1
我被告知这个代码可以运行:list(range(torch.cuda.device_count()))。不过还是谢谢! - Charlie Parker
2
@CharlieParker,假设您已经import torch,您希望使用以下代码获取GPU设备编号:devices = [d for d in range(torch.cuda.device_count())]如果您需要获取设备名称,可以使用以下代码:device_names = [torch.cuda.get_device_name(d) for d in devices]如果您像我一样需要跨机器管理这些信息,您可能希望将它们映射为字典:device_to_name = dict( zip(devices, device_names) ) - hello_there_andy
请使用此链接 - https://pypi.org/project/test-pytorch-gpu - undefined
19个回答

903

这些函数应该会有所帮助:

>>> import torch

>>> torch.cuda.is_available()
True

>>> torch.cuda.device_count()
1

>>> torch.cuda.current_device()
0

>>> torch.cuda.device(0)
<torch.cuda.device at 0x7efce0b03be0>

>>> torch.cuda.get_device_name(0)
'GeForce GTX 950M'

这告诉我们:

  • CUDA可用并且可以被一个设备使用。
  • 设备 0指的是GPU GeForce GTX 950M,它当前被PyTorch选择。

29
我认为这只是说明这些设备可以在机器上使用,但我不确定是否可以获取每个GPU正在使用多少内存之类的信息。 - kmario23
12
运行 torch.cuda.current_device() 对我很有帮助。它显示我的GPU太旧了:"Found GPU0 GeForce GTX 760 which is of cuda capability 3.0. PyTorch no longer supports this GPU because it is too old." - JohnnyFun
10
torch.cuda.is_available() - mrgloom
3
没问题,这个命令就是 $ watch -n 2 nvidia-smi 。如需更多细节,请参见我的回答 - kmario23
1
这对我非常有用。torch.cuda.is_available() 意外地返回了 False。运行 nvidia-smi 会在其输出的最后一行产生“WARNING: infoROM is corrupted at gpu 0000:00:1E.0”的警告。这是由硬件错误引起的,通过启动和停止 EC2 实例进行了“修复”;重新启动没有影响。 - Matthew Walker
显示剩余8条评论

237

由于在这里没有提出,因此我添加了一种使用torch.device的方法,因为这非常方便,特别是当在正确的device上初始化张量时。

# setting device on GPU if available, else CPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print('Using device:', device)
print()

#Additional Info when using cuda
if device.type == 'cuda':
    print(torch.cuda.get_device_name(0))
    print('Memory Usage:')
    print('Allocated:', round(torch.cuda.memory_allocated(0)/1024**3,1), 'GB')
    print('Cached:   ', round(torch.cuda.memory_reserved(0)/1024**3,1), 'GB')

编辑: torch.cuda.memory_cached 已更名为 torch.cuda.memory_reserved。因此在旧版本中请使用 memory_cached

输出:

Using device: cuda

Tesla K80
Memory Usage:
Allocated: 0.3 GB
Cached:    0.6 GB

如上所述,使用device,它是可能的

  • 将张量移动到相应的device

torch.rand(10).to(device)
  • 直接在设备上创建张量:

    torch.rand(10, device=device)
    
  • 这使得在不改变实际代码的情况下方便地在CPUGPU之间切换。


    编辑:

    由于关于cachedallocated内存存在一些问题和困惑,我添加了一些有关信息:


    您可以直接将device传递给如上所述的内容或者将其保留为None,它将使用current_device()


    附注:具有Cuda计算能力3.0或更低版本的旧图形卡可能是可见但无法被Pytorch使用的!
    感谢hekimgil指出这一点!-“发现GPU0 GeForce GT 750M,它的cuda能力为3.0。 PyTorch不再支持此GPU,因为它太旧了。我们支持的最小cuda能力为3.5。”


    2
    我尝试了你的代码,它识别了显卡,但分配和缓存都是0GB。这是正常的还是我需要配置它们? - KubiK888
    我根据这个教程 - https://www.analyticsvidhya.com/blog/2018/02/pytorch-tutorial/ 创建了一个 .py 脚本。特别是复制/粘贴以 ## neural network in pytorch 开头的部分,然后在末尾添加您的代码。它仍然显示使用设备:cuda;已分配和缓存的内存为0GB。我还尝试将其插入到 for 循环 for i in range(epoch): 的末尾,在反向传播之后,仍然全部为0GB。 - KubiK888
    3
    您必须保持一致性,不能在不同设备间执行操作。例如 my_tensor_on_gpu * my_tensor_on_cpu 这样的操作会失败。 - MBT
    4
    你的回答很好,但是对于第一行设备分配代码,我想指出,并不是因为有一个可用的CUDA设备,就意味着我们可以使用它。例如,我的旧电脑上有这个:Found GPU0 GeForce GT 750M which is of cuda capability 3.0. PyTorch不再支持此GPU,因为它太旧了。 我们支持的最小cuda能力是3.5。 - hekimgil
    1
    @CharlieParker 我还没有测试过,但我相信你可以使用 torch.cuda.device_count() 函数来获取设备数量,然后使用 list(range(torch.cuda.device_count())) 来获得所有设备的索引列表。 - MBT
    显示剩余5条评论

    72

    在开始运行训练循环后,如果你想要从终端手动观察程序是否利用了GPU资源以及利用程度的话,你可以简单地使用如下命令:watch

    $ watch -n 2 nvidia-smi
    

    这将每2秒钟持续更新使用统计数据,直到您按下 ctrl+c


    如果您需要更多控制更多的GPU统计信息,您可能需要使用nvidia-smi的更高级版本,带有--query-gpu=...。以下是一个简单的示例:

    $ watch -n 3 nvidia-smi --query-gpu=index,gpu_name,memory.total,memory.used,memory.free,temperature.gpu,pstate,utilization.gpu,utilization.memory --format=csv
    

    会输出类似以下统计数据的内容:
    Every 3.0s: nvidia-smi --query-gpu=index,gpu_name,memory.total,memory.used,memory.free,temperature.gpu,pstate,utilization.gpu,utilization.memory --format=csv           Sat Apr 11 12:25:09 2020
    
    index, name, memory.total [MiB], memory.used [MiB], memory.free [MiB], temperature.gpu, pstate, utilization.gpu [%], utilization.memory [%]
    0, GeForce GTX TITAN X, 12212 MiB, 10593 MiB, 1619 MiB, 86, P2, 100 %, 55 %
    1, GeForce GTX TITAN X, 12212 MiB, 11479 MiB, 733 MiB, 84, P2, 93 %, 100 %
    2, GeForce GTX TITAN X, 12212 MiB, 446 MiB, 11766 MiB, 36, P8, 0 %, 0 %
    3, GeForce GTX TITAN X, 12212 MiB, 11 MiB, 12201 MiB, 38, P8, 0 %, 0 %
    

    注意:在--query-gpu=...中,逗号分隔的查询名称之间不应有任何空格。否则这些值将被忽略,并且不会返回任何统计信息。


    此外,您可以通过执行以下操作来检查您的PyTorch安装是否正确地检测到了CUDA安装:
    In [13]: import  torch
    
    In [14]: torch.cuda.is_available()
    Out[14]: True
    

    True状态表示PyTorch已正确配置并正在使用GPU,尽管您需要在代码中使用必要的语句移动/放置张量。


    如果你想在Python代码中实现这个功能,那么可以查看这个模块: https://github.com/jonsafari/nvidia-ml-py 或者在pypi上查看:https://pypi.python.org/pypi/nvidia-ml-py/

    2
    请记住,PyTorch使用缓存的GPU内存分配器。即使完全使用,您可能会看到nvidia-smi的低GPU利用率。 - Jakub Bielan
    1
    @JakubBielan 谢谢!你能提供更多阅读参考资料吗? - kmario23
    1
    那个 watch 很有用。 - WestCoastProjects
    这只适用于Linux吗? - Gulzar
    5
    nvidia-smi有一个-l标志用于循环秒数,因此您无需使用watchnvidia-smi -l 2或者以毫秒为单位:nvidia-smi -lms 2000 - meferne

    53

    从实际角度考虑,只有一个小的偏离:

    import torch
    dev = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
    

    这个 dev 现在知道是使用 CUDA 还是 CPU 运行。

    当转向 CUDA 时,处理模型和张量的方式有所不同。起初可能会感觉有些奇怪。

    import torch
    import torch.nn as nn
    dev = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
    t1 = torch.randn(1,2)
    t2 = torch.randn(1,2).to(dev)
    print(t1)  # tensor([[-0.2678,  1.9252]])
    print(t2)  # tensor([[ 0.5117, -3.6247]], device='cuda:0')
    t1.to(dev)
    print(t1)  # tensor([[-0.2678,  1.9252]])
    print(t1.is_cuda) # False
    t1 = t1.to(dev)
    print(t1)  # tensor([[-0.2678,  1.9252]], device='cuda:0')
    print(t1.is_cuda) # True
    
    class M(nn.Module):
        def __init__(self):        
            super().__init__()        
            self.l1 = nn.Linear(1,2)
    
        def forward(self, x):                      
            x = self.l1(x)
            return x
    model = M()   # not on cuda
    model.to(dev) # is on cuda (all parameters)
    print(next(model.parameters()).is_cuda) # True
    

    这一切都很棘手,但只要理解一次,就可以帮助您更快地处理,减少调试。


    2
    您还需要在开头导入import torch.nn as nn - Bernardo Kyotoku

    34
    查询 指令
    PyTorch 是否看到任何 GPU? torch.cuda.is_available()
    张量是否默认存储在 GPU 上? torch.rand(10).device
    将默认张量类型设置为 CUDA: torch.set_default_tensor_type(torch.cuda.FloatTensor)
    此张量是否为 GPU 张量? my_tensor.is_cuda
    此模型是否存储在 GPU 上? all(p.is_cuda for p in my_model.parameters())

    1
    我不知道你可以将张量默认设置为在GPU上。酷! - undefined
    如果有多个GPU,我可以选择在哪个GPU上创建张量吗? - undefined

    28

    从官方网站的入门页面,您可以这样检查GPU是否对PyTorch可用:

    import torch
    torch.cuda.is_available()
    

    参考资料: PyTorch | 入门指南


    这是最有帮助(简洁)的答案 - undefined

    14

    检查是否有可用的GPU:

    torch.cuda.is_available()
    
    如果上述函数返回False,则可能存在以下情况:
    1. 您没有GPU;
    2. Nvidia驱动程序未安装,因此操作系统无法识别GPU;
    3. 环境变量CUDA_VISIBLE_DEVICES隐藏了GPU。当CUDA_VISIBLE_DEVICES的值为-1时,表示所有设备都被隐藏。您可以使用以下代码检查该值:os.environ['CUDA_VISIBLE_DEVICES']
    如果上述函数返回True,并不一定意味着您正在使用GPU。在Pytorch中,您可以在创建张量时将其分配到设备上。默认情况下,张量会分配到cpu上。要检查张量分配在哪里,请执行以下操作:
    # assuming that 'a' is a tensor created somewhere else
    a.device  # returns the device where the tensor is allocated
    
    请注意,您不能对分配在不同设备上的张量进行操作。有关如何将张量分配给GPU的详细信息,请参见此处:https://pytorch.org/docs/stable/notes/cuda.html

    10

    只需要在命令提示符或Linux环境下运行以下命令即可。

    python -c 'import torch; print(torch.cuda.is_available())'
    

    以上代码应该打印出True
    python -c 'import torch; print(torch.rand(2,3).cuda())'
    

    这个应该打印出以下内容:
    tensor([[0.7997, 0.6170, 0.7042], [0.4174, 0.1494, 0.0516]], device='cuda:0')
    

    10
    几乎所有的答案都涉及到 torch.cuda.is_available()。然而,这只是问题的一部分。它告诉你 GPU(实际上是 CUDA)是否可用,而不是它是否正在被使用。在典型的设置中,你需要像这样设置你的设备:
    device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
    

    但在更大的环境(例如研究)中,通常会给用户更多选项,因此根据输入,他们可以禁用CUDA,指定CUDA ID等。在这种情况下,GPU是否使用不仅取决于其是否可用。设置torch设备后,您可以获取其type属性以验证它是否为CUDA。

    if device.type == 'cuda':
        # do something
    

    7

    对于MacBook M1系统:

    import torch
    print(torch.backends.mps.is_available(), torch.backends.mps.is_built())
    

    两者都应该为真。


    2
    请注意,这也适用于至少一些较旧的英特尔Macbook。这在我的2019年英特尔Macbook上使用了一块Radeon Pro 560X 4GB GPU。 - Lucas Wiman

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接