Hi,
The difference is that in the first case, you have a single Function in the computational graph: LinearFunction, and so the backward will just call the backward for that Function.
In the second case, the computational graph contain few Functions: mm, transpose, addition, unsqueeze, expand…  This means that the backward pass will require to traverse all these functions and call the backward for each of them. Moreover to be able to perform this backward pass, all  intermediary results in between them will be saved in memory.
The first one is thus more efficient both speed and memory wise, but it requires you to implement the backward method by hand. The second one pay the cost of using the autograd to get the gradients without implementing the backward method explicitly.