繁体   English   中英

在 Amazon SageMaker 上使用 PyTorch DistributedDataParallel 和 Hugging Face

[英]Use PyTorch DistributedDataParallel with Hugging Face on Amazon SageMaker

即使对于单实例训练,PyTorch DistributedDataParallel (DDP) 通常比 PyTorch DataParallel (DP) 更推荐,因为 DP 的策略性能较低,并且在默认设备上使用更多 ZCD69B4957F06CD818D7BF3D61980E2。 (根据这个 PyTorch 论坛主题

Hugging Face 建议通过python -m torch.distributed.launch启动器运行分布式训练,因为他们的 Trainer API 支持 DDP,但如果不支持,则会退回到 DP。 (根据这个 HF 论坛主题

I recently ran in to this problem: scaling a HF training job from p3.8xlarge to p3.16xlarge increased memory consumption on (I think) one of the GPUs to the point where I had to significantly reduce batch size to avoid CUDA Out of Memory错误 - 基本上失去了所有的扩展优势。

因此,对于 p3.16xl+ 来说,好消息是我可以启用 SageMaker 分布式数据并行,PyToch DLC 将自动通过 torch.distributed 为我启动

对于具有较小工作负载或希望在扩展之前进行测试的用例来说,坏消息是 SMDistributed 不支持所有多 GPU 实例类型 例如,没有 p3.8xl 或 g 系列。 我确实尝试手动设置sagemaker_distributed_dataparallel_enabled环境变量,但没有任何乐趣。

那么我们如何在 SageMaker 上使用 PyTorch DDP 启动 HF Trainer 脚本呢?

好问题,感谢您的提问,PyTorch DDP 在多个进程中运行数据并行工作者。 必须由开发人员启动和管理,DDP 应该被视为一个托管的 allreduce,而不是一个托管的数据并行库。 因为它需要您启动和管理工作人员,甚至为工作人员分配资源:为了在 SageMaker 培训作业中启动 DDP 流程,您有很多选择:

  1. 如果你做多GPU,单机,你可以使用torch.multiprocessing.spawn ,如这个官方PyTorch演示所示(顺便说一下)
  2. 如果你做多 GPU 单机,你也可以使用Ray Train库来启动这些进程。 我可以在笔记本中使用它,但还不能在 DLC 中使用(最近的库学习和制作有点粗糙,请在此处查看我的所有问题)。 Ray Train 也应该在多节点上工作。
  3. 如果您使用多 GPU、任何机器,则可以使用torch.distributed.launch ,它包含在 shell 或 Python 的启动器脚本中。 此处示例https://gitlab.aws.dev/cruchant/a2d2-segmentation/-/blob/main/3_2D-Seg-Audi-A2D2-Distributed-Training-DDP.ipynb
  4. 您还可以使用 SageMaker MPI 集成而不是torch.distributed来启动这些流程。 不幸的是,我们没有为此创建文档,所以没有人使用它,也没有人推销它。 但它看起来很酷,因为它允许直接在 EC2 机器中运行脚本的副本,而无需调用中间 PyTorch 启动器。 这里的例子

所以现在,我的建议是 go 路线(3),这是最接近 PyTorch 社区所做的,因此提供了更容易的开发和调试路径。

备注

  • PyTorch DDP 发展迅速。 在 PT 1.10 中, torch.distributedtorchrun取代,并且正在创建一个torchX工具来...简化事情。)。
  • 不必管理这些混乱是 SageMaker 分布式数据并行是一个物超所值的一个原因:您只需要编辑脚本,SM 服务会处理进程创建。 不幸的是,正如您所指出的,SMDP 仅限于 P3 和 P4 培训工作,严重限制了它的使用。
  • 以下是将单 GPU 代码更改为多机器代码的重要 PT DDP 概念
    • 与代表您处理工作负载分区的 Apache Spark 不同,Pytorch 分布式训练要求用户将特定的工作分配给特定的 GPU。 在下一节中,我们假设我们在 GPU 上进行训练。
    • 在 PyTorch DDP 中,每个 GPU 运行您的训练代码的自定义副本。 在 GPU 上运行的训练代码副本通常称为rankdata parallel replicaprocessworker ,但可能存在其他名称。
    • 要让 PyTorch DDP 在分布在 M 台机器上的 MxN GPU 上启动训练集群,您必须向 PyTorch DDP 指定您拥有的机器数量和每台机器要启动的进程数量。 这分别由torch.distributed.launch实用程序的参数-nnodes-nproc_per_node完成。 您必须在训练集群的每个节点上运行一次torch.distributed.lauch 您可以使用多种工具来实现此并行命令,例如上面提到的 MPI 或 SageMaker 训练。 为了建立必要的握手并形成集群,您还必须在torch.distributed.launch命令中指定-node_rank ,它必须在每台机器上采用 0 到 N-1 之间的唯一机器 ID,以及-master_addr-master_port ,如果您运行单机集群,则可选,所有机器必须相同。
    • 在从每个数据并行副本脚本中运行的init_process_group DDP 初始化方法中,您必须分别使用world_sizerank参数指定世界大小和副本 ID。 因此,您必须有办法向每个脚本传达一个唯一 ID,通常称为global rank 全球排名可以帮助您个性化每个 GPU 所做的工作,例如仅从一张卡保存 model,或仅在一张卡中运行验证。 在由 3 台机器组成的集群中,每台机器有 4 个 GPU,全局等级的范围是 0 到 11。在一台机器中,为了将 DDP 数据并行副本分配给可用的 GPU,必须为每个副本中运行的脚本分配一个 GPU ID,在运行它的机器中是独一无二的。 这称为本地排名,可以通过 PyTorch DDP torch.distributed.launch设置为参数。 在由 3 台机器组成的集群中,每台机器有 4 个 GPU,在每台机器上,DDP 进程的本地等级范围为 0 到 3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM