PyTorch:cuda内存不足,但剩余内存足够(添加错误消息)

时间:2020-08-26 11:15:06

标签: pytorch

我正在尝试使用GoogleNet(Pytorch)对猫和狗进行分类。 每个类别包含4000张要训练的图像和1000张要测试的图像,尺寸为300 * 300。 我的计算机具有32GB RAM和RTX 2080 Super图形卡。 当它开始训练时,就会发生此错误。以下是我的代码,属于GoogleNet的一部分:

class Inception(nn.Module) :
    def __init__(self, in_dim, out_dim1, mid_dim3, out_dim3, mid_dim5, out_dim5, pool):
       super(Inception, self).__init__()
        self.lay1 = nn.Sequential(nn.Conv2d(in_dim, out_dim1, kernel_size= 1), nn.BatchNorm2d(out_dim1), nn.ReLU())
        self.lay2 = nn.Sequential(nn.Conv2d(in_dim, mid_dim3, kernel_size = 1), nn.BatchNorm2d(mid_dim3), nn.ReLU(), nn.Conv2d(mid_dim3, out_dim3, kernel_size = 3, padding = 1), nn.BatchNorm2d(out_dim3), nn.ReLU())
        self.lay3 = nn.Sequential(nn.Conv2d(in_dim, mid_dim5, kernel_size = 1), nn.BatchNorm2d(mid_dim5), nn.ReLU(), nn.Conv2d(mid_dim5, out_dim5, kernel_size = 3, padding = 1), nn.BatchNorm2d(out_dim5), nn.ReLU(), nn.Conv2d(out_dim5, out_dim5, kernel_size = 3, padding = 1), nn.BatchNorm2d(out_dim5), nn.ReLU())
        self.lay4 = nn.Sequential(nn.MaxPool2d(3, 1, 1), nn.Conv2d(in_dim, pool, kernel_size = 1), nn.BatchNorm2d(pool), nn.ReLU())

    def forward(self, x):
        y1 = self.lay1(x)
        y2 = self.lay2(x)
        y3 = self.lay3(x)
        y4 = self.lay4(x)

        return torch.cat([y1, y2, y3, y4], 1)


class Google(nn.Module):
    def __init__(self):
        super(Google, self).__init__()
        self.pre_lay = nn.Sequential(nn.Conv2d(1, 48, 3, padding = 1), nn.BatchNorm2d(48), nn.ReLU())
        self.glay1 = Inception(48, 16, 24, 32, 4, 8, 8)
        self.glay2 = Inception(64, 32, 32, 48, 8, 24, 16) # input channel : prev output channel sum(torch.cat)
        self.maxpool = nn.MaxPool2d(3, stride = 2, padding = 1)
        self.glay3 = Inception(120, 48, 24, 52, 4, 12, 16)
        self.glay4 = Inception(128, 40, 28, 56, 6, 16, 16)
        self.glay5 = Inception(128, 32, 32, 64, 6, 16, 16)
        self.glay6 = Inception(128, 28, 36, 72, 8, 16, 16)
        self.glay7 = Inception(132, 64, 40, 80, 8, 32, 32)
        self.glay8 = Inception(208, 64, 40, 80, 8, 32, 32)
        self.glay9 = Inception(208, 96, 48, 96, 12, 32, 32)


        self.avgpool = nn.AvgPool2d(8, stride = 1)
        self.linear = nn.Linear(47872, 2)
        gc.collect()
        torch.cuda.empty_cache()


    def forward(self, x):
        gc.collect()
        torch.cuda.empty_cache()
        # with torch.no_grad() : // 
            out = self.pre_lay(x) # CUDA out of memory Occurs!!
            out = self.glay1(out)
            out = self.glay2(out)
            out = self.maxpool(out)
            out = self.glay3(out)
            out = self.glay4(out)
            out = self.glay5(out)
            out = self.glay6(out)
            out = self.glay7(out)
            out = self.maxpool(out)
            out = self.glay8(out)
            out = self.glay9(out)
            out = self.avgpool(out)
            out = out.view(out.size(0), -1)
            print("Out size : ", out.size())
            out = self.linear(out)

        return out

正如我所写,在GoogleNet的第一步中发生了错误。错误发生的前一行,有人建议在模型的前向函数中添加torch.no_grad():如果存在cuda内存错误,但内存不是问题,则在模型的正向函数处添加。但是然后 张量的元素0不需要grad并且没有grad_fn 错误。 我怀疑可以大量使用GPU内存的每个步骤都尝试过empty_cache,但仍然无法正常工作。

如果有人遇到类似的错误或知道原因,那么您的建议必须非常感谢。

添加完整的错误消息

cuda memory error

这就是我遇到的内存错误。

grad error

下面的错误是我在forward()上添加torch.no_grad()

2 个答案:

答案 0 :(得分:0)

我不知道为什么会出现此错误,但是我有一些建议可以尝试。 您可以创建生成器数据加载器功能,而不用处理内存中的所有图像。

答案 1 :(得分:0)

“ CUDA内存不足”是关于 GPU 而不是RAM的错误。错误消息说它需要1.25 GB,但只有1.16 GB可用空间,因此您没有足够的GPU内存。

为避免此错误,您可以尝试使用较小的批处理大小来减少GPU上的内存使用量。此外,还要检查Python进程中是否有任何“重影”张量,即已分配但不再使用的张量。