如何确保Pytorch中的所有内容都在GPU上自动运行?

时间:2017-08-07 18:36:51

标签: machine-learning neural-network conv-neural-network pytorch

我想用一种代码最少的方式,这样我脚本中的所有内容都可以在GPU中自动运行(或者pytorch执行它的标准方式)。类似的东西:

torch.everything_to_gpu()

然后它"正常工作"。我不在乎手动将东西放在GPU等中。我只是想让它自动完成它的工作(就像tensorflow那样吗?)。我确实看到了a related question in the pytorch forum,但似乎并没有直接解决我的问题。

现在,在我看来(从我已经通过的例子中)可以通过为每个火炬变量/张量指定一个简单类型来实现我想要的东西,如下所示:

dtype = torch.FloatTensor
# dtype = torch.cuda.FloatTensor # Uncomment this to run on GPU

只要每个变量/张量以某种方式取dtype就好了。

Variable(torch.FloatTensor(x).type(dtype), requires_grad=False)

然后我们可以使用该单个变量来控制GPU中的内容而不是。如果存在这样的单个命令,那么我遇到的问题会使我的内容变得模糊不清是在使用torch.nn.Module包时。例如,使用

l = torch.nn.Linear(D_in,D_out)

或服装NN类(继承自它)。这种情况似乎是处理它的最佳方法是使用:

torch.nn.Module.cuda(device_id=device_id) # device_id = None is the default

功能/方法。然而,这似乎告诉我,可能还有其他隐藏的功能,我可能不知道确保一切确实在GPU中运行。

因此:是否有集中的方法确保所有在某些(理想情况下自动)分配的GPU中运行?

在反思中,我认为让我感到困惑的一件事是,我不理解pytorch如何在GPU上进行计算。例如,我相当确定MATLAB的工作方式是,如果至少有一件事在GPU上,那么所有进一步的计算将在GPU上。所以我想,我想知道,这是pytorch的工作原理吗?如果可能的话,它与TensorFlow相比如何?

3 个答案:

答案 0 :(得分:2)

我认为没有这样的事情。

从我所看到的,人们通常会创建以下课程: i)继承nn.Module
ii)具有描述模型参数的属性(例如self.opt);
iii)将每个变量/参数设置为属性(例如self.my_var
iv)如果设置了.cuda()参数,则在其上调用-use_gpu

我还在我的类中使用了maybe_cuda(variable)函数,以便更容易地创建变量(如果variable.cuda()为True,则传递变量,返回opt.cuda

事实上,我做过这样的事情(可能不完美,但发现它很实用):

class MyModule(nn.Module):
    def __init__(self, opt):
        super(MyModule, self).__init__()
        self.opt = opt

    def maybe_cuda(self, variable):
        if self.opt.cuda:
            return variable.cuda()
        return variable

class Model(MyModule):
    def __init__(self, opt, other_arg):
        super(Model, self).__init__(opt)

        self.linear = nn.Linear(opt.size1, opt.size2)
        self.W_out = nn.Parameter(_____)

    def forward(self, ____):
        # create a variable, put it on GPU if possible
        my_var = self.maybe_cuda(Variable(torch.zeros(___)))

答案 1 :(得分:1)

据我所知,没有一个配置可以使将来所有与割炬有关的计算都在GPU中进行。您需要明确指定它。

除了pltrdy's answer之外,以下是在GPU中运行代码的另一种简便方法。在要运行代码的设备上创建一个torch.device变量,其中包含设备信息。

#Assuming you have a cuda boolean flag
device = torch.device('cuda') if cuda else torch.device('cpu')
some_tensor = torch.randn(2).to(device)
some_model = ModelClass().to(device)

#If you want to use multiple GPUs use DataParallel
some_model = torch.nn.DataParallel(some_model)

关于您的最后一个问题,依赖于张量的新张量将自动驻留在父张量的设备中。

a = torch.randn(1).cuda() #In the GPU
b = a + 2                 #Also in the GPU

DataParallel的文档

答案 2 :(得分:0)

似乎是github上的一个未解决问题:[FR] torch context with default device & dtype。我之所以来到这里,是因为我认为这是一个愚蠢的问题,并且没有这样做是有充分理由的(在这里[feature request] Global GPU Flag他们提到谈论不可言传的情形,即您的程序在多个设备上运行张量……)。似乎人们已经想要了足够的东西,他们可以实现它。