pytorch如何确保每次实验可重复性(每次训练测试结果相同)(模型每次结果也不一样的问题解决方法)(固定随机种子等操作)

本文介绍了影响深度学习模型训练可复现性的四个关键因素:设置随机种子、使用确定性算法、DataLoader设置和数据集排序。通过详细的操作步骤,帮助开发者提高实验的可重复性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

影响可复现的因素主要有这几个:
1、随机种子
2、训练使用不确定的算法
CUDA卷积优化——CUDA convolution benchmarking
Pytorch使用不确定算法——Avoiding nondeterministic algorithms
3、数据加载DataLoader
4、自己代码是否使用随机排列数据集

1跟2,直接复制下面的代码,全网最全(自认为)

# 固定随机种子等操作
            seed_n = 42
            print('seed is ' + str(seed_n))
            g = torch.Generator()
            g.manual_seed(seed_n)
            random.seed(seed_n)
            np.random.seed(seed_n)
            torch.manual_seed(seed_n)
            torch.cuda.manual_seed(seed_n)
            torch.cuda.manual_seed_all(seed_n)
            torch.backends.cudnn.deterministic=True
            torch.backends.cudnn.benchmark = False
            torch.backends.cudnn.enabled = False
            torch.use_deterministic_algorithms(True)
            os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':16:8'
            os.environ['PYTHONHASHSEED'] =
<think>嗯,用户问的是PyTorch多卡训练时保存的模型参数和原始参数一样问题。首先,我需要理解用户的问题到底是什么。可能他们在多卡训练后保存模型,发现参数和单卡训练同,或者保存的方式有问题? 首先,PyTorch多卡训练主要有两种模式:DataParallel(DP)和DistributedDataParallel(DDP)。用户可能用了其中一种,但保存模型时没处理好。 对于DataParallel的情况,模型会被包装在DataParallel类里,这时候模型的实际参数会被放在module属性下。如果直接保存model.state_dict(),会会有问题?比如,保存的是带有module.前缀的参数名,而原始单卡模型没有这个前缀。这样在加载时,单卡模型会因为参数名匹配而报错。这时候需要处理参数名的前缀问题,或者在保存时通过model.module.state_dict()来获取正确的参数。 然后是DDP的情况,DDP每个进程可能只处理一部分参数,但保存的时候是否需要只在主进程保存?如果每个进程都保存,可能会有重复或者冲突。另外,DDP的参数同样被包裹在module里,所以同样存在参数名前缀的问题。这时候应该用model.module.state_dict()来保存,避免参数名错误。 另外,用户可能是在多卡训练后,想将模型部署到单卡上,这时候如果处理参数名前缀,加载就会失败。需要指导用户如何正确保存和加载,比如在保存时去掉module.前缀,或者在加载时加上。 还有可能用户遇到的问题是,多卡训练时使用了同的参数初始化方式,导致参数一致?过这种情况比较少见,更多可能还是参数名的问题。 总结下来,用户的问题可能出在两个方面:参数名前缀的处理和多卡训练保存模型的最佳实践。需要分步骤解释原因,并提供解决方案,比如正确使用model.module.state_dict(),以及在DDP中如何控制保存的进程。</think>在PyTorch多卡训练中,保存的模型参数与单卡训练参数一致的问题通常与模型封装方式和参数命名规则相关。以下是关键问题解析及解决方案: --- ### **1. 核心问题模型封装导致的参数名变化** 当使用`DataParallel`或`DistributedDataParallel`时,模型会被自动封装,导致参数名称中添加了`module.`前缀。 #### **示例对比:** - **原始单卡模型参数名**: ```python {'conv1.weight': ..., 'fc.bias': ...} ``` - **多卡训练后参数名**: ```python {'module.conv1.weight': ..., 'module.fc.bias': ...} ``` --- ### **2. 具体原因分析** #### **(1) DataParallel (DP) 模式** - 模型被包装为`DataParallel`对象,参数路径变为`module.*` - **错误保存方式**: ```python torch.save(model.state_dict(), 'dp_model.pth') # 参数名包含`module.` ``` #### **(2) DistributedDataParallel (DDP) 模式** - 同样存在`module.`前缀问题 - 需注意多进程保存时的竞态条件 --- ### **3. 解决方案** #### **(1) 统一参数名称** 通过`model.module.state_dict()`直接访问原始模型参数: ```python # 保存代码 if isinstance(model, (DataParallel, DistributedDataParallel)): state_dict = model.module.state_dict() else: state_dict = model.state_dict() torch.save(state_dict, 'model.pth') ``` #### **(2) DDP模式下的进程控制** 仅允许rank 0进程保存模型: ```python if torch.distributed.get_rank() == 0: torch.save(model.module.state_dict(), 'ddp_model.pth') ``` #### **(3) 加载时的兼容处理** 若已保存含`module.`前缀的参数,可通过重映射加载: ```python # 加载到单卡 state_dict = torch.load('dp_model.pth') new_state_dict = {k.replace('module.', ''): v for k, v in state_dict.items()} model.load_state_dict(new_state_dict) ``` --- ### **4. 完整代码示例(DDP模式)** ```python import torch.distributed as dist def save_checkpoint(model, path): if dist.get_rank() == 0: # 仅主进程保存 state_dict = model.module.state_dict() # 关键:去掉封装 torch.save(state_dict, path) ``` --- ### **5. 验证方法** ```python # 保存后检查参数名 print(list(torch.load('model.pth').keys())) # 应显示无module.前缀 ``` 通过正确处理模型封装层级,即可保证多卡/单卡参数的一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值