东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 3622|回复: 5
打印 上一主题 下一主题

[课堂笔记] pytorch训练过程中突然死机,重启才行

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14432
QQ
跳转到指定楼层
楼主
发表于 2020-8-21 11:17:52 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式


pytorch训练过程中突然死机,重启才行


分析问题的原因:
1、内存溢出 用htop查看,并未出现内存过大
2、内存泄漏 需要在训练结束后关闭 SummaryWriter
self.writer.close()   但是一般只会出现在训练多轮后 才会卡死
3、pytorch由dataloader引发的死锁 pin_memory = True num_workers的配置问题
该问题在pytorch的官方github上的issue上有提到, 这里不再赘述。
https://github.com/pytorch/pytorch/issues/1355
4、多进程的启动问题
from torch.multiprocessing import set_start_method
set_start_method('spawn')
需要注意的是,该函数的调用位置,必须位于所有与多进程有关的代码之前。


启动进程的方式大致可分为以下 3 种:

    spawn:使用此方式启动的进程,只会执行和 target 参数或者 run() 方法相关的代码。Windows 平台只能使用此方法,事实上该平台默认使用的也是该启动方式。相比其他两种方式,此方式启动进程的效率最低。
    fork:使用此方式启动的进程,基本等同于主进程(即主进程拥有的资源,该子进程全都有)。因此,该子进程会从创建位置起,和主进程一样执行程序中的代码。注意,此启动方式仅适用于 UNIX 平台,os.fork() 创建的进程就是采用此方式启动的。
    forserver:使用此方式,程序将会启动一个服务器进程。即当程序每次请求启动新进程时,父进程都会连接到该服务器进程,请求由服务器进程来创建新进程。通过这种方式启动的进程不需要从父进程继承资源。注意,此启动方式只在 UNIX 平台上有效。

    总的来说,使用类 UNIX 平台,启动进程的方式有以上 3 种,而使用 Windows 平台,只能选用 spawn 方式(默认即可)


最终我的配置:
pin_memory = True
num_workers = 0
# from multiprocessing import set_start_method
from torch.multiprocessing import set_start_method
set_start_method('spawn')

此 API 100% 兼容原生模块 - 所以足以将 import multiprocessing 改成 import torch.multiprocessing 使得所有的 tensors 通过队列发送或者使用其它共享机制, 移动到共享内存











pytorch dead.png (94.67 KB, 下载次数: 127)

pytorch dead.png
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14432
QQ
沙发
 楼主| 发表于 2020-8-21 11:25:41 | 只看该作者
如果我的配置:
pin_memory = True
num_workers = 8
# from multiprocessing import set_start_method
from torch.multiprocessing import set_start_method
set_start_method('spawn')


会报错:RuntimeError: context has already been set
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14432
QQ
板凳
 楼主| 发表于 2020-8-21 11:26:40 | 只看该作者
这个也会报错:RuntimeError: context has already been set


  1. import torch
  2. import torch.multiprocessing as mp
  3. torch.multiprocessing.set_start_method("spawn")


  4. def sub_processes(A, B, D, i, j, size):

  5.     D[(j * size):((j + 1) * size), i] = torch.mul(B[:, i], A[j, i])


  6. def task(A, B):
  7.     size1 = A.shape
  8.     size2 = B.shape
  9.     D = torch.zeros([size1[0] * size2[0], size1[1]]).cuda()
  10.     D.share_memory_()

  11.     for i in range(1):
  12.         processes = []
  13.         for j in range(size1[0]):
  14.             p = mp.Process(target=sub_processes, args=(A, B, D, i, j, size2[0]))
  15.             p.start()
  16.             processes.append(p)
  17.         for p in processes:
  18.             p.join()

  19.     return D


  20. A = torch.rand(3, 3).cuda()
  21. B = torch.rand(3, 3).cuda()
  22. C = task(A, B)
  23. print(C)
复制代码
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14432
QQ
地板
 楼主| 发表于 2020-8-21 11:30:10 | 只看该作者
解决方法:当使用spawn的时候 要用 if __name__ == "__main__"
这样改就可以了

  1. import torch
  2. import torch.multiprocessing as mp
  3. from torch.multiprocessing import set_start_method


  4. def sub_processes(A, B, D, i, j, size):

  5.     D[(j * size):((j + 1) * size), i] = torch.mul(B[:, i], A[j, i])


  6. def task(A, B):
  7.     size1 = A.shape
  8.     size2 = B.shape
  9.     D = torch.zeros([size1[0] * size2[0], size1[1]]).cuda()
  10.     D.share_memory_()

  11.     for i in range(1):
  12.         processes = []
  13.         for j in range(size1[0]):
  14.             p = mp.Process(target=sub_processes, args=(A, B, D, i, j, size2[0]))
  15.             p.start()
  16.             processes.append(p)
  17.         for p in processes:
  18.             p.join()

  19.     return D


  20. if __name__ == "__main__":
  21.     set_start_method("spawn")
  22.     A = torch.rand(3, 3).cuda()
  23.     B = torch.rand(3, 3).cuda()
  24.     C = task(A, B)
  25.     print(C)

复制代码
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14432
QQ
5#
 楼主| 发表于 2020-8-21 11:40:37 | 只看该作者
东方耀 发表于 2020-8-21 11:30
解决方法:当使用spawn的时候 要用 if __name__ == "__main__"
这样改就可以了

但是 我的pytorch训练到几轮后 还是会卡死  以后再继续尝试吧
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14432
QQ
6#
 楼主| 发表于 2020-8-22 13:34:20 | 只看该作者
后来发现:换了一个显卡 一切又都可以了   
配置成以前的:
pin_memory = True
num_workers = 16
不需要下面的:
# from multiprocessing import set_start_method
from torch.multiprocessing import set_start_method
set_start_method('spawn')
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|人工智能工程师的摇篮 ( 湘ICP备2020019608号-1 )

GMT+8, 2024-4-26 15:37 , Processed in 0.183054 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表