已设置随机种子的PyTorch单Linear层模型每次运行输出不一致原因
问题原因
该问题通常有以下几个常见诱因:
种子配置的执行时机和范围不符合要求
最常见的场景是在Jupyter等交互式环境中运行代码时,仅执行了一次种子配置代码,之后反复执行模型初始化、推理的代码块。PyTorch的随机数状态是全局的,每调用一次随机初始化(比如Linear层的权重初始化)就会消耗一次随机数,改变全局随机状态,下一次再初始化模型时用的就是新的随机状态,自然会得到不同的权重、不同的输出。
验证该问题的方法非常简单:每次运行模型代码前,重新执行一遍所有的种子配置代码,再跑模型初始化和推理,观察输出是否一致。缺少PYTHONHASHSEED环境变量配置
你当前的配置里没有设置Python哈希种子,这个参数需要在Python进程启动前就配置,不能在代码运行时动态设置。如果是在命令行运行代码,需要先执行export PYTHONHASHSEED=76(Linux/macOS)或者set PYTHONHASHSEED=76(Windows)再启动Python脚本;如果是Jupyter环境,需要修改内核启动配置,提前设置这个环境变量。CUDA算子的确定性未完全开启
如果你用的是GPU(device为cuda),仅配置cudnn的参数还不够,部分CUDA算子默认存在非确定性实现。你可以在种子配置代码中添加一行torch.use_deterministic_algorithms(True),强制所有算子使用确定性实现,避免这部分带来的波动。
如果你使用的PyTorch版本较旧,这个API对应为torch.set_deterministic(True),效果一致。
验证方法
你可以把所有代码放在同一个脚本里一次性运行,不要分段执行:
import os import random import torch import numpy as np # 提前设置环境变量,注意这行要放在所有torch相关导入前才生效 os.environ['PYTHONHASHSEED'] = '76' random_seed=76 torch.manual_seed(random_seed) torch.cuda.manual_seed(random_seed) torch.cuda.manual_seed_all(random_seed) torch.backends.cudnn.deterministic = True torch.backends.cudnn.benchmark = False # 开启全局确定性算子 torch.use_deterministic_algorithms(True) np.random.seed(random_seed) random.seed(random_seed) device = 'cuda' if torch.cuda.is_available() else 'cpu' model = torch.nn.Linear(1,1).to(device) x_train1 = torch.FloatTensor([[1], [2], [3]]).to(device) out = model(x_train1) print(out)
多次运行这个完整脚本,输出就会完全一致。
内容的提问来源于stack exchange,提问作者junekk

