final_loss.backward() would calculate the gradients but there are some strange things in your scheme (these may seem strange due to lack of information in your question):
The first strange this is: why having two separate optimizers? It could only be justified if you purposely want different optimization algorithms for each network.
The second and most strange thing is: why would you want to have a combined loss? The only reason that comes to my mind would be that
module2 share some parameters. Otherwise, I see no point in combining two totally unrelated losses because they could have different scales, leading to one of the partial losses to have little effect. Minimizing each loss separately would lead to a much better result.