thanks for the reply;
based on your code,
if we change  loss_w_grad = (w_grad**2).mean()
to
loss_w_grad = ((w_grad+loss_w)**2).mean() by introducing the first loss function
so our code
loss_w.backward(retain_graph=True)
w_grad = w.grad.clone()

w_grad.requires_grad_(True)

loss_w_grad = ((w_grad+loss_w)**2).mean()

loss_w_grad.backward() 

It makes me wonder that whether loss_w_grad.backward() differentiate w_grad but rather it as constant.
Because in my original code it would
z = function(x) # function involves a parameter called phi
f_z = Net(z) #neural net
der_shape = torch.ones(f_z.size())
f_z.backward(der_shape ,retain_graph=True) 
d_phi = phi.grad().clone()
d_phi.requires_grad_(True)
phi.grad.data.zero_()

g = f_z + d_phi

phi.data.sub_(0.01*g) # update phi

variance_loss = (g ** 2).mean() 

var_opt.zero_grad() # here var_opt = torch.optim.Adam(Net().parameters(), lr=0.01)
variance_loss.backward()
var_opt.step()

d_phi.grad.data.zero_()

it turns out that the results would be SAME for both d_phi.requires_grad_(True) and d_phi.requires_grad_(False) (need to comment out d_phi.grad.data.zero_()). So I just think that variance_loss.backward() only backpro on f_z; the value of d_phi has no influence of second backward().
My second backward() is focus on differentiate variance_loss w.r.t. parameters of neural net