【问题标题】:Forward pass gets 10000x slower after iterating for a while迭代一段时间后,前向传递速度变慢了 10000 倍
【发布时间】:2020-05-21 23:25:59
【问题描述】:

我实现了一个简单的 Deconv 网络,就像 pytorch 的官方 DCGAN 教程一样。 我反复将zeros 向量传递给它。一段时间后,所用时间显着减慢。我想知道原因是什么以及如何解决。

代码:

import torch
import torch.nn as nn
import time

# JUST TO MEASURE TIME
class Timer:
    def __init__(self, msg):
        self.msg = msg

    def __enter__(self):
        self.start = time.process_time()
        return self

    def __exit__(self, *args):
        self.end = time.process_time()
        self.interval = self.end - self.start

        print('{}: {:.5f}'.format(self.msg, self.interval))

device = torch.device("cuda")

ngf, nc, nz, batchSize = 64, 1, 6, 1<<16
class Generator(nn.Module):
    def __init__(self):
        super(Generator, self).__init__()
        self.main = nn.Sequential(
            # input is Z, going into a convolution
            nn.ConvTranspose2d( nz, ngf * 4, 4, 1, 0, bias=False),
            nn.BatchNorm2d(ngf * 4),
            nn.ReLU(True),
            # state size. (ngf*4) x 4 x 4
            nn.ConvTranspose2d(ngf * 4, ngf * 2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf * 2),
            nn.ReLU(True),
            # state size. (ngf*2) x 8 x 8
            nn.ConvTranspose2d( ngf * 2, ngf, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf),
            nn.ReLU(True),
            # state size. (ngf) x 16 x 16
            nn.ConvTranspose2d( ngf, nc, 4, 2, 1, bias=False),
            nn.Tanh()
            # state size. (nc) x 32 x 32
        )

    def forward(self, input):
        return self.main(input)

# Create the generator
netG = Generator().to(device)

def weights_init(m):
    classname = m.__class__.__name__
    if classname.find('Conv') != -1:
        nn.init.normal_(m.weight.data, 0.0, 0.02)
    elif classname.find('BatchNorm') != -1:
        nn.init.normal_(m.weight.data, 1.0, 0.02)
        nn.init.constant_(m.bias.data, 0)

netG.apply(weights_init)

# torch.backends.cudnn.benchmark=True

while True:
    with Timer('Time elapsed'):
        with torch.no_grad():
            netG(torch.zeros([batchSize, nz, 1, 1], device=device))

结果:

经过时间:0.02309 经过时间:0.00072 经过时间:0.00208 时间 经过:0.00128 经过时间:0.00119 经过时间:0.00153 时间 经过:0.00176 经过时间:0.00170 经过时间:0.00185 时间 经过:0.00188 经过时间:0.00191 经过时间:0.00190 时间 经过:0.00171 经过时间:0.00176 经过时间:0.00167 时间 经过:0.00120 经过时间:0.00168 经过时间:0.00169 时间 经过:0.00166 经过时间:0.00167 经过时间:0.00171 时间 经过:0.00168 经过时间:0.00168 经过时间:0.00168 时间 经过:0.00169 经过时间:0.00177 经过时间:0.00173 时间 经过:0.00176 经过时间:0.00173 经过时间:0.00171 时间 经过:0.00168 经过时间:0.00173 经过时间:0.00168 时间 经过:0.00178 经过时间:0.00169 经过时间:0.00171 时间 经过:0.00168 经过时间:0.00169 经过时间:0.00169 时间 经过:0.00173 经过时间:0.00154 经过时间:0.00170 时间 经过:0.00167 经过时间:0.00224 经过时间:0.00117 时间 经过:0.00175 经过时间:0.00168 经过时间:0.00173 时间 经过:0.00169 经过时间:12.62760 经过时间:12.71425 时间 经过:12.71379 经过时间:12.71846 经过时间:12.71909 时间 经过:12.71898 经过时间:12.72288 经过时间:12.72157 时间 经过:12.72226 经过时间:12.72456 经过时间:12.72350 时间 经过:12.72480 经过时间:12.72644 经过时间:12.72337 时间 经过:12.72424 经过时间:12.72538 经过时间:12.72533 时间 经过:12.72510 经过时间:12.72507 经过时间:12.72806 时间 经过:12.72865 经过时间:12.72764 经过时间:12.72431

  • 我的 GPU:Titan RTX
  • PyTorch 版本:1.4
  • Python 版本:3.7

【问题讨论】:

  • 这是python2.7吗?您的代码可能保留了通常会在后面的 prob 中删除的变量,因此最终可以使用的内存很少
  • 它是 python3。如果你的猜测是正确的,那我应该如何解决?
  • 奇怪我在python3中没有看到super。我不太了解 pytorch,但 this 可能会有所帮助
  • 我从 pytorch 教程中复制了模块,super 显示 python 3 没有问题
  • 仅供参考,我可以在 TITAN RTX 上重现这一点,尽管我不完全确定它为什么会发生。我认为这是由于 pytorch 的异步行为而发生的,因为如果您通过y = netG(... 捕获输出然后调用torch.cuda.synchronize(),那么每次迭代都需要相同的时间(大约 12 秒)。如果您添加torch.cuda.synchronize() 而不分配netG(... 的输出,那么它仍然不会等待,但我认为这是因为没有等待更新的变量。

标签: python deep-learning gpu pytorch


【解决方案1】:

我在我的 Titan RTX 上尝试了相同的代码并得到了完全相同的行为。

所有 gpu 调用都是异步的(正如 jodag 在 cmets 中指出的那样),并且仅在需要时同步,如果存在依赖关系。所以为了测试它,我稍微更改了代码,以便实际使用网络的输出并创建一个依赖项这样的依赖项。所以现在需要在下一次迭代开始之前输出。

while True:
    with Timer('Time elapsed'):
        with torch.no_grad():
            output = netG(torch.zeros([batchSize, nz, 1, 1], device=device))
            print(output.mean())

现在它总是需要 12.8 秒。所以jodag是完全正确的。它与对 GPU 的异步调用以及 pytorch 如何在内部处理所有事情有关。

【讨论】:

    猜你喜欢
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    相关资源
    最近更新 更多