To answer your first question: you  need to specify retain_graph=True in your first backward-call when using multiple losses for one output and backwarding them separately. Otherwise the gradient graph will be destroyed during your first backward-call and you will be unable to use the second loss.
Whether or not these approaches are equal depends on how you are using the optimizer. If you call optim.zero_grad() between the backward calls these approaches are not equivalent but if you don’t do so that they are since gradients are per default accumulated in Pytorch.