Pytorch - 分布式训练极简体验
由于工作需要,最近在补充分布式训练方面的知识。经过一番理论学习后仍觉得意犹未尽,很多知识点无法准确get到(例如:分布式原语scatter、all reduce等代码层面应该是什么样的,ring all reduce 算法在梯度同步时是怎么使用的,parameter server参数是如何部分更新的)。
著名物理学家,诺贝尔奖得主Richard Feynman办公室的黑板上写了:"What I cannot create, I do not understand."。在程序员界也经常有"show me the code"的口号。 因此,我打算写一系列的分布式训练的文章,将以往抽象的分布式训练的概念以代码的形式展现出来,并保证每个代码可执行、可验证、可复现,并贡献出来源码让大家相互交流。
经过调研发现pytorch对于分布式训练做好很好的抽象且接口完善,因此本系列文章将以pytorch为主要框架进行,文章中的例子很多都来自pytorch的文档,并在此基础上进行了调试和扩充。
最后,由于分布式训练的理论介绍网络上已经很多了,理论部分的介绍不会是本系列文章的重点,我会将重点放在代码层面的介绍上面。
1 任务介绍
通过实现一个线性变换模型 的单机2卡分布式训练任务,来初步体验pytorch中DistributeDataparallel的使用。本文主要参考pytorch tutorial中的介绍。
2 整体流程
代码编写流程如下:
- 初始化pytorch分布式训练通信模块;
- 创建模型(这里包括本地模型和分布式模型)
- 创建损失函数和优化器
- 计算(forward 和backward)和梯度更新
- 多任务启动
3 初始化通信模块
pytorch中分布式通信模块为torch.distributed
本例中初始化代码为:
- 通过环境变量
MASTER_ADDR
和MASTER_PORT
设置rank0的IP和PORT信息,rank0的作用相当于是协调节点,需要其他所有节点知道其访问地址; - 本例中后端选择的是nccl,通过设置
NCCL_DEBUG
环境变量为INFO,输出NCCL的调试信息; init_process_group
:执行网络通信模块的初始化工作- backend:设置后端网络通信的实现库,可选的为gloo、nccl和mpi;
- rank:为当前rank的index,用于标记当前是第几个rank,取值为0到work_size - 1之间的值;
- world_size: 有多少个进程参与到分布式训练中;
# set env信息os.environ['MASTER_ADDR'] = '127.0.0.1'os.environ['MASTER_PORT'] = '29500'os.environ['NCCL_DEBUG'] = "INFO"# create default process groupdist.init_process_group(backend="nccl", rank=rank, world_size=world_size)
4 创建模型
通过下面的代码分别创建本地模型和分布式模型:
nn.Linear(10, 10).to(rank)
: 创建线性变换模型,input size和out put size都是10,并且将模型copy到gpu上(通过rank来标识gpu 的id)DDP(model, device_ids=[rank])
: 创建分布式模型;该模型会将local model 复制到所有副本上,并对数据进行切分,然后使得每个local model都按照mini batch进行训练。
# create local modelmodel = nn.Linear(10, 10).to(rank)# construct DDP modelddp_model = DDP(model, device_ids=[rank])
5 创建Loss和optimizer
# define loss function and optimizerloss_fn = nn.MSELoss()optimizer = optim.SGD(ddp_model.parameters(), lr=0.001)
6 计算和梯度更新
通过ddp_model执行forward和backward计算,这样才能够达到分布式计算的效果;
# forward passoutputs = ddp_model(torch.randn(20, 10).to(rank))labels = torch.randn(20, 10).to(rank)# backward passloss_fn(outputs, labels).backward()# update parametersoptimizer.step()
7 任务启动
启动一个有两个process组成的分布式任务:
run_worker
:子进程执行的function,会以fn(i, *args)
的形式被调用,i为process的id(0,1,2...),*args为spawn的args参数args
:执行进程的参数nprocs
:进程的个数join
:是否等待子进程执行完成
def main():worker_size = 2mp.spawn(run_worker,args=(worker_size,),nprocs=worker_size,join=True)
8 完整代码
import os
import torch
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 DDPdef run_worker(rank, world_size):os.environ['MASTER_ADDR'] = '127.0.0.1'os.environ['MASTER_PORT'] = '29500'os.environ['NCCL_DEBUG'] = "INFO"# create default process groupdist.init_process_group(backend="nccl", rank=rank, world_size=world_size)# create local modelmodel = nn.Linear(10, 10).to(rank)# construct DDP modelddp_model = DDP(model, device_ids=[rank])# define loss function and optimizerloss_fn = nn.MSELoss()optimizer = optim.SGD(ddp_model.parameters(), lr=0.001)# forward passoutputs = ddp_model(torch.randn(20, 10).to(rank))labels = torch.randn(20, 10).to(rank)# backward passloss_fn(outputs, labels).backward()# update parametersoptimizer.step()def main():worker_size = 2mp.spawn(run_worker,args=(worker_size,),nprocs=worker_size,join=True)if __name__=="__main__":main()
代码执行如下:
root@g48r13:/workspace/DDP# python linear-ddp.py
g48r13:350:350 [0] NCCL INFO Bootstrap : Using [0]bond0:11.139.84.88<0>
g48r13:350:350 [0] NCCL INFO NET/Plugin : No plugin found (libnccl-net.so), using internal implementationg48r13:350:350 [0] misc/ibvwrap.cc:63 NCCL WARN Failed to open libibverbs.so[.1]
g48r13:350:350 [0] NCCL INFO NET/Socket : Using [0]bond0:11.139.84.88<0>
g48r13:350:350 [0] NCCL INFO Using network Socket
NCCL version 2.7.8+cuda10.2
g48r13:351:351 [1] NCCL INFO Bootstrap : Using [0]bond0:11.139.84.88<0>
g48r13:351:351 [1] NCCL INFO NET/Plugin : No plugin found (libnccl-net.so), using internal implementationg48r13:351:351 [1] misc/ibvwrap.cc:63 NCCL WARN Failed to open libibverbs.so[.1]
g48r13:351:351 [1] NCCL INFO NET/Socket : Using [0]bond0:11.139.84.88<0>
g48r13:351:351 [1] NCCL INFO Using network Socket
g48r13:350:366 [0] NCCL INFO Channel 00/02 : 0 1
g48r13:351:367 [1] NCCL INFO threadThresholds 8/8/64 | 16/8/64 | 8/8/64
g48r13:350:366 [0] NCCL INFO Channel 01/02 : 0 1
g48r13:351:367 [1] NCCL INFO Trees [0] -1/-1/-1->1->0|0->1->-1/-1/-1 [1] -1/-1/-1->1->0|0->1->-1/-1/-1
g48r13:351:367 [1] NCCL INFO Setting affinity for GPU 1 to ffffffff,ffffffff
g48r13:350:366 [0] NCCL INFO threadThresholds 8/8/64 | 16/8/64 | 8/8/64
g48r13:350:366 [0] NCCL INFO Trees [0] 1/-1/-1->0->-1|-1->0->1/-1/-1 [1] 1/-1/-1->0->-1|-1->0->1/-1/-1
g48r13:350:366 [0] NCCL INFO Setting affinity for GPU 0 to ffffffff,ffffffff
g48r13:351:367 [1] NCCL INFO Channel 00 : 1[5000] -> 0[4000] via P2P/IPC
g48r13:350:366 [0] NCCL INFO Channel 00 : 0[4000] -> 1[5000] via P2P/IPC
g48r13:351:367 [1] NCCL INFO Channel 01 : 1[5000] -> 0[4000] via P2P/IPC
g48r13:350:366 [0] NCCL INFO Channel 01 : 0[4000] -> 1[5000] via P2P/IPC
g48r13:351:367 [1] NCCL INFO 2 coll channels, 2 p2p channels, 2 p2p channels per peer
g48r13:351:367 [1] NCCL INFO comm 0x7fb0b4001060 rank 1 nranks 2 cudaDev 1 busId 5000 - Init COMPLETE
g48r13:350:366 [0] NCCL INFO 2 coll channels, 2 p2p channels, 2 p2p channels per peer
g48r13:350:366 [0] NCCL INFO comm 0x7fc7a8001060 rank 0 nranks 2 cudaDev 0 busId 4000 - Init COMPLETE
g48r13:350:350 [0] NCCL INFO Launch mode Parallel
Pytorch - 分布式训练极简体验相关推荐
- 干货|Pytorch弹性训练极简实现( 附源码)
点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者丨颜挺帅@知乎(已授权) 来源丨https://zhuanlan ...
- PyTorch分布式训练
PyTorch分布式训练 PyTorch 是一个 Python 优先的深度学习框架,能够在强大的 GPU 加速基础上实现张量和动态神经网络.PyTorch的一大优势就是它的动态图计算特性. Licen ...
- 【干货】极简体验+免费真的万能嘛?北森Saas第一坑:免费
小咖注:这个时代 极简体验 和 免费,已经成了互联网必杀"秘笈".而互联网发展到今天从来都没有一种唯一的方法论,因为面向的人群,需求,场景都是在变化的. 至今,我有一件事情搞不明白 ...
- 新手手册:Pytorch分布式训练
文 | 花花@机器学习算法与自然语言处理 单位 | SenseTime 算法研究员 目录 0X01 分布式并行训练概述 0X02 Pytorch分布式数据并行 0X03 手把手渐进式实战 A. 单机单 ...
- PyTorch 分布式训练DDP 单机多卡快速上手
PyTorch 分布式训练DDP 单机多卡快速上手 本文旨在帮助新人快速上手最有效的 PyTorch 单机多卡训练,对于 PyTorch 分布式训练的理论介绍.多方案对比,本文不做详细介绍,有兴趣的读 ...
- pytorch分布式训练 DistributedSampler、DistributedDataParallel
pytorch分布式训练 DistributedSampler.DistributedDataParallel 大家好,我是亓官劼(qí guān jié ),在[亓官劼]公众号.CSDN.Git ...
- 【Pytorch分布式训练】在MNIST数据集上训练一个简单CNN网络,将其改成分布式训练
文章目录 普通单卡训练-GPU 普通单卡训练-CPU 分布式训练-GPU 分布式训练-CPU 租GPU服务器相关 以下代码示例基于:在MNIST数据集上训练一个简单CNN网络,将其改成分布式训练. 普 ...
- 【分布式】Pytorch分布式训练原理和实战
[分布式]基于Horovod的Pytorch分布式训练原理和实战 并行方法: 1. 模型并行 2. 数据并行 3. 两者之间的联系 更新方法: 1. 同步更新 2. 异步更新 分布式算法: 1. Pa ...
- CCCanvas.Heptagonal - CCCanvas iOS Metal MetalKit GPU 极简体验Demo之 - 七边形
CCCanvas.Heptagonal - CCCanvas iOS Metal MetalKit GPU 极简体验Demo之 - 七边形 [友情提示:因为主要是演示用,不考虑向前兼容,可通过Pod升 ...
最新文章
- ES6新特性3:函数的扩展
- 无监督方法实现C++、Java、Python 代码转换,程序员:出了bug怎么办,两种语言都要看吗?...
- DeepChem | Windows 10下anaconda3环境从源码构建并安装deepchem
- 在Linux下通过Wake On LAN实现网络唤醒远程开机
- android object数组赋值_VUE2.X为什么只对数组的部分方法实现了数据监测?
- java面试题十一 基本数据类型
- MongoDB学习3——mongoDB的一些基本使用
- 一个机器周期 计算机_计算机科学组织| 机器周期
- python建立列表并输入_python操作列表
- 谁说贾跃亭不还钱?人家已偿还超30亿美元的国内债务
- python到底有什么用-Python中的闭包到底有什么用
- HTML5 — 知识总结篇《VIII》【媒体元素】
- 慕课网仿去哪儿项目笔记--(三)-城市页面制作
- matlab光学应用实践,Matlab在光学信息处理仿真实验中的应用
- 解决phpstudy的Apache启动失败
- Crucible 安装日志
- 淘宝/天猫按图搜索商品API接口,以图搜商品API接口,图片搜索API接口
- 福州大学计算机学院李敏,福州大学厦门工艺美术学院
- Flowable工作流之多实例任务会签
- 程序员应该保持危机感
热门文章
- 元宇宙公司有哪些 元宇宙公司 元宇宙开发公司
- linux网络设备应用与驱动编程学习3——lpc3250以太网控制器
- Discuz X3.2使用支付宝提供的担保交易
- 一 软件应用架构演进
- BlackHat上的工控蠕虫病毒 绿盟科技工控研究员用SCL语言编写实现 录像让你亲眼看看...
- 《精彩绝伦的CSS》——布局(一)用轮廓代替边框
- 基于TI达芬奇系列TMS320DM8148浮点DSP C674x JTAG仿真器接口、风扇接口
- Spek:JetBrains出品的JVM语言规范框架
- 【侯捷】C++STL标准库与泛型编程(第一讲)
- 烧开水理论-证明自己存在的三个过程