Hi,
Here is a self contained example to show the behaviour.
Removing the clone in the custom identity shows the behaviour that you describe right?
import torch
from torch import nn
from torch.autograd import Variable
from collections import OrderedDict

def print_grad(mod):
    def tmp(*args):
        print("grad for {}".format(mod))
        print(args)
    return tmp

class Identity(nn.Module):
    def forward(self, inp):
        # Remove the following line to get weird behavior
        inp = inp.clone()
        return inp

model = nn.Sequential(OrderedDict([('lin1', nn.Linear(2, 4)),
                                   ('relu1', nn.ReLU(inplace=True)),
                                   ('ef1', Identity()),
                                   ('lin2', nn.Linear(4, 3)),
                                   ('relu2', nn.ReLU(inplace=True)),
                                   ('ef2', Identity()),
                                   ('lin3', nn.Linear(3, 2))
                               ]))

model.relu1.register_backward_hook(print_grad("relu1"))
model.ef1.register_backward_hook(print_grad("ef1"))

dummy = Variable(torch.rand(5, 2))
target = Variable(torch.rand(5).zero_().long())
y_hat = model(dummy)
loss_fn = nn.CrossEntropyLoss()
loss = loss_fn(y_hat, target)
loss.backward()