After the first call to train, hidden becomes a tensor that has requires_grad=True and is a part of the computation graph.
During the second call to train, the backward step tries to propagate gradients through hidden. However, since we already did a backward(), the computation graph of hidden doesn’t exist anymore.
Perhaps you did not mean to propagate gradients through hidden during the second call to train? Something like the following:
hidden, loss = train(torch.tensor([[[inputs[i]]]]), torch.tensor([[[targets[i+1]]]]))
hidden = hidden.detach_()  # detach it from the computation graph for the next iteration of training