PyTorch 随机种子怎么设置?用两次训练核对可重复性

同时控制模型初始化与 DataLoader 乱序,用两次同种子运行比较顺序、损失和参数,再用不同种子对照;说明跨设备和版本的复现边界。

PyTorch 固定随机种子后,先核对三件事:样本顺序是否一样、训练损失序列是否一样、最终参数是否一样。只看到“设了 torch.manual_seed(7)”不能证明结果可重复,因为数据加载、Python 或 NumPy 随机数以及某些算子还可能引入变化。

PyTorch 2.8 可重复性说明明确指出,跨版本、平台以及 CPU/GPU 执行的完全一致结果不受保证。下面只验证同一软件环境、同一 CPU 玩具代码运行两次的结果,读者应按自己的任务建立对照。

PyTorch 随机种子怎么设置?用两次训练核对可重复性

先把随机源和实验条件写清楚

对象 本例做法 实际项目还要检查
模型初始化 创建模型前调用 torch.manual_seed 调用顺序、随机初始化的额外层
样本乱序 DataLoader 使用单独 torch.Generator 分布式采样器、数据增强、多 worker
Python 随机数 调用 random.seed 预处理或采样代码是否使用 random
算子行为 启用确定性算法检查 是否存在不支持确定性实现的操作

每次运行都在创建模型和读取器之前重新设种子;不要在每个小批次开头反复设成同一个值,否则可能让原本应变化的数据增强或随机掩码不断重复。

跑两次同种子,再加一个不同种子的对照

以下完整脚本在 Windows、Python 3.11.15、PyTorch 2.8.0+cpu、NumPy 2.3.3 环境实际运行通过,只验证这个 CPU 玩具任务。它不下载模型权重,也不代表真实模型的精度、速度或显存表现。在已启用的独立 Python 环境中可安装相同依赖:

python -m pip install torch==2.8.0 --index-url https://download.pytorch.org/whl/cpu
python -m pip install numpy==2.3.3

保存为 seed_demo.py,运行 python seed_demo.py。样本通过固定公式生成,不涉及真实业务数据;DataLoader 的 num_workers=0,避免把 Windows 多进程启动细节混进这个最小验证。

import random
import torch
from torch.utils.data import DataLoader, TensorDataset

torch.set_num_threads(1)
torch.use_deterministic_algorithms(True)
x = torch.linspace(-1, 1, 12).reshape(-1, 1)
y = 2 * x + 0.5
indices = torch.arange(len(x))

def run(seed):
    random.seed(seed)
    torch.manual_seed(seed)
    data_rng = torch.Generator().manual_seed(seed)
    loader = DataLoader(TensorDataset(x, y, indices), batch_size=4,
                        shuffle=True, generator=data_rng, num_workers=0)
    model = torch.nn.Linear(1, 1)
    opt = torch.optim.SGD(model.parameters(), lr=0.1)
    losses, order = [], []
    for _ in range(2):
        for xb, yb, ids in loader:
            order.extend(ids.tolist())
            opt.zero_grad(set_to_none=True)
            loss = torch.nn.functional.mse_loss(model(xb), yb)
            loss.backward()
            opt.step()
            losses.append(loss.item())
    return order, losses, [p.detach().clone() for p in model.parameters()]

a, b, changed = run(7), run(7), run(8)
print("same_sample_order:", a[0] == b[0])
print("same_losses:", a[1] == b[1])
print("same_parameters:", all(torch.equal(p, q) for p, q in zip(a[2], b[2])))
print("different_seed_changes_order:", a[0] != changed[0])
assert a[0] == b[0] and a[1] == b[1]
assert all(torch.equal(p, q) for p, q in zip(a[2], b[2]))

怎样解读运行结果

本次 CPU 运行输出为:

same_sample_order: True
same_losses: True
same_parameters: True
different_seed_changes_order: True

同一个种子,两次运行的样本顺序、损失列表和参数都相同;换成另一个种子后,样本顺序发生变化。读者应在自己的训练函数外调用两次独立运行,保存顺序或样本 ID、原始损失和参数,然后按允许的数值误差比较,不要只比较四舍五入后的最后一个指标。

这个结果证明的是当前玩具程序的条件得到控制,不代表任何模型跨电脑、跨 GPU 或升级 PyTorch 后都会重现相同参数;验证指标相同也不保证参数完全一致。

增加 NumPy、多个 worker 或 CUDA 时怎样补齐

如果预处理使用 NumPy,全局随机数可设 numpy.random.seed(seed);新建的 numpy.random.default_rng(seed) 是独立生成器,应把 seed 或已有生成器明确传入。只设全局 seed 不会控制所有独立 Generator。

DataLoader 增加 num_workers 时,可在 worker_init_fn 中用 torch.initial_seed() % 2**32 初始化每个 worker 的 NumPy 和 Python 随机数,同时保留读取器的 generator;对应写法见前述官方文档。Windows 使用多进程时还要把入口放进 if __name__ == “__main__”,本文脚本保持单进程。

使用 CUDA 时,核对 cuDNN benchmark、确定性算子支持和文档要求的环境设置。torch.use_deterministic_algorithms(True) 遇到没有可用确定性实现的操作可能报错;这时先定位算子和对应版本说明,不能捕获后静默忽略错误并声称实现了确定性训练。确定性模式也可能带来性能代价。

常见问题:重复了,是不是就能证明实验结论可靠?

不能。单个种子可重复只是调试基础;正式实验还需固定数据版本和切分、记录依赖与设备,并用多个事先选定的种子检查结果波动。跨环境复现应比较任务指标及容差,而不是把本文的逐位比较直接当成普遍承诺。本文没有运行多 worker、CUDA、分布式训练或跨版本实验。

Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30330.html

赞 (0)
AI小管家的头像AI小管家
DeepSeek 数据清洗工具怎么用?校验日期和金额并隔离异常行
上一篇 1天前
DeepSeek 如何读取本地文件?先用 Python 提取文本再提供内容
下一篇 1天前

相关推荐

联系我们

联系我们

1

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
关注微信
分享本页
返回顶部