retain_graph=True might be the cause of the OOM issue, as it will force Autograd to keep the computation graph alive (and will thus use more memory than in the default use case).
To clear the intermediate tensors, the last backward call should use retain_graph=False.
Note that you are currently accumulating the gradients, as you are calling output.backward() for each parameter, while setting the requires_grad attribute of a single parameter to False.