Deep Learning:PyTorch 基于docker 容器的分布式训练实践

引言 
PyTorch distributed currently only supports Linux.   这句话是来自 pytorch 官网 的 torch.distributed 部分,说明 pytorch 支持分布式训练,而且只在linux 上支持。   torch.distributed supports three backends, each with different capabilities.   同样来自上述 页面,pytorch 在分布式训练中,支持三种后端(backend)进行集群管理或者通信。  那么,在什么情况下选用什么样的backend? 
经验法则 
  使用NCCL后端进行分布式GPU培训使用Gloo后端进行分布式CPU培训。 具有InfiniBand互连的GPU主机 
  使用NCCL,因为它是目前唯一支持InfiniBand和GPUDirect的后端。 GPU主机与以太网互连 
  使用NCCL,因为它目前提供最佳的分布式GPU训练性能,特别是对于多进程单节点或多节点分布式训练。如果您遇到NCCL的任何问题,请使用Gloo作为后备选项。(请注意,Gloo目前运行速度比GPU的NCCL慢。) 具有InfiniBand互连的CPU主机 
  如果您的InfiniBand已启用IP over IB,请使用Gloo,否则请使用MPI。我们计划在即将发布的版本中为Gloo添加InfiniBand支持。 具有以太网互连的CPU主机 
  除非您有特殊原因要使用MPI,否则请使用Gloo。  
实践部分 
首先,假设,我们要起一个分布式训练,起 2 个 rank。把他们起来两台机器上,机器 1 的 ip 为 192.168.61.55,机器 2 的 ip 为 192.168.61.56机器 1 上起 1 个 rank,机器 2 上起 1 个 rank 
 
 我这里使用的示例代码来自于 github 上的一段开源代码, 地址是 https://github.com/pytorch/examples/tree/master/mnist 。我对这段代码做了些更改,使其支持起 rank 的操作,测试的时候一台机器上起一个 rank 。你可以在 网上搜索到类似的修改。   但是,这不是一个最佳的测试例子,原因是因为这段代码缺少 类似 all_reduce 这样的操作,缺少运算过程中所有 rank 的权重进行修改、因而引起的 PCI 通信或者 InfiniBand 网络通信(非系统通信)等等。我不明白的是,网上有很多人把这段代码作为一个 非常有效的例子 用来 测试分布式运算,估计都是没有深究,互相抄抄改改。   我找到了一段最佳实验代码, 地址是 https://github.com/seba-1511/dist_tuto.pth/blob/gh-pages/train_dist.py 。奈何不是做 深度学习 出身,修改了几次也没能成功修改成需要符合需求的测试代码(有高手的话,麻烦能修改好,联系我测试测试)。这段代码是自带 创建 rank 的,并且是单机运行的。我想要的是,自己创建每一个 rank,并且支持多机分布式。 
 
多机分布式训练 
需要安装 python3 环境,并且安装 torch 和 torchvision 。两台机器的 python 环境应当保持一致。/mnt/pytorch/ 是一个分布式存储挂载目录。执行程序需要下载数据,如果你需要数据,可以在 https://download.csdn.net/download/github_37320188/11670737 查找 (由于没有积分了,小收几个积分用用,不能老做公益呀)。当然也可以自己下载,有合适的网络环境的话,相对来说就是花点时间。 
# 机器 1 上输入命令
python3 /mnt/pytorch/mnist.py --rank 0 --world-size 2 --init-method tcp://192.168.61.55:9090 --backend gloo

# 机器 2 上输入命令
python3 /mnt/pytorch/mnist.py --rank 1 --world-size 2 --init-method tcp://192.168.61.55:9090 --backend gloo
12345 
 
 其实这已经是一个多机训练的例子了。但是我建议在操作之前,先单节点 跑 2 个 rank 试试。 并且 run 一下 官方 示例 的一些代码,玩一下。   这个操作中,以 gloo 作 backend ,以 rank0 作为 master 通信,9090 机器 1 的未被占用通信端口。相关概念可以仔细阅读官方说明。 
 
docker 分布式训练 
首先你需要一个 支持 python 、torch、torchvision 的 docker image。如果选择省事,我建议去docker hub 下载一个官方的 tag 为 pytorch/pytorch:latest 的 image 。然后,这个 image 自带了 conda 、python3、torch,但是你需要自己安装 torchvision ,打包一个新的 image。建议通过 pip 安装,并且受限于 国内环境问题,你可能一次成功不了,可能需要多尝试几次。最后,如果实在 操作 docker 容器的耐心都没有了,你可以从我的 docker hub 里下载一个。tag 是 docker.io/loongc/pytorch:pytorch 
操作一波 
# 机器 1 
docker run -it --rm  -v /mnt/pytorch/:/pytorch -w /pytorch --net=host loongc/pytorch:pytorch  python mnist.py --rank 0 --world-size 2 --init-method tcp://192.168.61.55:9090 --backend gloo

# 机器 2
docker run -it --rm  -v /mnt/pytorch/:/pytorch -w /pytorch --net=host loongc/pytorch:pytorch  python mnist.py --rank 1 --world-size 2 --init-method tcp://192.168.61.55:9090 --backend gloo
12345 
讨论 
以上部分,测试都是在 多节点CPU 上运行的。如果你需要在GPU 进行运算: 
首先,你需要节点本身 支持gpu 运算,安装 cuda 环境如果你希望在 docker 中进行 gpu 运算,那么 docker image 需要支持gpu 运算。幸运的是,前文提到的 image 支持gpu 运算 
  如果,环境已经准备好了,就可以做一些 GPU 相关的测试了。   使用 基于 Docker 的 GPU 分布式运算,如果不需要 诸如 运算性能 特殊的需求,你可以直接使用 上一节 的 操作方法即可。如果 需要 诸如使用 分布式文件系统通信、环境变量通信、InfiniBand通信,使用 nccl 作为 backend 等等,将在下一节做一个总结。 
backend 与通信方式 的一些总结 
引言中,已经提到 3 种 backend,分别是:MPI、GLOO、NCCL。这 3 种 backend 支持了 3 种 通信 方式:tcp、环境变量、分布式文件系统(当前使用的 pytorch 版本如此,后续的版本就不知道了)。   所以,大致上可以认为不同 rank 之间的通信就是 由 backend 与 通信方式的 组合完成的。当然,在不同的组合方式所带来的 通信速度(影响运算整体性能)是不同的,能实现的功能也是不太一样的(详情见引言中的表格)。   本文前面的内容当中,使用的 backend 都是GLOO,使用的通信方式都是 tcp。   本节内容,主要围绕 NCCL 的 3 种 通信操作方式展开,以及如何使用 InfiniBand。 MPI 的方式我没有测过,也不打算测试,主要原因是需要 额外的依赖 。 
NCCL 与 tcp 
nccl 与 gloo 使用 tcp 的方式是一致的,不需要多余的操作。在运行 python 脚本的时候,只需要将传入 backend 的参数 gloo 改为 nccl 即可。 
NCCL 与 环境变量 
nccl 使用环境变量,相对于 tcp 要复杂一些。 
首先,需要将传入 backend 的参数 gloo 改为 nccl其次,将传入 init-method 的参数 由 tcp://ip:port 改为 env://另外,容器启动的时候的需要给容器设置 2 个环境变量 MASTER_ADDR ,MASTER_PORT 
还是在 192.168.61.55 和 192.168.61.56 两台机器上操作,启动大致如下: 
# 机器 1
docker run -it --rm --env-file /mnt/pytorch_env/master -v /mnt/pytorch/:/pytorch -w /pytorch --net=host loongc/pytorch:pytorch python mnist.py --rank 0 --world-size 2 --init-method env:// --backend nccl

# 机器 2
docker run -it --rm --env-file /mnt/pytorch_env/master -v /mnt/pytorch/:/pytorch -w /pytorch --net=host loongc/pytorch:pytorch python mnist.py --rank 1 --world-size 2 --init-method env:// --backend nccl

# 文件 /mnt/pytorch_env/master 内容如下
MASTER_ADDR=192.168.61.55
MASTER_PORT=9090
123456789 
 
 上述 /mnt/pytorch_env/master 文件的内容中 MASTER_ADDR=192.168.61.55 是 rank0 所在机器的 ip ,MASTER_PORT=9090 是该机器上一个未被征用的 端口 
 
NCCL 与 分布式文件系统 
nccl 使用分布式文件系统,那么就需要把分布式文件系统 映射进 容器当中,在这里,我是在 挂载目录下 /mnt/pytorch/ 创建了一个文件 backendnccl ,因为本身这个挂载 就是分布式文件系统。 
# 以机器 1 上的操作为例
docker run -it --rm -v /mnt/pytorch/:/pytorch -w /pytorch --net=host loongc/pytorch:pytorch python mnist.py --rank 0 --world-size 2 --init-method file:///pytorch/backendnccl --backend nccl
12 
使用 InfiniBand 
原本,pytorch 是支持 IP over IB 的,所以可操作 InfiniBand 的方式主要有以下几种: 
在使用 tcp方式 进行通信 时,可以不使用 IP 地址,而直接使用 IB (InfiniBand) 卡的地址在使用环境变量过程中,设置的环境变量中 将 MASTER_ADDR 设置成 IB 卡的地址 
另外,NCCL和Gloo后端都会尝试找到要使用的正确网络接口,如果自动检测到的接口不正确,您可以使用以下环境变量覆盖它(适用于相应的后端):   在使用 过程中,如果确定 使用 nccl,并且打算用 InfiniBand ,推荐通过环境变量(写进 前文提到的 文件 /mnt/pytorch_env/master ) NCCL_SOCKET_IFNAME=ib0 
 
 额外说明,如果你的机器上有多张 InfiniBand 卡,你可以通过 NCCL_SOCKET_IFNAME 指定任意一张,如 ib0 或者 ib1 这种   但是,你可以直接使用 NCCL_SOCKET_IFNAME=ib 进行指定,这样所有的 ib 卡都有机会被调用起来用于通信。你可以通过相关工具,如 ibdump 进行监控 ib 卡的发包 和 数据的发送与接受。   经过分析,我们认为在 以发送数据包 的方式进行通信的过程中,除了真正用于计算的数据包,还可能包括 机器通信 的数据。 
 
总结 
这里,实现了手动启动多个rank 进行 基于 docker 的分布式训练。那么,自动化进行分布式训练就变得比较容易了。   可以通过 mesos 或者 k8s 启动多个 容器,进行集群管理,完成分布式训练。通过 设计 api 指定启动 指定数目的 rank,指定硬件资源,以及是否使用 InfiniBand 。   如果有更好的实现 分布式训练 PyTorch ,欢迎留言讨论。
 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 深度学习是一项非常热门的技术,在人工智能领域得到广泛应用。PyTorch是一种使用Python编程语言的开源深度学习框架,它非常适合研究和开发深度学习模型。为了帮助初学者更好地学习PyTorch深度学习技术,CSDN(全球最大中文IT社区)开设了“DeepLearning with PyTorch”系列课程。 这个系列课程以实践为主要教学方式,让学生在实际操作中掌握PyTorch深度学习的技能。在学习过程中,学生可以学到基础的模型结构设计,各种优化算法,如学习率调整、梯度下降等,并且可以在实战操作中学到如何使用PyTorch完成各种实际应用,例如图像分类和识别,自然语言处理等等。 这门课程的受众群体不仅仅是那些想要从事人工智能开发的工程师,它对于对深度学习感兴趣的学生和科研人员也是非常有用的。这是因为在这个课程中,教师基于实际使用场景和数据集介绍了PyTorch深度学习技术,从实践中总结出的方法和经验不仅可以快速提升工程开发效率,也可以加深对深度学习理论的理解。 总之,“DeepLearning with PyTorch”系列课程非常实用和有趣,可以为初学者提供全面而深入的深度学习知识,帮助他们掌握用PyTorch来开发深度学习模型的基础技能。 ### 回答2: Deep Learning是一种用于训练多层神经网络的机器学习方法,已被广泛应用于视觉、语音、自然语言处理等领域。而PyTorch是一种开源的深度学习框架,具有快速、灵活、易用等优点,因此受到了越来越多的关注和使用。 CSDN是一个致力于IT技术在线学习和分享的平台,在其中学习deeplearning with pytorch将能够获取丰富的知识和实践经验。首先,我们需要了解PyTorch的基本概念和操作方法,如如何构建网络模型、定义损失函数和优化器、进行前向传播和反向传播等。然后,我们可以学习如何使用PyTorch进行数据预处理,如数据清洗、标准化、归一化等。此外,还可了解如何使用PyTorch进行分布式训练、混合精度训练等高级技术,以及如何在GPU上进行训练和推理等实践技巧。 总之,在CSDN上学习deeplearning with pytorch,能够让我们更好地掌握PyTorch的使用技巧,帮助我们更快、更好地完成深度学习的应用开发和研究工作。同时也可以通过活跃在CSDN平台上与其他开发者的交流来共同进步。 ### 回答3: PyTorch是一种针对深度学习任务的开源机器学习库,它支持快速的原型设计和大量的实验,是当前科学界和工业界中最受欢迎的深度学习框架之一。CSDN推出的Deeplearning with Pytorch系列课程就是致力于教授学生如何使用PyTorch进行深度学习,以及在此基础上更深层次的研究探索。 此系列课程包含了从入门到进阶多个方面的内容,在基础课程中,学员将学会如何使用PyTorch进行深度学习的各个方面,包括但不限于神经网络、优化器、损失函数等,使其基本掌握PyTorch的使用方法。而在进阶课程中,以一些大型深度学习任务为基础,详细介绍了超参数优化、神经网络模型架构选择、分布式训练、自己写网络模型等更高级的知识,通过深度剖析一些开源库的源码,为学员提供了很多实现深度学习任务的技巧和方法。 课程的开设不仅帮助了很多想更深入了解深度学习的爱好者,也有助于那些打算将深度学习应用在自己的科研工作中的研究者们更加快捷、有效地完成自己的研究任务。相信随着人工智能的不断发展,PyTorch这样的框架将会发挥越来越重要的作用,而帮助大家掌握这些工具的Deeplearning with Pytorch系列课程也必将得到更多的关注和支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值