Hi,
The memory error in your first question is because when you do self.train_loss.append(closure().cpu()) you save both the value of the loss and all the metadata that allows to compute gradients. You can use detach to fix this if you want as well self.train_loss.append(closure().cpu().detach()).
For the seed, you can check the notes on reproducibility but the short answer is that it is very hard to get reproducible results because of how float arithmetic works. And in your case, since you do operations in different orders, it is impossible to get the exact same result.