You don’t need to average the loss before calling loss.backward(). The gradients that are computed on each process are reduced across processes, and upon returning from loss.backward() each process has identical gradients for their model parameters.
Regarding the utilization, check out torchgpipe 203. It might be useful here.