Unfortunately there is no guaranty that two models with the same architecture will converge to exactly the same solution.
Also keep in mind that to train your network, you want the gradients wrt the weights. Not the input or activations. So your use of modelB might not be right. In particular, the gradients wrt the weights are given by dL/dy dy/dparams = dL/dy * input for a Linear layer.
A simpler check for this could be:
initialize modelF
initialize modelB with transpose of modelF
initialize modelC with modelF

Get a single sample
do a forward / backward in modelC
do forward in modelF, modelB
check the values computed by modelB and the .grad in modelC