【问题标题】:Loop optimization in PytorchPytorch 中的循环优化
【发布时间】:2021-03-31 16:19:16
【问题描述】:

我正在尝试找到一种方法来防止 Pytorch 中出现令人痛苦的缓慢 for 循环。基本上,我有一个张量,我想将它分成几部分并将这些部分输入我的模型,在精神上类似于各种分组卷积。

        self.C = C
        self.block = Block(C, 3, 64)
    def forward(self, x):
        x_shape = x.shape
        x = torch.flatten(x, start_dim=1, end_dim=-1).unsqueeze(1)
        x = torch.split(x, self.C, -1)
        attention = []
        for i in x:
            attended = self.block(i)
            attention.append(attended)
        attention = torch.stack(attention, 1)

我认为,C 的小值加上大张量会使这个操作出奇地慢得多,因为上面的代码运行了 Python for 循环。但是,当我将批处理维度交换为“C”维度并循环遍历批处理维度时,这会导致显着的加速,但是对我来说仍然感觉很笨拙,并且在足够大的批处理大小下可能仍然会很慢。我想要一种方法来解决这个问题,同时仍然保持批处理暗淡完整并避免 for 循环。我想我正在寻找的是一种向我的模型添加第二个批次维度的方法,或者类似的方法。

除了上面描述的稍微有点hacky的方法之外,还有其他方法可以解决这个问题吗?

编辑: MWE:(假装单个线性层就像一个分裂的注意力层......)

import torch

class Net(torch.nn.Module):
    def __init__(self, split_size):
        super().__init__()
        self.split_size = split_size
        self.linear = torch.nn.Linear(split_size, split_size)
    def forward(self, x):
        #Slow implementation:

        #Input is B,C,H and is flattened to B,C*H.
        y = x.flatten(start_dim=1, end_dim=-1)

        y_split = torch.split(y, self.split_size, 1) #Tensor is split and each piece is fed into the model...

        outs = []

        for i in y_split:
            i_out = self.linear(i)
            outs.append(i_out)
        y = torch.cat(outs, 1)
        print(y.shape)

        #Fast implementation using batch dims, but possibly slower for large batches...
        y = x.flatten(start_dim=1, end_dim=-1)
        y_split = torch.split(y, self.split_size, 1)

        y = torch.stack(y_split, 0)
        outs = []
        for i in torch.split(y, 1, 1):
            i_out = self.linear(i.squeeze(1)).unsqueeze(0)
            outs.append(i_out)
        y = torch.cat(outs, 0)
        y = y.flatten(start_dim=1, end_dim=-1)
        print(y.shape)
        return y
        
if __name__ == "__main__":
    net = Net(32)
    net(torch.randn(256,3,32,32))
    net(torch.randn(32,3,32,32))

【问题讨论】:

  • 您能否添加一个 MWE,以便我们更好地了解您的问题?此外,这将有助于清楚地查看操作集,并且可能人们会提出甚至不需要循环的方法

标签: python performance for-loop pytorch


【解决方案1】:

我认为 2D 输入将在具有相同网络层的每个通道中处理。

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
  • 2014-07-30
  • 2017-02-28
相关资源
最近更新 更多