with torch.no_grad() would work, if you don’t need any gradients in parameters, which are used before this block, since the no_grad() guard would not create the computation graph for this section.
Here is a small example:
# setup
lin1 = nn.Linear(1, 1)
lin2 = nn.Linear(1, 1)
lin3 = nn.Linear(1, 1)

x = torch.randn(1, 1)

# case1
with torch.no_grad():
    out = lin1(x)
    out = lin2(out)
out = lin3(out)
out.mean().backward()

print(lin1.weight.grad, lin2.weight.grad, lin3.weight.grad)
> None None tensor([[-0.8122]])
lin1.zero_grad(), lin2.zero_grad(), lin3.zero_grad()

# case2
out = lin1(x)
with torch.no_grad():
    out = lin2(out)
out = lin3(out)
out.mean().backward()

print(lin1.weight.grad, lin2.weight.grad, lin3.weight.grad) # !!! lin1 doesn't have grads !!!
> None None tensor([[-0.8122]])
lin1.zero_grad(), lin2.zero_grad(), lin3.zero_grad()

# case3
for param in lin2.parameters():
    param.requires_grad = False

out = lin1(x)
out = lin2(out)
out = lin3(out)
out.mean().backward()
print(lin1.weight.grad, lin2.weight.grad, lin3.weight.grad)
> tensor([[-0.0768]]) None tensor([[-0.8122]])