One difference would be the loss scale, since you are using the mean reduction in the first approach and a sum in the latter. Also, the latter trains for 1000 epochs with the entire dataset (all 2000 samples), while the former approach trains a single epoch with a single sample per batch in each iteration.
When running your second code the model converged 3 out of 10 times (the other 7 runs were giving NaN losses).
After fixing the differences (there might be more) the first code snippet converged ~5 out of 10 times, so it seems both approaches are equally stable/unstable.