Pycharm远程设置 DDP简单介绍

前言

最近接到一些改代码或者帮助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 dataloaderdef 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 = accprint(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 dataloaderdef 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 = accprint(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 = accprint(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.devicemain()

几乎一模一样,只需要一个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.hqwc.cn/news/9517.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python自动化测试框架:unittest介绍

Unittest是Python中最常用的测试框架之一,它提供了丰富和强大的测试工具和方法,可以帮助开发者更好地保证代码质量和稳定性,本文就来介绍下Unittest单元测试框架 1. 介绍 unittest是Python的单元测试框架,它提供了一套丰富的测试…

Leetcode---352周赛

周赛题目 2760. 最长奇偶子数组 2761. 和等于目标值的质数对 2762. 不间断子数组 2763. 所有子数组中不平衡数字之和 一、最长奇偶子数组 这题的数据范围允许用暴力来做,只要我们分别枚举左端点left和右端点right,然后看区间[left,right]是否符合题目条…

flutter3.7版本下使用flutter boost解决使用platview崩溃或异常问题

背景 工程使用了混合开发,使用flutter boost插件,flutter 的activity1 frament1 跳转activity2 frament2,frament1 包含platformView,按照上面老哥解决崩溃问题的基础上,出现activity2 frament2返回activity1 framen…

golang 协程的实现原理

核心概念 要理解协程的实现, 首先需要了解go中的三个非常重要的概念, 它们分别是G, M和P, 没有看过golang源代码的可能会对它们感到陌生, 这三项是协程最主要的组成部分, 它们在golang的源代码中无处不在. G (goroutine) G是goroutine的头文字, goroutine可以解释为受管理的…

C++图形开发(6):落下后能弹起的小球

文章目录 1.重复下落的小球2.落下后能弹起的小球3.能上下反弹的小球4.符合重力的能上下反弹的小球 今天我们来尝试实现一个落地后可以弹起的小球 1.重复下落的小球 首先,我们要来实现一个小球的重复下落 我们知道,在前面的代码中(详见C图形…

ChatGPT与Excel结合_编写VBA宏

先来解释下什么是Excel vba宏 ⭐Excel VBA宏(Visual Basic for Applications)是一种用于在Microsoft Excel中自动化和扩展功能的编程语言。VBA允许用户编写自定义的脚本或宏,以便通过执行一系列指令来自动完成特定任务。 使用Excel VBA宏&a…

基于改进莱维飞行和混沌映射的金鹰优化算法(10种混沌映射随意切换),附matlab代码

“ 本篇文章对金鹰优化算法进行改进,首先通过引入混沌映射机制,对其群体进行初始化,增加金鹰个体的多样性;然后在金鹰个体的位置更新公式上引入改进的莱维飞行机制,提高搜索精度,帮助金鹰个体跳出局部最优。…

Work20230705

//main.c #include "uart4.h" extern void printf(const char *fmt, ...); void delay_ms(int ms) {int i,j;for(i 0; i < ms;i)for (j 0; j < 1800; j); }int main() {while(1){//将获取到的字符1发送到终端//hal_put_char(hal_get_char()1);hal_put_string…

监控系统Zabbix

zabbix概述 作为一个运维&#xff0c;需要会使用监控系统查看服务器状态以及网站流量指标&#xff0c;利用监控系统的数据去了解上线发布的结果&#xff0c;和网站的健康状态。 利用一个优秀的监控软件&#xff0c;我们可以&#xff1a; 通过一个友好的界面进行浏览整个网站…

【设计模式】第十七章:状态模式详解及应用案例

系列文章 【设计模式】七大设计原则 【设计模式】第一章&#xff1a;单例模式 【设计模式】第二章&#xff1a;工厂模式 【设计模式】第三章&#xff1a;建造者模式 【设计模式】第四章&#xff1a;原型模式 【设计模式】第五章&#xff1a;适配器模式 【设计模式】第六章&…

谷歌Bard入门指南

文章目录 谷歌Bard入门指南一、简介二、使用指南三、中文化3.1 中文提问3.2 中文回答 四、Hello Game五、亮点 谷歌Bard入门指南 一、简介 Bard 是一个大型语言模型&#xff0c;也称为对话式 AI 或聊天机器人&#xff0c;经过训练&#xff0c;内容丰富且全面。Bard 接受过大量…

Tkinter_使用Progressbar创建和管理进度条

前言 Progressbar是Tkinter库中的一个小部件&#xff0c;用于创建和管理进度条。它可以在图形用户界面中显示任务的进度&#xff0c;并提供了多种样式和配置选项。 使用Progressbar&#xff0c;你可以按照固定或不确定的进度展示任务的进行状态。它可以显示任务完成的百分比&am…