Pycharm远程设置 DDP简单介绍

news2024/11/27 14:49:27

前言

最近接到一些改代码或者帮助debug的需求,大多数不是在本地而是autodl这种服务器上,有些人可能不太了解如何设置远程环境。通常在实验室一般都是在本地调好代码然后scp到服务器上去训练,不过这就需要本地有显卡能测试代码是否能跑通,或者直接在autodl这些提供的jupyter上去写代码(代码提示不算友好),一般复杂项目还是更倾向于在Pycharm,VsCode这种编辑器中开发。正好端午节回家,用家里的MacBook和服务器来演示一下整套流程以及介绍一下DDP相关的内容。

1. Pycharm远程设置

通常服务器会给一个公网ip允许你访问,而我这里因为服务器就放在阳台接的家里内网所以相当于局域网内访问原理是一样的。先连接远程进去看一下服务器ip,ifconfig 得到ip

打开Pycharm,点击tools->Deployment->Configuration

image-20230623004605917

image-20230623004638604

这里就是基本的ssh连接设置,将服务器的ip,用户名和密码设置好,然后点击测试,如果能顺利连接就进行下一步操作。

image-20230623005016284

顺利创建连接之后,设置一下文件路径映射。在Deployment中将自动上传给选上,保证本地的文件修改能顺利在服务器中同步。

image-20230623004919449

2. DDP 相关

通常为了加速训练,我们要尽量使用服务器的所有显卡资源。最常见的环境就是单机多卡(多机多卡后期抽空把实验室的服务器全整上来单独出一期),所以今天主要还是将单机多卡场景。

在单机多卡之前,还是上一版最简单的单卡的demo作为比较

 def get_dataloader():
     transform = transforms.Compose([
         transforms.ToTensor(),
     ])
     dataset = torchvision.datasets.MNIST("./", train=True, transform=transform, download=True)
     dataloader = DataLoader(dataset, batch_size=256, shuffle=True, num_workers=12, pin_memory=True)
     return dataloader
     
     
 def train(epochs=10, ckpt_save_path='./best.pt'):
     model = Model(10).cuda()
     criterion = nn.CrossEntropyLoss()
     optimizer = optim.Adam(model.parameters(), lr=1e-4)
     dataloader = get_dataloader()
     best_acc = -torch.inf
 ​
     start = time.time()
     for epoch in range(epochs):
         labels_list = []
         prediction_list = []
         loss_list = []
         model.train()
         for _, (images, labels) in tqdm(enumerate(dataloader), total=len(dataloader), leave=True):
             images, labels = images.cuda(), labels.cuda()
             optimizer.zero_grad()
             outputs = model(images)
             loss = criterion(outputs, labels)
             loss_list.append(loss)
             outputs = torch.max(outputs, dim=1)[1]
             prediction_list.extend(outputs)
             labels_list.extend(labels)
             loss.backward()
             optimizer.step()
         acc = accuracy_score(labels.cpu().detach().numpy(), outputs.cpu().detach().numpy())
         print(f'Epoch: {epoch + 1} \t loss: {sum(loss_list) / len(loss_list)} \t acc: {acc}')
         if acc > best_acc:
             best_acc = acc
             print(f"best acc:{best_acc}  model save!")
             torch.save(model.state_dict(), ckpt_save_path)
     return time.time() - start

image-20230623010236854

然后再来看看单机多卡版本

 def setup():
     dist.init_process_group('nccl')
     rank = dist.get_rank()
     torch.cuda.set_device(rank)
     device_id = rank % torch.cuda.device_count()
     return device_id
 ​
 def cleanup():
     dist.destroy_process_group()
     
 def get_distributed_dataloader():
     transform = transforms.Compose([
         transforms.ToTensor(),
     ])
     dataset = torchvision.datasets.MNIST("./", train=True, transform=transform, download=True)
     data_sampler = DistributedSampler(dataset)
     dataloader = DataLoader(dataset, batch_size=256, num_workers=12, sampler=data_sampler, pin_memory=True)
     return dataloader
     
     
 def train_ddp(epochs=10, ckpt_save_path='./best_ddp.pt'):
     setup()
     model = Model(num_classes=10).cuda()
     model = DDP(model)
     criterion = nn.CrossEntropyLoss()
     optimizer = optim.Adam(model.parameters(), lr=1e-4)
     dataloader = get_distributed_dataloader()
     best_acc = -torch.inf
 ​
     start = time.time()
     for epoch in range(epochs):
         labels_list = []
         prediction_list = []
         loss_list = []
         model.train()
         for _, (images, labels) in tqdm(enumerate(dataloader), total=len(dataloader), leave=True):
             images, labels = images.cuda(), labels.cuda()
             optimizer.zero_grad()
             outputs = model(images)
             loss = criterion(outputs, labels)
             loss_list.append(loss)
             outputs = torch.max(outputs, dim=1)[1]
             prediction_list.extend(outputs)
             labels_list.extend(labels)
             loss.backward()
             optimizer.step()
         acc = accuracy_score(labels.cpu().detach().numpy(), outputs.cpu().detach().numpy())
         if dist.get_rank() == 0:
             print(f'Epoch: {epoch + 1} \t loss: {sum(loss_list) / len(loss_list)} \t acc: {acc}')
             if acc > best_acc:
                 best_acc = acc
                 print(f"best acc:{best_acc}  model save!")
                 torch.save(model.state_dict(), ckpt_save_path)
     return time.time() - start

image-20230623005248983

得益于pytorch封装,相比起来单机多卡仅仅多了几行代码。比如数据的分布式采样以及模型的分布式,简单说就是每张显卡都有模型或者副本以及数据,然后反向传播的时候这些模型的梯度会同步下降,保证不同显卡上的模型权重相同。不过也可以看出为了DDP我们还是做了一些看起来没有太大必要的事情,比如保证dist.init_process_group来实现不同显卡之间的通信,而且手动去设置模型以及数据的分布式貌似也不是那么省事(对于我这个懒人),更不合理的地方在于如果我为了单机多卡训练写好的代码,换到单卡环境还得重新改写代码,反之亦然。

是否有更好的封装能够完美兼容pytorch的训练呢?真的有,那就是Accelerate

通过Accelerate,我们可以写一套单机单卡的代码仅仅修改几句,然后在任何环境下都可以运行。还记得一开始的那个单机单卡demo吗?现在我们用Accelerate来完善一下。

 from accelerate import Accelerator
 ​
 def get_dataloader():
     transform = transforms.Compose([
         transforms.ToTensor(),
     ])
     dataset = torchvision.datasets.MNIST("./", train=True, transform=transform, download=True)
     dataloader = DataLoader(dataset, batch_size=256, shuffle=True, num_workers=12, pin_memory=True)
     return dataloader
 ​
 ​
 def train(epochs=10, ckpt_save_path='./best.pt'):
     model = Model(10).to(device)
     criterion = nn.CrossEntropyLoss()
     optimizer = optim.Adam(model.parameters(), lr=1e-4)
     dataloader = get_dataloader()
     model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader)
     best_acc = -torch.inf
 ​
     start = time.time()
     for epoch in range(epochs):
         labels_list = []
         prediction_list = []
         loss_list = []
         model.train()
         for _, (images, labels) in tqdm(enumerate(dataloader), total=len(dataloader), leave=True):
             optimizer.zero_grad()
             outputs = model(images)
             loss = criterion(outputs, labels)
             accelerator.backward(loss)
             optimizer.step()
             loss_list.append(loss)
             outputs = torch.max(outputs, dim=1)[1]
             prediction_list.extend(outputs)
             labels_list.extend(labels)
         acc = accuracy_score(labels.cpu().detach().numpy(), outputs.cpu().detach().numpy())
         print(f'Epoch: {epoch + 1} \t loss: {sum(loss_list) / len(loss_list)} \t acc: {acc}')
         if acc > best_acc:
             best_acc = acc
             print(f"best acc:{best_acc}  model save!")
             torch.save(model.state_dict(), ckpt_save_path)
     return time.time() - start
 ​
 ​
 def main():
     print(f"Accelerate training cost:{train(epochs=10)}")
 ​
 ​
 if __name__ == '__main__':
     accelerator = Accelerator()
     device=accelerator.device
     main()

几乎一模一样,只需要一个accelerator.prepareaccelerator.backward就可以实现一次代码多处使用,这不就是大家都喜欢的“跨平台”特性吗?再来看看训练速度,只需要一行代码运行accelerate launch --multi_gpu --num_processes=2 train2.py

image-20230623013901141

看起来和pytorch的ddp训练时间差不多,时间测试不算准确毕竟没有取多次平均,但是如此方便的特性谁又会在乎慢几秒呢。况且在训练过程中可以直接设置fp16,只需要加上--mixed_precision=fp16,而不用自己写amp和scaler那几行,更加适合把精力放在模型优化而不是训练上。

总结

其实不光Pycharm,VsCode安装remote插件同样可以实现远程操作,这里主要是考虑文件同步问题,一定要记得上传!!! 分布式训练有的时候一些Bug确实非常恼人,但是Accelerate算是给出了一种很好的解决方案。想到这就想发散一点,封装其实也是制定了一些硬性规则,如果这些规则足够易用用户还是能接受的。反观国内一些库,一个库依赖另一个库版本还要匹配,想要去修改一点点东西牵一发而动全身属实够恶心的,用起来更多的感受是心累。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【NX】NX二次开发设置对象高亮和颜色模板实现

在NX二次开发当中,我们经常需要高亮一个或者多个对象,或者设置对象的颜色方便实现,直接调用函数稍微显得麻烦,尤其是当我们需要处理的对象是容器的时候,于是我写了几个简单的模板实现,方便调试。 //author&…

Android Studio利用CMake生成.so文件并且可供其他项目引用

1、CMake工具 1.1、CMake是什么 CMake是一个主要用于CPP的构建工具。CMake语言是平台无关的中间编译工具。同一个CMake编译规则在不同系统平台构建出不同的可执行构建文件,所有操作都是通过编译CMakeLists.txt来完成的。在Linux产生MakeFile,在Windows…

5.1ORB-SLAM3之回环检测线程检测是否存在共视区域

1.简介 本质上是计算当前关键帧和关键帧数据库中的关键帧是否存在公共单词,相似性分数是否满足要求。 bool LoopClosing::NewDetectCommonRegions();主要包括以下几个模块: 寻找回环候选关键帧和融合候选关键帧对候选关键帧进行共视几何验证如果共视几…

Android Studio实现内容丰富的安卓校园二手交易平台(带聊天功能)

如需源码可以添加q-------3290510686,也有演示视频演示具体功能,源码不免费,尊重创作,尊重劳动。 项目编号083 1.开发环境 android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端: 1.注册登录 2.查看二手商品…

AndroidStudio设置compileSdk33后xml无提示问题

这个非常蛋疼的问题遇到很多次了,AndroidStudio升级compileSdk33后无xml提示。挺久前写一个调研demo时发现了这个问题,但因为那会任务重,也没有去深入研究,就在写代码时用target32,写完打包demo时修改为33,…

附录7-用户列表案例,element-ui

目录 1 效果 1.1 查询所有用户 1.2 添加新用户 1.3 删除用户 1.4 用户详情 2 后端 2.1 查询所有 2.2 添加 2.3 删除 2.4 查询单个 3 前端 3.1 环境 3.2 main.js 3.3 userList.vue 3.4 userInfo.vue 1 效果 1.1 查询所有用户 1.2 添加新用户 …

工厂水电能耗监测系统组成

工厂水电能耗监测系统是一种用于监测工厂水电能耗的系统,可以帮助工厂管理者了解水电能耗情况,提高能源利用效率,降低生产成本。本文将从系统组成、功能、优点等方面进行介绍。 一、系统组成 工厂水电能耗监测系统由多个部分组成&#xff0c…

MySQL第一天

文章目录 作业1 简述MySQL体系结构CetenOS 7的MySQLyum在线安装CetenOS 7的MySQL的二进制方式安装 作业1 简述MySQL体系结构 MySQL是由SQL接口、解析器、优化器、缓存、储存引擎组成的,MySQL的最重要的是它的储存引擎架构,这种设计将查询处理及其系统任…

【运维工程师学习】Debian安装

【运维工程师学习】Debian安装 1、界面说明2、选择语言3、等待探测并挂载安装介质完成4、设置主机名称、用户信息5、磁盘分区6、创建分区7、最终分区为8、安装ssh9、查看ssh状态10、查看内存大小11、查询系统磁盘及分区情况12、查看各磁盘及分区剩余13、查看ip地址 选择镜像文件…

新服务器配环境

本章节的大概思路为: 1、远程连接服务器 直接远程连接,前的是你要连接的目录名称,后为服务器公网IP。 ssh xxxxxx.xxx.xxx.xxx 远程连接服务器不同端口 -p后为端口名称 ssh xxxxxx.xxx.xxx.xxx -p xxxx 之后输入密码就行了。 2、创建子用…

c语言修炼之猜数字游戏

前言 小伙伴们&#xff0c;今天来学习猜数字游戏叭&#xff01;废话不多说&#xff0c;让我们一起开始学习叭! 思路&#xff1a; 一打开游戏就出现一个菜单然后可以让我们选择是进入游戏还是退出游戏&#xff01; #include<stdio.h> void menu() {printf("*****…

详解高性能无锁队列的实现

一、无锁队列 1.1 什么是无锁队列 无锁队列&#xff08;Lock-Free Queue&#xff09;是一种并发数据结构&#xff0c;它允许多个线程在没有锁的情况下进行并发操作。 传统的队列通常通过互斥锁来实现线程安全的操作&#xff0c;但互斥锁在高并发情况下可能会造成竞争和性能瓶…

【后端面经-Java】AQS详解

【后端面经-Java】AQS详解 1. AQS是什么&#xff1f;2. AQS核心思想2.1 基本框架2.1.1 资源state2.1.2 CLH双向队列 2.2 AQS模板 3. 源码分析3.1 acquire(int)3.1.1 tryAcquire(int)3.1.2 addWaiter(Node.EXCLUSIVE)3.1.3 acquireQueued(Node node, int arg) 3.2 release(int)3…

校园水电节能管理解决方案

随着社会经济的不断发展&#xff0c;能源问题日益突出&#xff0c;节能减排成为了各级各类学校必须面对的问题。学校的水电能源消耗是其中的一个重要方面&#xff0c;因此&#xff0c;如何对校园水电进行节能管理成为了一个迫切的问题。本文将从以下几个方面介绍校园水电节能管…

在选择自动化测试工具时需要考虑哪些因素?

自动化测试工具是软件开发中不可或缺的一部分&#xff0c;它可以提高测试效率、减少人力成本、提升软件质量&#xff0c;那在选择自动化测试工具时需要考虑哪些因素&#xff1f; 测试需求&#xff1a;首先要明确自动化测试的需求是什么&#xff0c;不同的测试需求对应着不同的工…

电子电气架构相关安全体系介绍

摘要&#xff1a; 随着电子电气架构技术的不断升级&#xff0c;整车越来越多的系统和组件对功能安全产生影响&#xff0c;为此&#xff0c;功能安全也从部分关键系统开发&#xff0c;向整车各系统全面开发拓展。同时&#xff0c;由于域集中式、中央集中式等新架构形态的出现&a…

文档翻译免费怎么做?三分钟告诉你

小乐&#xff1a;嘿&#xff0c;小阳&#xff0c;你知道吗&#xff1f;我最近在学习文档翻译英文&#xff0c;真是太神奇了&#xff01; 小阳&#xff1a;哇&#xff0c;真的吗&#xff1f;那听起来很厉害啊&#xff01;文档翻译英文是怎么做的呢&#xff1f; 小乐&#xff1…

深入解析Java多态进阶学习

目录 1.动态绑定机制 实例A实例B实例C2.多态数组 3.多态数组的高阶用法 4.多态参数 5.多态参数的高阶用法 1.动态绑定机制 java的动态绑定机制非常重要 实例A 我们来看一个实例&#xff1a; 阅读上面的代码&#xff0c;请说明下面的程序将输出什么结果&#xff1a; 程序将会…

机器学习24:《数据准备和特征工程-II》收集数据

构建数据集常用的步骤如下所示&#xff1a; 收集原始数据。识别特征和标签来源。选择抽样策略。拆分数据。 这些步骤在很大程度上取决于你如何构建 ML 问题。本文主要介绍——数据收集-Collecting Data。 目录 1. 数据集的大小和质量 1.1 数据集的大小 1.2 数据集的质量 …

.NET Core webapi 从零开始在IIS上面发布后端接口

文章目录 原因环境配置windows环境.NET Core安装开发端安装服务端安装 新建ASP.NET项目 原因 .NET core是以后.NET未来的趋势&#xff0c;虽然我感觉Java在web后端的主导地位10年内不会动摇&#xff0c;因为Java占据了先发优势。 不过C#的特点就是&#xff0c;简单&#xff0…