【问题标题】:Is the forward definition of a model executed sequentially in PyTorch or in parallel?模型的前向定义是在 PyTorch 中顺序执行还是并行执行?
【发布时间】:2020-09-08 22:58:04
【问题描述】:

我想知道深度模型类的前向定义中的指令是否按顺序执行?例如:

class Net(nn.Module):
    ...
    def forward(self,x):

        #### Group 1
        y = self.conv1(x)
        y = self.conv2(y)
        y = self.conv3(y)

        ### Group 2
        z = self.conv4(x)
        z = self.conv5(z)
        z = self.conv6(z)

        out = torch.cat((y,z),dim=1)
        return out

在这种情况下,Group1Group2 指令可以并行化。但是前向定义会自动理解这一点,还是会按顺序执行?如果不是,那么如何并行运行它们?

我正在运行 PyTorch 1.3.1

非常感谢

【问题讨论】:

    标签: pytorch


    【解决方案1】:

    它们是按顺序执行的,只有运算的计算是并行的。据我所知,PyTorch 没有直接的方法让它们并行运行。

    我假设您期望通过并行运行它们来提高性能,但这充其量是最小的,最坏的情况是慢得多,因为像卷积这样的操作已经高度并行化,除非输入非常小,所有核心将被永久使用。并行运行多个卷积会导致大量上下文切换,除非您要平均分配可用内核,但这并不会真正比使用所有内核按顺序执行它们更快。

    如果您同时运行两个 PyTorch 程序,您可以观察到相同的行为,例如运行以下程序,它有 3 个相对常见的卷积并使用 224x224 图像(如 ImageNet),即与其他模型(例如对象检测)使用的模型相比很小:

    import torch
    import torch.nn as nn
    
    
    class Model(nn.Module):
        def __init__(self):
            super(Model, self).__init__()
            self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
            self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
            self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
    
        def forward(self, input):
            out = self.conv1(input)
            out = self.conv2(out)
            out = self.conv3(out)
            return out
    
    
    input = torch.randn((10, 3, 224, 224))
    model = Model().eval()
    
    # Running it 100 times just to create a microbenchmark
    for i in range(100):
        out = model(input)
    

    要获取有关上下文切换的信息,可以使用/usr/bin/time(不是内置的time)。

    /usr/bin/time -v python bench.py
    

    单次运行:

    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:22.68
    Involuntary context switches: 857 
    

    同时运行两个实例:

    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:43.69
    Involuntary context switches: 456753
    

    澄清一下,每个实例大约需要 43 秒,这不是累计时间。

    【讨论】:

    • 谢谢你。在阅读了您对执行时间的评论后,python 的time.time() 在 CPU 上进行推理时是否可靠,或者按照您的建议,应该使用/usr/bin/time
    • Python 的 time.time() 非常适合测量 CPU 时间。我使用/usr/bin/time 的原因是为了获取上下文切换的数量。
    猜你喜欢
    • 1970-01-01
    • 2017-03-25
    • 2018-06-25
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多