Heizkessel:

states.requires_grad_(True)


I think you do not require gradient to states variable. Commenting this line will make the code work.
Why .detach()ing works?
This is my understanding. You are using the same variable (states) that is having requires_grad = True again and again. When you use it for the first time, there is no problem. i.e., when you back propagate, the graph is destroyed on the go and the gradient is accumulated in states.grad buffer.
When you use the states variable second time (I call it states2), this is a variable derived from original states variable. i.e., there is still a link exists to the original states from states2. When you back-propagate through states2, it is still required to pass on the gradients to original states because it has requires_grad=True. But the graph between original states and states2 was already destroyed during first back-propagation. Hence it causes RuntimeError: Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time.
This case is similar to (i.e, same variable usage):

  
    
    
    Using backward cannot calculate grad for input 
  
  
    I would say, try creating a new tensor before forward() call everytime. 
sample_seq = sample_seq.detach().clone()
sample_seq.requires_grad = True
...forward()...

To me, it looks like you are involving the same variable sample_seq in further calculations and its difficult to trace . I am not sure if this is the issue. But you can try.