F.log_softmax expects logits which might have arbitrarily large and small numbers.
If you just call F.softmax on your input tensor, you’ll see that the probability is not exactly one for the desired class:
x = torch.zeros(1, 21)
x[0, 3] = 1.
print(F.softmax(x, 1))
> tensor([[0.0440, 0.0440, 0.0440, 0.1197, 0.0440, 0.0440, 0.0440, 0.0440, 0.0440,
         0.0440, 0.0440, 0.0440, 0.0440, 0.0440, 0.0440, 0.0440, 0.0440, 0.0440,
         0.0440, 0.0440, 0.0440]])

As you can see, class3 has a probability of 0.1197, so you’ll get a positive loss.