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

PyTorch DDP单机多GPU训练:训练与测试精度差异问题

问题原因及解决步骤

这种差异几乎肯定是训练循环内的精度计算逻辑没有适配DDP的分布式环境导致的,核心是你没正确统计全局的训练样本和正确预测数,具体原因和修复方法如下:

  • 未同步各GPU的统计数据
    DDP中每个GPU只处理全局batch的一个子集,如果你在每个GPU上单独计算准确率再取平均,得到的结果和全局真实准确率会有偏差(极端情况下就会出现你这种极低的数值)。正确的做法是:

    1. 每个GPU计算自己的局部正确预测数(correct_local)和局部样本数(total_local)
    2. 使用torch.distributed.all_reduce把所有GPU的correct_local和total_local汇总到主GPU(或所有GPU)
    3. 用汇总后的总数计算全局训练准确率,而不是直接平均各GPU的准确率

    示例代码片段:

    # 每个GPU计算局部统计
    pred = torch.argmax(output, dim=1)
    correct_local = pred.eq(target).sum()
    total_local = target.size(0)
    
    # 同步所有GPU的统计值
    torch.distributed.all_reduce(correct_local, op=torch.distributed.ReduceOp.SUM)
    torch.distributed.all_reduce(total_local, op=torch.distributed.ReduceOp.SUM)
    
    # 计算全局准确率(仅主GPU打印即可)
    if torch.distributed.get_rank() == 0:
        train_acc = correct_local.item() / total_local.item()
        print(f"Train Accuracy: {train_acc:.4f}")
    
  • 训练时计算精度未处理BN层的行为
    训练循环内模型处于train()模式,BN层会使用当前batch的均值和方差,而测试时模型切换到eval()模式用累计的全局统计值。如果你的训练精度计算逻辑没有暂时切换模型模式,可能会因为BN层的不稳定输出导致预测结果偏差(虽然这个影响通常不会这么极端,但也是潜在因素)。修复方法是:
    在计算训练精度前临时切换到eval()模式,计算完成后切回train():

    model.eval()
    with torch.no_grad():
        # 计算训练精度的代码
        ...
    model.train()
    
  • 误将单GPU的局部结果当作全局结果
    如果你只打印了主GPU的局部准确率,而主GPU恰好分到了难分类的样本子集,就会出现看似全局精度极低的情况。但你说的是8块GPU平均后的结果,所以更可能是第一种同步问题。

另外,确认你保存模型时是用model.module.state_dict()(DDP封装后的模型要取module的参数),这点你已经做到了,因为测试精度正常,说明模型参数保存正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 12:26:23