我已经使用torch.nn.DataParallel来使用多GPU训练模型,但我注意到,当我使用两个cuda来计算结果时,它与使用单个cuda或cpu不同。这是奇怪的,我不知道为什么,请告诉我如何解决它或解释它。
PyTorch:2.0.0+cu117
CUDA版本:12.0
你可以使用下面的代码来重现这个问题,它会打印这样,多卡结果与单卡结果或CPU结果有很大不同。
0.436291307 | 0.307008564 | 0.307096988 |
0.618099451 | 0.502333581 | 0.498412549 |
-0.230154008 | -0.209866986 | -0.206241921 |
-0.556713521 | -0.558704913 | -0.555095673 |
-0.30781576 | -0.209164187 | -0.211295918 |
-0.410598308 | -0.512709379 | -0.513415456 |
0.298149496 | 0.474029034 | 0.468837589 |
-0.270193249 | -0.148075178 | -1.52E-01 |
-0.05058343 | -0.017191991 | -0.019832365 |
0.619232118 | 6.59E-01 | 6.56E-01 |
-0.036778659 | -0.135650381 | -0.132507876 |
import torch
import torchvision
def load_data(num_gpus):
transforms = torchvision.transforms.Compose([
torchvision.transforms.Resize(256),
torchvision.transforms.CenterCrop(224),
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
# dataset = torchvision.datasets.ImageFolder(root='datasets/cifar-10-python.tar.gz', transform=transforms)
dataset = torchvision.datasets.CIFAR10('datasets', train=True, transform=transforms,download=True)
dataloader = torch.utils.data.DataLoader(
dataset=dataset,
batch_size=64,
shuffle=False,
num_workers=4*num_gpus
)
return dataloader
model = torchvision.models.resnet50(pretrained=False)
model = model.cuda()
model = torch.nn.parallel.DataParallel(model, device_ids=[0,1], dim=0)
dataloader = load_data(2)
m_s = model.module.state_dict()
model1 = torchvision.models.resnet50(pretrained=False)
model1.load_state_dict(m_s)
model2 = torchvision.models.resnet50(pretrained=False)
model2.load_state_dict(m_s)
model2 = model2.to('cuda:2')
for images, labels in dataloader:
break
multi_gpu = model(images.cuda())
cpu_predict = model1(images)
s_gpu = model2(images.to('cuda:2'))
a = multi_gpu.reshape(-1).cpu()
b = cpu_predict.reshape(-1)
c = s_gpu.reshape(-1).cpu()
for i,j,k in zip(a,b,c):
print(i.item(),j.item(),k.item())
这是因为你没有调用
eval()
函数。 dropout
层是一个随机过程。在每次运行中,输出将根据您的预设概率随机设置为 0。除非您调用 eval()
函数来禁用此行为,否则我敢打赌您的模型在每次运行后都会输出不同的结果,即使它们使用相同的设备。