You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BERT下一句预测(NSP)代码每次运行输出随机结果问题排查

问题原因与修复方法

你每次运行得到不同损失、不同推理结果,是两个核心配置遗漏导致的,不存在NSP任务逻辑层面的代码错误:

  • 未全局固定所有随机源的随机种子
    你的代码从数据集构造阶段就存在大量随机逻辑:包括正样本对的起始位置选择、50%概率采样正负样本、负样本的随机选取、DataLoader的批次打乱,再加上PyTorch、CUDA本身的随机数生成器,所有这些环节默认每次运行都会生成不同的随机值,直接导致每次训练的数据集组成、批次顺序、参数更新路径都不一样,损失和最终权重自然有差异。
    你需要在所有代码逻辑执行的最开头(导入完依赖之后)加入固定种子的代码:

    import random
    import numpy as np
    import torch
    
    seed = 42
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False
    

    如果后续你给DataLoader设置了大于0的num_workers开启多进程加载,还需要额外给DataLoader传入worker_init_fn参数固定每个子进程的种子,避免多进程带来的随机波动。如果你使用PyTorch 1.8以上版本,也可以额外加一行torch.use_deterministic_algorithms(True)开启全局确定性算法,进一步避免个别算子的非确定计算带来的结果差异。

  • 推理阶段未切换模型到评估模式
    你训练完之后直接执行推理,此时模型还处于model.train()开启的训练模式,BERT结构中内置的Dropout层会随机失活部分神经元,哪怕输入完全相同、模型权重完全一致,前向计算的输出也会随机波动。
    推理前需要先切换模型到评估模式,同时关闭梯度计算减少额外开销:

    # 推理前必须先执行这行切换模式
    model.eval()
    
    # 推理代码放在no_grad上下文中
    with torch.no_grad():
        prompt = "sentence 1 text"
        prompt2 = "sentence 2 text"
        output = tokenizer.encode_plus(prompt,prompt2, return_tensors="pt").to(device)
        result = model(**output)[0]
        prob = softmax(result, dim=1)
        print(prob)
    

完成以上两个修改后,你每次运行的训练损失变化、最终模型权重、相同输入的推理概率输出都会完全一致,符合可复现要求。

内容的提问来源于stack exchange,提问作者not_yet_a_fds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 09:33:41