Indeed, I understand now. The previous iteration of features remains in memory while model(batch) is evaluated the second time, and so there are points in the execution where two different graphs exist in memory.
You’re right, in inference mode I should be wrapping the call with no_grad.
Would this not happen in a training loop, as the additional backward pass would free the graph?