I was able to track down my bug! It turns out that I tried to set the input tensor’s requires_grad = True, but managed to do it in a way that didn’t actually set requires_grad =True. Essentially, I created a tensor with requires_grad = True, then passed that through a nn.transform module, and only then assigned it my candidate variable. It looked something like this:
candidate = transform.ToPILImage()(torch.rand(C, W, H, requires_grad = True))

Which to me as a beginner seemed fine, but resulted in candidate not actually having requires_grad be True.
Just thought I’d post this in case some other poor soul falls into the same trap I did and manages to serendipitously happen across this exact forum post.