Here in your code 12 you’re setting
def hook_function(module, grad_in, grad_out):
    self.gradients = grad_in[0]

I think this happens on each GPU, so in the end you only get one-fourth of what you should have gotten (assuming 4 gpus).
You can try defining self.gradients as a python list, and then appending to it:
def hook_function(module, grad_in, grad_out):
    self.gradients.append(grad_in[0])