You shouldn’t use a softmax on the model outputs when you want to calculate the loss using nn.CrossEntropyLoss, since (as you’ve already said) nn.CrossEntropyLoss applies F.log_softmax and nn.NLLLoss internally, so pass the raw logits to this loss function instead.
On the other hand, you can apply a softmax on the model outputs (logits), if you want to “visualize” the probabilities or use them in any other way besides the input to nn.CrossEntropyLoss.