GPU memory keep increasing as iterating epoch

username: Jerry_h
cooked: <p>The memory of GPU just keep increasing with iterations. I just post the reproducible code.<br>
environment:</p>
<pre><code class="lang-bash">pytorch: 1.5.1
GPU: 1080Ti
</code></pre>
<pre><code class="lang-python">import torch.nn as nn
import torch
from collections import OrderedDict
import torch.nn.functional as F

class _DenseLayer(nn.Sequential):

    def __init__(self, num_input_features, growth_rate, bn_size, drop_rate):
        super(_DenseLayer, self).__init__()

        self.add_module('norm1', nn.BatchNorm2d(num_input_features))
        self.add_module('relu1', nn.ReLU(inplace=True))
        self.add_module('conv1', nn.Conv2d(num_input_features, bn_size * growth_rate,
                                           kernel_size=1, stride=1, bias=False))

        self.add_module('norm2', nn.BatchNorm2d(bn_size * growth_rate))
        self.add_module('relu2', nn.ReLU(inplace=True))
        self.add_module('conv2', nn.Conv2d(bn_size * growth_rate, growth_rate,
                                           kernel_size=3, stride=1, padding=1, bias=False))

        self.drop_rate = drop_rate

    def forward(self, x):
        # print(f"{self.__class__.__name__}: \nInput shape {x.shape}")
        new_features = super(_DenseLayer, self).forward(x)
        if self.drop_rate &gt; 0:
            new_features = F.dropout(new_features, p=self.drop_rate, training=self.training)
        new_features = torch.cat([x, new_features], 1)
        # print(f"output shape{output.shape}")
        return new_features


class _DenseBlock(nn.Sequential):

    def __init__(self, num_layers, num_input_features, bn_size, growth_rate, drop_rate):
        '''
        :param num_layers:  number of layers in every block.
        :param num_input_features: the channel of input data.
        :param bn_size:
        :param growth_rate:
        :param drop_rate:
        '''
        super(_DenseBlock, self).__init__()
        for i in range(num_layers):
            layer = _DenseLayer(num_input_features + i * growth_rate, growth_rate, bn_size, drop_rate)
            self.add_module('denselayer%d' % (i + 1), layer)


# Transition layer
class _Transition(nn.Sequential):
    '''Transition layer between two adjacent DenseBlock'''

    def __init__(self, num_input_features, num_output_features):
        super(_Transition, self).__init__()
        self.add_module('norm', nn.BatchNorm2d(num_input_features))
        self.add_module('relu', nn.ReLU(inplace=True))
        self.add_module('conv', nn.Conv2d(num_input_features, num_output_features,
                                          kernel_size=1, stride=1, bias=False))
        self.add_module('pool', nn.AvgPool2d(2, stride=2))


# densenet
class DenseNetTrail5D(nn.Module):
    '''DenseNet-BC model'''

    def __init__(self, init_channels=4, growth_rate=32, block_config=(6, 12, 24, 16), num_init_features=64,
                 bn_size=4, compression_rate=0.5, drop_rate=0, num_classes=1000):
        """

        :param growth_rate: (int) number of filters used in DenseLayer, `k` in the paper
        :param block_config: (list of 4 ints) number of layers in each DenseBlock
        :param num_init_features: (int) number of filters in the first Conv2d
        :param bn_size: (int) the factor using in the bottleneck layer
        :param compression_rate: (float) the compression rate used in Transition Layer
        :param drop_rate: (float) the drop rate after each DenseLayer
        :param num_classes: (int) number of classes for classification
        """
        super(DenseNetTrail5D, self).__init__()
        # first conv2d
        self.features = nn.Sequential(
            OrderedDict([
                ('conv0', nn.Conv2d(init_channels, num_init_features, kernel_size=3, stride=1, padding=1, bias=False)),
                ('norm0', nn.BatchNorm2d(num_init_features)),
                ('relu0', nn.ReLU(inplace=True)),
                ('pool0', nn.MaxPool2d(3, stride=1, padding=1))
            ])
        )

        # Dense block
        num_features = num_init_features
        for i, num_layers in enumerate(block_config):
            block = _DenseBlock(num_layers, num_features, bn_size, growth_rate, drop_rate)
            self.features.add_module('denseblock%d' % (i + 1), block)
            num_features += num_layers * growth_rate
            if i != len(block_config) - 1:
                transition = _Transition(num_features, int(num_features * compression_rate))
                self.features.add_module('transition%d' % (i + 1), transition)
                num_features = int(num_features * compression_rate)

        # final bn + ReLU
        self.features.add_module('norm5', nn.BatchNorm2d(num_features))
        self.features.add_module('relu5', nn.ReLU(inplace=True))

        # classification layer
        # self.classfier = nn.Linear(num_features, num_classes)
        self.linear = nn.Sequential(
            nn.Linear(3200, 1),
        )

        # params initialization
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.bias, 0)
                nn.init.constant_(m.weight, 1)
            elif isinstance(m, nn.Linear):
                nn.init.constant_(m.bias, 0)

    def forward(self, x):
        features = self.features(x.view(-1, 5, 13, 40, 40).permute(0, 2, 3, 1, 4).reshape(-1, 13, 40, 200))
        out = F.avg_pool2d(features, (3, 9), padding=(1, 0), stride=(1, 4)).view(features.size(0), -1)
        out = self.linear(out)

        return out

if __name__ == '__main__':
    from torchsummary import summary
    import torch
    sample = torch.randn((64, 5, 13*1600))
    model = DenseNetTrail5D(13, block_config=(2, 2, 2, 2))
    model = model.cuda()
    # with torch.no_grad():
    for i in range(5):
        print(i)
        y = model(sample.cuda()).cpu()
</code></pre>
<p>Any help is appreciated~</p>

username: ptrblck
cooked: <p>I cannot reproduce this issue locally using a nightly binary from ~3 weeks ago.<br>
If I run the model for 50 iterations and print the allocated device memory via <code>print(torch.cuda.memory_allocated())</code>, it seems to move between ~3521MB and ~3523MB.</p>
<p>How large is the increase in memory in your use case and are you eventually running out of memory?</p>

username: Jerry_h
cooked: <p>i just run it again and cannot reproduce this issue either. maybe just some weird thing happened. Thanks for your time and replay~ <img src="https://discuss.pytorch.org/images/emoji/apple/joy.png?v=9" title=":joy:" class="emoji" alt=":joy:"></p>