记录使用Pytorch分布式训练(torch.distributed)踩过的坑

news2024/11/26 16:38:57

引言

最近由于想加速神经网络模型训练,便开始着手学习pytorch的分布式训练(DDP),结果踩了很多坑,在这里记录一下,便于以后查看,也同时分享给大家。

教程

我是通过下面几篇博客学习pytorch分布式训练的,感觉写得都不错,很清晰明了,强烈推荐第一篇:

  1. https://zhuanlan.zhihu.com/p/358974461
  2. https://zhuanlan.zhihu.com/p/76638962
  3. https://zhuanlan.zhihu.com/p/113694038

一些遇到的坑

不同进程的loss不一致

在训练过程中,我设置了两个进程,使其以数据并行的方式训练,但是在训练过程中,我发现两个进程的loss竟然不一致:

在这里插入图片描述

DDP可以自动实现不同进程间的梯度同步,从而使各进程的参数保持一致。因此出现这种情况主要是因为train_sampler使用了DistributedRandomIdentitySampler,该类的__iter__函数会根据进程的rank将数据集划分为不同部分,从而使各个进程读取的训练集中的数据不同,如下所示:

class DistributedRandomIdentitySampler(Sampler):
		'''......此处省略其它代码......'''
		# 从list_container中获取当前进程对应的样本索引
        list_container = list_container[self.rank:self.total_size//self.num_instances:self.num_replicas]
        assert len(list_container) == self.num_samples//self.num_instances

因此,虽然各个进程的模型参数一致,但训练时读取的数据不同,计算出的loss也就会不同。顺便提一句,每个进程的batch_size相同(手动设置),只是读取的数据不同,而DDP会将不同进程的batch数据对应的梯度进行聚合并同步梯度,因此DDP的实际batch_size是设置的batch_size的n倍,n为进程数量。

除此之外还有一种情况,就是不同进程的参数初始化不一致,这也会导致不同进程的训练出现loss值不同的情况。此时应该检查随机数种子是否固定,从而防止参数初始化的随机性。如下所示,即在不同进程中固定set_seed函数的输入seed值:

def set_seed(seed=None):
    if seed is None:
        return
    random.seed(seed)
    os.environ['PYTHONHASHSEED'] = ("%s" % seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    torch.backends.cudnn.benchmark = False
    torch.backends.cudnn.deterministic = True

在测试时使用了DistributedInferenceSampler

在测试阶段如果使用了DistributedInferenceSampler,会导致不同进程读取到的测试集数据不同,因此测试结果也不同,这是错误的。正确做法是testloader不使用DistributedInferenceSampler而直接使用默认的sampler(不指定sampler):

galleryloader = DataLoader(dataset=ImageDataset_test(dataset.gallery, transform=transform_test),
                                batch_size=config.DATA.TEST_BATCH, num_workers=config.DATA.NUM_WORKERS,
                                pin_memory=True, drop_last=False, shuffle=False)

遇到报错:RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. This error indicates that your module has parameters that were not used in producing loss.

解决方法:在使用nn.parallel.DistributedDataParallel封装模型时加上find_unused_parameters=True:

model = nn.parallel.DistributedDataParallel(model, device_ids=[rank], output_device=rank, find_unused_parameters=True)

遇到报错:RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation.

解决方法:检查在训练过程中有没有出现同一个模型被前向执行两次及以上的情况,例如:

features1=model(img1)
features2=model(img2)

将同一个模型的前向输出过程写到一行代码中,如下所示:

features1, features2 = model(torch.cat((img1, img2), dim=0)).split(img1.size(0), dim=0)

如果这种方式没有成功解决报错,在nn.parallel.DistributedDataParallel封装模型时加上broadcast_buffers=False,即设置模型在每次迭代时不要提前将缓冲区内的数据覆盖到其它进程:

model = nn.parallel.DistributedDataParallel(model, device_ids=[rank], output_device=rank, find_unused_parameters=True, broadcast_buffers=False)

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

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

相关文章

JVM类加载器及其详解

1.JVM加载过程分析 1.1加载流程图 1.2双亲委派机制 引导类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如rt.jar、charsets.jar等扩展类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包应用程序…

chatgpt赋能python:Python倒序的实现方法介绍

Python倒序的实现方法介绍 Python是一种高级编程语言,被广泛用于数据处理、人工智能、Web开发等领域。其中,倒序是常见的一种操作需求。Python提供了多种实现倒序的方法,下面进行详细介绍。 1. 切片 切片是Python中常用的语法,…

chatgpt赋能python:Python倒序循环–优化你的编程效率

Python倒序循环 – 优化你的编程效率 在Python编程中,倒序循环是一种非常强大的操作。它可以用于遍历一个序列并对其中的元素进行逆序处理,从而提高编程效率。本文将介绍Python倒序循环的优势及如何在编程中使用。 什么是Python倒序循环 在传统循环中…

Web应用技术(第十五周/END)

本次练习基于how2j和课本,进行SSM的初步整合,理解SSM整合的原理、好处。 SSM整合应用 1.简单的实例项目:2.原理分析:3.浅谈使用SSM框架化: 1.简单的实例项目: how2j 2.原理分析: 具体见流程图…

MySQL-1-基础

MySQL 简介 mysql-server #提供服务 mysql-client #提供SQL命令 官网地址:https://dev.mysql.com/downloads/ https://downloads.mysql.com/archives/community/查看帮助文档 mysql> ? contents一、安装MySQL 1.1、二进制安装mysql5.7-linux 安装前准备 sh…

SpringBoot 的创建和使用

Spring Boot 的优点 Spring的出现是为了简化 Java 程序开发,而 SpringBoot 的出现是为了简化 Spring 程序开发. SpringBoot 就是 Spring脚手架 快速集成框架,Spring Boot提供了启动添加依赖的功能,用于秒级集成各种框架。内置运行容器,无需配…

python+vue大学新生入学报道交流平台pycharm

本系统的用户可分学生、教师、管理员三类。 管理员模块 1)登录:管理员输入用户名、密码;选择“管理员”角色;点击登录按钮。 2)管理员主界面:以管理员身份登录成功后,选择进入网站系统管理模块;选择进入首页…

Python字符串类型的使用

文章目录 Python中的字符串类型一、字符串的常用操作二、字符串的常用函数 Python中的字符串类型 注意:字符串为不可修改类型 python中没有单独的字符类型,字符就是长度为1的字符串。 通常创建字符串的方式:一般用单引号(’ &am…

从数据库到固态硬盘的读取过程

应用程序到数据库到操作系统到固态硬盘 在我研究了从应用程序发送的简单 SQL 查询是如何最终存储到磁盘的过程中,我发现术语 “页(page)” 和 “块(block)” 可能是软件工程中最多用的概念之一。有数据库页&#xff08…

Python新技术和趋势:如何应对Python生态的变化和发展趋势

第一章:引言 Python作为一门简洁、优雅且易于学习的编程语言,一直以来都备受开发者的喜爱。它拥有强大的生态系统和活跃的社区,使得Python在各个领域都有广泛的应用。然而,随着时间的推移,Python生态系统也在不断演变…

STM32H743烧录后无法识别Jlink的问题

利用Cubemx生成H743的代码,点击烧录后,无法再识别到Jlink了,只能烧录时按着复位再松开(类似51单片机)。 烧录后不运行,用keil进行debug,调试发下芯片进去内存管理错误中断。 经过不断调试发现&…

vuex核心

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、什么是状态管理?二、复杂的状态管理1.随着代码越来越多,需要管理的状态越来越复杂,当多个组件共享状态时,单…

​刷爆朋友圈!前百度总裁陆奇最新AI重磅演讲:我的大模型世界观​

陆奇的演讲刷屏了,我认真看了他的演讲稿,收获颇丰。 陆奇提到,人类社会的发展,大致可分为:农业化、工业化和数字化三个阶段。 在三个递进的阶段中,人类一直在探索如何减少烦琐且消耗能量的体力和脑力劳动&a…

安装 MySQL 8 如何在生产环境中

文章结构 安装生产环境安装 MySQLDocker 安装 MySQL 相关资源网址 安装 生产环境安装 MySQL 一般的,我们使用 RPM 包的方式完成 MySQL 的安装,本教程参考了官方的安装说明,安装的具体步骤如下: 什么是 RPM: rpm&…

chatgpt赋能python:Python代码怎么读?

Python代码怎么读? Python是一种高级编程语言,它具有明确简洁的语法和丰富的资源库。它是一个简单易学的语言,非常适合编写快速原型。 但是,对于初学者来说,Python代码可能看起来有点吓人。好消息是,Pyth…

前端基础(HTML)——html介绍 常用标签 几个案例

引出 html是啥,常见的标签,几个例子 一、概述 1.1 HTML是什么? Hyper Text Markup Language (超文本标记语言) 简写:HTML,HTML 通过标签来标记要显示的网页中的各个部分。网页文件本身是一种文本文件, 通过在文本文…

solr快速上手:创建核心/索引/core(四)

0. 引言 上节,我们讲解了solr的核心配置文件managed-schema,了解定义索引的核心配置标签,今天我们来实操配置,创建一个索引 solr快速上手:solr简介及安装(一) solr快速上手:核心概…

chatgpt赋能python:Python修改上一行:简化你的工作流程

Python修改上一行:简化你的工作流程 作为一名有10年Python编程经验的工程师,我一直在探索更加高效的工作方式。今天,我想向大家分享的是Python修改上一行的技巧,让你的工作流程更加简化,提高工作效率。 什么是Python…

【利用AI让知识体系化】进程和线程

文章目录 1. 介绍1.1 什么是进程1.2 什么是线程1.3 进程和线程之间的关系 2. 进程的概念2.1 进程的定义2.2 进程的特征2.3 进程的状态2.4 进程的调度 3. 线程的概念3.1 线程的定义3.2 线程的优点3.3 线程的实现3.4 线程的调度 4. 进程和线程的比较4.1 进程和线程的区别4.2 进程…

chatgpt赋能python:Python修改Word二级标题的SEO优化

Python修改Word二级标题的SEO优化 Python是一种非常流行的编程语言,可以用于许多各种各样的应用程序。其中之一是用Python处理文档,其中一个重要的任务是修改文档中的标题。二级标题是英文文档中非常常见的元素,这篇文章将介绍如何使用Pytho…