由于工作需要,最近在补充分布式训练方面的知识。经过一番理论学习后仍觉得意犹未尽,很多知识点无法准确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_ADDRMASTER_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 - 分布式训练极简体验相关推荐

  1. 干货|Pytorch弹性训练极简实现( 附源码)

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者丨颜挺帅@知乎(已授权) 来源丨https://zhuanlan ...

  2. PyTorch分布式训练

    PyTorch分布式训练 PyTorch 是一个 Python 优先的深度学习框架,能够在强大的 GPU 加速基础上实现张量和动态神经网络.PyTorch的一大优势就是它的动态图计算特性. Licen ...

  3. 【干货】极简体验+免费真的万能嘛?北森Saas第一坑:免费

    小咖注:这个时代 极简体验 和 免费,已经成了互联网必杀"秘笈".而互联网发展到今天从来都没有一种唯一的方法论,因为面向的人群,需求,场景都是在变化的. 至今,我有一件事情搞不明白 ...

  4. 新手手册:Pytorch分布式训练

    文 | 花花@机器学习算法与自然语言处理 单位 | SenseTime 算法研究员 目录 0X01 分布式并行训练概述 0X02 Pytorch分布式数据并行 0X03 手把手渐进式实战 A. 单机单 ...

  5. PyTorch 分布式训练DDP 单机多卡快速上手

    PyTorch 分布式训练DDP 单机多卡快速上手 本文旨在帮助新人快速上手最有效的 PyTorch 单机多卡训练,对于 PyTorch 分布式训练的理论介绍.多方案对比,本文不做详细介绍,有兴趣的读 ...

  6. pytorch分布式训练 DistributedSampler、DistributedDataParallel

    pytorch分布式训练 DistributedSampler.DistributedDataParallel   大家好,我是亓官劼(qí guān jié ),在[亓官劼]公众号.CSDN.Git ...

  7. 【Pytorch分布式训练】在MNIST数据集上训练一个简单CNN网络,将其改成分布式训练

    文章目录 普通单卡训练-GPU 普通单卡训练-CPU 分布式训练-GPU 分布式训练-CPU 租GPU服务器相关 以下代码示例基于:在MNIST数据集上训练一个简单CNN网络,将其改成分布式训练. 普 ...

  8. 【分布式】Pytorch分布式训练原理和实战

    [分布式]基于Horovod的Pytorch分布式训练原理和实战 并行方法: 1. 模型并行 2. 数据并行 3. 两者之间的联系 更新方法: 1. 同步更新 2. 异步更新 分布式算法: 1. Pa ...

  9. CCCanvas.Heptagonal - CCCanvas iOS Metal MetalKit GPU 极简体验Demo之 - 七边形

    CCCanvas.Heptagonal - CCCanvas iOS Metal MetalKit GPU 极简体验Demo之 - 七边形 [友情提示:因为主要是演示用,不考虑向前兼容,可通过Pod升 ...

最新文章

  1. ES6新特性3:函数的扩展
  2. 无监督方法实现C++、Java、Python 代码转换,程序员:出了bug怎么办,两种语言都要看吗?...
  3. DeepChem | Windows 10下anaconda3环境从源码构建并安装deepchem
  4. 在Linux下通过Wake On LAN实现网络唤醒远程开机
  5. android object数组赋值_VUE2.X为什么只对数组的部分方法实现了数据监测?
  6. java面试题十一 基本数据类型
  7. MongoDB学习3——mongoDB的一些基本使用
  8. 一个机器周期 计算机_计算机科学组织| 机器周期
  9. python建立列表并输入_python操作列表
  10. 谁说贾跃亭不还钱?人家已偿还超30亿美元的国内债务
  11. python到底有什么用-Python中的闭包到底有什么用
  12. HTML5 — 知识总结篇《VIII》【媒体元素】
  13. 慕课网仿去哪儿项目笔记--(三)-城市页面制作
  14. matlab光学应用实践,Matlab在光学信息处理仿真实验中的应用
  15. 解决phpstudy的Apache启动失败
  16. Crucible 安装日志
  17. 淘宝/天猫按图搜索商品API接口,以图搜商品API接口,图片搜索API接口
  18. 福州大学计算机学院李敏,福州大学厦门工艺美术学院
  19. Flowable工作流之多实例任务会签
  20. 程序员应该保持危机感

热门文章

  1. 元宇宙公司有哪些 元宇宙公司 元宇宙开发公司
  2. linux网络设备应用与驱动编程学习3——lpc3250以太网控制器
  3. Discuz X3.2使用支付宝提供的担保交易
  4. 一 软件应用架构演进
  5. BlackHat上的工控蠕虫病毒 绿盟科技工控研究员用SCL语言编写实现 录像让你亲眼看看...
  6. 《精彩绝伦的CSS》——布局(一)用轮廓代替边框
  7. 基于TI达芬奇系列TMS320DM8148浮点DSP C674x JTAG仿真器接口、风扇接口
  8. Spek:JetBrains出品的JVM语言规范框架
  9. 【侯捷】C++STL标准库与泛型编程(第一讲)
  10. 烧开水理论-证明自己存在的三个过程