If you use momentum or weight decay (from the optimizer), you will get changing parameters even when the grad has the numerical value 0.
Optimizers do special case None gradients to mean “do nothing”, but that isn’t available for parts of a parameter, but in your example model.conv1.weight.grad = None would do the trick.
Best regards
Thomas