alvations:

predictions = model(X)
loss = criterion(predictions, Y)


These two lines create a chain on operations linking your model and the loss applied to the output.
When you do loss.backward(), the autograd engine computes the gradient of the loss with respect to each weight in your forward graph and populates the .grad attribute.
So these values are added during the .backward() call and NOT the .step() call.
The role of the .step() call is to update the weights according to the optimiser you have defined.