PyTorch多GPU训练时同步梯度是mean还是sum?

PyTorch 通过两种方式可以进行多GPU训练: DataParallel, DistributedDataParallel. 当使用DataParallel的时候, 梯度的计算结果和在单卡上跑是一样的, 对每个数据计算出来的梯度进行累加. 当使用DistributedDataParallel的时候, 每个卡单独计算梯度, 然后多卡的梯度再进行平均.
下面是实验验证:

DataParallel

import torch
import os
import torch.nn as nn

def main():
    model = nn.Linear(2, 3).cuda()
    model = torch.nn.DataParallel(model, device_ids=[0, 1])
    input = torch.rand(2, 2)
    labels = torch.tensor([[1, 0, 0], [0, 1, 0]]).cuda()
    (model(input) * labels).sum().backward()
    print('input', input)
    print([p.grad for p in model.parameters()])


if __name__=="__main__":
    main()

执行CUDA_VISIBLE_DEVICES=0,1 python t.py可以看到输出, 代码中对两个样本分别求梯度, 梯度等于样本的值, DataParallel把两个样本的梯度累加起来在不同GPU中同步.

input tensor([[0.4362, 0.4574],
        [0.2052, 0.2362]])
[tensor([[0.4363, 0.4573],
        [0.2052, 0.2362],
        [0.0000, 0.0000]], device='cuda:0'), tensor([1., 1., 0.], device='cuda:0')]

DistributedDataParallel

import torch
import os
import torch.distributed as dist
import torch.multiprocessing as mp
import torch.nn as nn
import torch.optim as optim
from torch.nn.parallel import DistributedDataParallel as DDP


def example(rank, world_size):
    # create default process group
    dist.init_process_group("gloo", rank=rank, world_size=world_size)
    # create local model
    model = nn.Linear(2, 3).to(rank)
    print('model param', 'rank', rank, [p for p in model.parameters()])
    # construct DDP model
    ddp_model = DDP(model, device_ids=[rank])
    print('ddp model param', 'rank', rank, [p for p in ddp_model.parameters()])
    # forward pass
    input = torch.randn(1, 2).to(rank)
    outputs = ddp_model(input)
    labels = torch.randn(1, 3).to(rank) * 0
    labels[0, rank] = 1
    # backward pass
    (outputs * labels).sum().backward()
    print('rank', rank, 'grad', [p.grad for p in ddp_model.parameters()])
    print('rank', rank, 'input', input, 'outputs', outputs)
    print('rank', rank, 'labels', labels)
    # update parameters
    optimizer.step()

def main():
    world_size = 2
    mp.spawn(example,
        args=(world_size,),
        nprocs=world_size,
        join=True)

if __name__=="__main__":
    # Environment variables which need to be
    # set when using c10d's default "env"
    # initialization mode.
    os.environ["MASTER_ADDR"] = "localhost"
    os.environ["MASTER_PORT"] = "29504"
    main()

执行CUDA_VISIBLE_DEVICES=0,1 python t1.py可以看到输出, 代码中对两个样本分别求梯度, 梯度等于样本的值, 最终的梯度是各个GPU的梯度的平均.

model param rank 0 [Parameter containing:
tensor([[-0.4819,  0.0253],
        [ 0.0858,  0.2256],
        [ 0.5614,  0.2702]], device='cuda:0', requires_grad=True), Parameter containing:
tensor([-0.0090,  0.4461, -0.3493], device='cuda:0', requires_grad=True)]
model param rank 1 [Parameter containing:
tensor([[-0.3737,  0.3062],
        [ 0.6450,  0.2930],
        [-0.2422,  0.2089]], device='cuda:1', requires_grad=True), Parameter containing:
tensor([-0.5868,  0.2106, -0.4461], device='cuda:1', requires_grad=True)]
ddp model param rank 1 [Parameter containing:
tensor([[-0.4819,  0.0253],
        [ 0.0858,  0.2256],
        [ 0.5614,  0.2702]], device='cuda:1', requires_grad=True), Parameter containing:
tensor([-0.0090,  0.4461, -0.3493], device='cuda:1', requires_grad=True)]
ddp model param rank 0 [Parameter containing:
tensor([[-0.4819,  0.0253],
        [ 0.0858,  0.2256],
        [ 0.5614,  0.2702]], device='cuda:0', requires_grad=True), Parameter containing:
tensor([-0.0090,  0.4461, -0.3493], device='cuda:0', requires_grad=True)]
rank 1 grad [tensor([[ 0.2605,  0.1631],
        [-0.0934, -0.5308],
        [ 0.0000,  0.0000]], device='cuda:1'), tensor([0.5000, 0.5000, 0.0000], device='cuda:1')]
rank 0 grad [tensor([[ 0.2605,  0.1631],
        [-0.0934, -0.5308],
        [ 0.0000,  0.0000]], device='cuda:0'), tensor([0.5000, 0.5000, 0.0000], device='cuda:0')]
rank 1 input tensor([[-0.1868, -1.0617]], device='cuda:1') outputs tensor([[ 0.0542,  0.1906, -0.7411]], device='cuda:1',
       grad_fn=<AddmmBackward0>)
rank 0 input tensor([[0.5209, 0.3261]], device='cuda:0') outputs tensor([[-0.2518,  0.5644,  0.0314]], device='cuda:0',
       grad_fn=<AddmmBackward0>)
rank 1 labels tensor([[-0., 1., -0.]], device='cuda:1')
rank 0 labels tensor([[1., 0., -0.]], device='cuda:0')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/172739.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

同星智能完成A+轮超亿元融资,国投招商领投

2023年10月&#xff0c;上海同星智能科技有限公司成功完成超亿元A轮融资。本轮融资由国投招商管理的先进制造产业投资基金二期领投&#xff0c;老股东丰年资本超额跟投。 本轮融资将用于产品研发和全球化市场拓展。 同星智能成立于2017年&#xff0c;一直专注于研发国产自主可控…

java算法学习索引之数组矩阵问题

一 将正方形矩阵顺时针转动90 给定一个NN的矩阵matrix&#xff0c;把这个矩阵调整成顺时针转动90后的形式。 顺时针转动90后为&#xff1a; 【要求】额外空间复杂度为O&#xff08;1&#xff09;。 public void rotate(int[][] matrix) {int tR 0; // 左上角行坐标int tC 0;…

NUCLEO-L552ZE SWD外部接口定义

如果使用ST-LINK调试器对外部MCU编程需要将CN4上的跳线拔下。

MAC地址注册管理最佳实践:安全性、可用性和灵活性

MAC地址注册管理是在网络环境中确保设备身份验证和访问控制的重要步骤。本文将介绍MAC地址注册管理的最佳实践&#xff0c;旨在提高安全性、可用性和灵活性&#xff0c;以满足现代网络的需求。 随着网络规模和复杂性的不断增加&#xff0c;管理和维护设备身份变得至关重要。MAC…

MindSpore基础教程:使用 MindCV和 Gradio 创建一个图像分类应用

MindSpore基础教程&#xff1a;使用 MindCV和 Gradio 创建一个图像分类应用 官方文档教程使用已经弃用的MindVision模块&#xff0c;本文是对官方文档的更新 在这篇博客中&#xff0c;我们将探索如何使用 MindSpore 框架和 Gradio 库来创建一个基于深度学习的图像分类应用。我…

京东优惠券查询API接口接入方案,item_search_coupon - 京东优惠券查询接口演示

要接入京东优惠券查询API接口&#xff08;item_search_coupon&#xff09;&#xff0c;您可以按照以下步骤进行操作&#xff1a; 注册并获取API密钥&#xff1a;首先&#xff0c;您需要在京东开放平台上注册并获取API密钥。这将为您提供唯一的标识符和密钥&#xff0c;用于访问…

博主都在用的网站,一键制作电子杂志

​随着互联网的发展&#xff0c;越来越多的人开始使用电子杂志来展示自己的作品或宣传自己的品牌。而制作电子杂志的工具也越来越多&#xff0c;其中一些工具非常受欢迎&#xff0c;被许多博主使用。今天&#xff0c;我们就来介绍一款博主都在用的网站&#xff0c;它可以帮助你…

【python】Python生成GIF动图,多张图片转动态图,pillow

pip install pillow 示例代码&#xff1a; from PIL import Image, ImageSequence# 图片文件名列表 image_files [car.png, detected_map.png, base64_image_out.png]# 打开图片 images [Image.open(filename) for filename in image_files]# 设置输出 GIF 文件名 output_g…

svn文件不显示红色感叹号

如下图所示&#xff0c;受svn版本控制的文件不显示下图中红色感叹号和绿色对号时&#xff0c; 可以试着如下操作 空白处单击右键&#xff0c;具体操作如下图

CF 1894A 学习笔记 思维 题意理解分析

原题 A. Secret Sport time limit per test 3 seconds memory limit per test 512 megabytes input standard input output standard output Lets consider a game in which two players, A and B, participate. This game is characterized by two positive integer…

Spring源码-5.aop代理

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…

4.2、Linux进程(1)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 基本概念 描述进程-PCB task_struct-PCB的一种 task_struct内容分类 查看进程 通过系统调用获取进程标识符 前言 进入进程前&#xff0c;我建议读一读这两篇文章&#xff0c;他们都是进程的前导知识。 操作系统…

Joern安装与使用

环境准备 Joern需要在Linux环境中运行&#xff0c;所以在Windows系统中需要借助WSL或虚拟机安装。 JDK安装 Joern的运行需要JAVA环境的支持&#xff0c;本次采用的是JDK17&#xff0c;其他版本建议看一下Joern官方文档。 apt install openjdk-17-jre-headless 配置JAVA环境变…

shell脚本之条件语句

条件语句 linux测试 test 测试 测试表达式是否成立&#xff08;用echo $? 检测是否正确&#xff09; 语法&#xff1a;test [选项] [文件名] 选项作用-e测试文件是否存在-r查看文件有无读的权限-d测试是否为目录-f测试是否为文件-w测试当前用户有无写的权限-x测试是否有执…

EANet:用于医学图像分割的迭代边缘注意力网络

EANet: Iterative edge attention network for medical image segmentation EANet&#xff1a;用于医学图像分割的迭代边缘注意力网络背景贡献实验方法Dynamic scale-aware context module&#xff08;动态规模感知上下文模块&#xff09;Edge attention preservation module&a…

【Java】java | CacheManager | redisCacheManager

一、说明 1、查询增加缓存&#xff0c;使用Cacheable注解 2、项目中已经用到了ehcache&#xff0c;现在需求是两个都用 二、备份配置 1、redisConfig增加代码 Bean("redisCacheManage")Primarypublic CacheManager redisCacheManager(RedisConnectionFactory fact…

Matlab通信仿真系列——图形处理函数

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 本节目录 一、plot函数 (1)绘制一…

SystemV

一、共享内存 1、直接原理 进程间通信的本质是&#xff1a;先让不同的进程&#xff0c;看到同一份资源&#xff01;&#xff01; 我们要把这句话奉若圭臬一般 到了共享内存了支持双向通信能读也能写&#xff0c;但是一般都是一个读一个写 要想通信先看到同一个份资源&#xff0…

Lifecyle的原理

1、Lifecycle是典型的观察者模式&#xff0c;被观察者的继承关系如上图所示。 2、LifeCycleRegistry是Lifecycle的子类。 3、观察者通过LifeCycle对象的addObserver注册监听生命周期的变化&#xff0c;通过removeObserver移除监听生命周期的变化。 4、Activity或Fragment的生命…
最新文章