Three ways to say "don't track gradients here"
Most of the time you want autograd recording. Sometimes you don't — during inference, evaluation, preprocessing, metric computation, plotting. Recording costs memory (it has to keep activations around) and a small amount of CPU. Three tools for skipping it:
torch.no_grad()— context manager. No graph is built for any op inside the block. The standard wrapper aroundmodel.eval()code paths.torch.inference_mode()— stronger version of no_grad. Disables both autograd AND view-tracking, slightly faster. The recommended choice for pure inference.tensor.detach()— returns a new tensor that shares storage but is disconnected from the autograd graph. Used for individual tensors (logging loss values, RL target networks) rather than whole code blocks.
The boundary: model.eval() vs no_grad()
These two are related but different:
model.eval()changes module behavior — Dropout becomes a no-op, BatchNorm uses running stats instead of batch stats. It does NOT disable autograd.torch.no_grad()disables autograd. It does NOT change module behavior.
For evaluation you almost always want both: model.eval() for the right behavior, torch.no_grad() (or inference_mode()) for speed.