Based on your model architecture, it’s expected that only self.prior will get gradients, as the loss calculation is dependent on these parameters only.
In Glow.forward:
    zero = torch.zeros_like(out)
    mean, log_sd = self.prior(zero).chunk(2, 1)
    log_p = gaussian_log_p(out, mean, log_sd)
    log_p = log_p.view(b_size, -1).sum(1)

    return out, logdet, log_p, mean, torch.exp(log_sd)

Here you are creating a new tensor via zeros_like, which doesn’t have any history and pass it to self.prior. The output will now have a valid grad_fn.
In the next line (gaussian_log_p) the out tensor is used, so it would probably attach all previous modules to the graph.
However, the loss calculation only depends on the last two return values:
    z, logdet, prior_logprob, mu, sigma = model(x)

    #Custom Loss Function
    loss = bhatta_loss(mu, sigma, target)

which are coming from self.prior only.
After the backward call, you could add:
for name, param in model.named_parameters():
    print(name, param.grad)

and would see that all other parameters have a None gradient.
Calling e.g. z.mean().backward() would create gradients for all parameters (this was only a test to check, if this tensor is also detached from the previous operations).