You have a point. However for efficiency most people don’t do what you suggest. Waiting for the next epoch in order to use the new weights is probably not going to slow down training much, whereas repeating the forward pass will nearly double the time needed for each epoch.
If you do want to repeat the forward pass, then you would have to save the hidden state before running the first forward pass in order to use it for the second. Something like this.
for for s_idx in start_idx:
    # prepare sample_v and target_v
    for h in model.hidden:
        h.detach_() # tells PyTorch not to backpropagate furthur back into the past
    # model.hidden = [Variable(h.data) for h in model.hidden] # would work too
    
    old_hidden = [h.clone() for h in model.hidden]
    
    # do a forward pass and update the weights
    
    # redo a forward pass with the new weights
    model.hidden = old_hidden
    model(sample_v)