I get the same results, if I try to make sure to use the same calls into the PRNG:
torch.manual_seed(2809)
modelA = ResNet(BasicBlock, [2, 2, 2, 2], 1000)
in_ = modelA.fc.in_features
classes = 10
modelA.fc = nn.Linear(in_features=in_, out_features=classes)
torch.manual_seed(2809)
modelB = ResNet(BasicBlock, [2, 2, 2, 2], 1000)
in_ = modelB.fc.in_features
classes = 10
modelB.fc = nn.Linear(in_features=in_, out_features=classes)

torch.manual_seed(2809)
modelC = models.resnet18()
in_ = modelC.fc.in_features
modelC.fc = nn.Linear(in_features=in_, out_features=classes)


x = torch.randn(8, 3, 224, 224)

outA = modelA(x)
outB = modelB(x)
outC = modelC(x)
print((outA - outB).abs().max())
> tensor(0., grad_fn=<MaxBackward1>)

print((outA - outC).abs().max())
> tensor(0., grad_fn=<MaxBackward1>)

In your example you are using modelC = ResNet(BasicBlock, [2, 2, 2, 2], 10), which will directly create a linear layer with 10 output classes.
While it’s a valid approach for your use case, this will break the comparison using seeds, since the calls to the PRNG in the torchvision implementation are:
-> init layer1
-> init layer2
...
-> init fc with 1000 output classes
-> init custom nn.Linear with 10 output classes

while you would skip the penultimate step.
If you use my code, you should get the same results.
That being said, I would recommend not to use the seeding approach to compare models, as you would need to be familiar which layers are initialized in which order.
The better approach is just to load the state_dict from one model into the other and test both models.