使用分布式训练(例如DDP)时如何修复pytorch中的SIGSEGV?

Cha*_*ker 5 python distributed-computing multiprocessing neural-network pytorch

在 pytorch 中运行 DDP 时,我不断遇到此问题:

\n
Traceback (most recent call last):\n  File "ml4coq-proj/embeddings_zoo/tree_nns/main_brando.py", line 330, in <module>\n    main_distributed()\n  File "ml4coq-proj/embeddings_zoo/tree_nns/main_brando.py", line 230, in main_distributed\n    mp.spawn(fn=train, args=(opts,), nprocs=opts.world_size)\n  File "/home/miranda9/miniconda3/envs/automl-meta-learning/lib/python3.8/site-packages/torch/multiprocessing/spawn.py", line 199, in spawn\n    return start_processes(fn, args, nprocs, join, daemon, start_method=\'spawn\')\n  File "/home/miranda9/miniconda3/envs/automl-meta-learning/lib/python3.8/site-packages/torch/multiprocessing/spawn.py", line 157, in start_processes\n    while not context.join():\n  File "/home/miranda9/miniconda3/envs/automl-meta-learning/lib/python3.8/site-packages/torch/multiprocessing/spawn.py", line 105, in join\n    raise Exception(\nException: process 1 terminated with signal SIGSEGV\n
Run Code Online (Sandbox Code Playgroud)\n

但这个错误的信息量相当小(例如,它没有告诉我什么进程或它试图访问什么),所以我不确定我需要做什么来解决它。

\n

一些研究告诉你:

\n
\n

SIGSEGV:在 Linux 等 Unix 操作系统上,“分段违规”(也称为“信号 11”、“SIGSEGV”、“分段错误”或缩写为“sig11”或“segfault”)是由当系统检测到某个进程正在尝试访问不属于它的内存地址时,内核会向该进程发出通知。通常,这会导致违规进程被终止。

\n
\n

是的,我确实有通常mp.spawn(fn=train, args=(opts,), nprocs=opts.world_size)需要的多处理代码。

\n

首先,我阅读了有关共享策略的文档,其中讨论了如何在 pytorch 中共享张量:

\n
\n

请注意,它仅适用于 CPU 张量 - CUDA 张量将始终使用 CUDA API,因为 \xe2\x80\x99s 是它们共享的唯一方式。

\n
\n

我使用的是文件系统共享内存,因为当我需要大量进程时,它似乎给我带来了更少的问题,但我只使用了 2 个进程和 2 个 GPU,并且共享策略为文件描述符。我想也许如果进程有自己的缓存文件描述符,那么就不会有问题。

\n

我确实检查了可用的 cuda 设备:

\n
 $ echo $CUDA_VISIBLE_DEVICES\n1,3\n
Run Code Online (Sandbox Code Playgroud)\n

一切看起来都很好。

\n

我不确定是什么原因导致了这个问题。可能存在以下问题:

\n
    \n
  • 两个进程试图同时检查点,但我总是只让rank=0检查点进行,这样就没有意义。
  • \n
  • 两个进程正在写入张量板,但我也只允许rank=0进行日志记录(或任何打印)。
  • \n
\n

所以我不确定是什么原因导致了这个问题。可能是我的数据集连接了所有 1 个单个 json 文件,导致了问题,但这并没有导致昨天多个 GPU 出现问题……不过,如果是这种情况,则很难修复,因为DDP(分布式)数据并行)使用DistributedSampler,它不会对我的数据集或数据加载器施加任何限制......或者至少据我所知(afaik)。

\n

最后一件事是,昨天我也遇到了奇怪的错误,不知怎的,我突然想到检查 GPU 类型。我正在提出一个问题,因为我使用的是 k40 gpu。我确信情况并非如此。昨天我使用的是Quadro 6000 RTX,今天看来这些是我得到的 GPU:

\n
$ nvidia-smi\nTue Mar  2 12:15:04 2021       \n+-----------------------------------------------------------------------------+\n| NVIDIA-SMI 450.36.06    Driver Version: 450.36.06    CUDA Version: 11.0     |\n|-------------------------------+----------------------+----------------------+\n| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |\n| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |\n|                               |                      |               MIG M. |\n|===============================+======================+======================|\n|   0  TITAN X (Pascal)    Off  | 00000000:02:00.0 Off |                  N/A |\n| 22%   37C    P0    56W / 250W |      0MiB / 12196MiB |      0%      Default |\n|                               |                      |                  N/A |\n+-------------------------------+----------------------+----------------------+\n|   1  TITAN X (Pascal)    Off  | 00000000:03:00.0 Off |                  N/A |\n| 24%   39C    P0    56W / 250W |      0MiB / 12196MiB |      0%      Default |\n|                               |                      |                  N/A |\n+-------------------------------+----------------------+----------------------+\n|   2  TITAN X (Pascal)    Off  | 00000000:82:00.0 Off |                  N/A |\n| 53%   84C    P2   244W / 250W |  11935MiB / 12196MiB |     57%      Default |\n|                               |                      |                  N/A |\n+-------------------------------+----------------------+----------------------+\n|   3  TITAN X (Pascal)    Off  | 00000000:83:00.0 Off |                  N/A |\n| 25%   39C    P0    56W / 250W |      0MiB / 12196MiB |      3%      Default |\n|                               |                      |                  N/A |\n+-------------------------------+----------------------+----------------------+\n                                                                               \n+-----------------------------------------------------------------------------+\n| Processes:                                                                  |\n|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |\n|        ID   ID                                                   Usage      |\n|=============================================================================|\n|    2   N/A  N/A     31809      C   python                          11933MiB |\n+-----------------------------------------------------------------------------+\n
Run Code Online (Sandbox Code Playgroud)\n

不确定这是否会导致问题,但获得 Quadro 并不总是现实的,所以我希望它也适用于 Titan(以及任何不是 k40s 的东西,因为 k40s 似乎pytorch 不再支持)。

\n

有一些 pytorch 讨论论坛帖子和 gitissues,但似乎没有一个很有帮助(至少对我来说 - 尽管讨论结束,但不清楚他们做了什么来解决问题):

\n\n

我还注意到当排名 0 在排名 1 之前结束时会发生这种情况(这帮助我重现它,否则会发生 sigabort SIGABRT)。

\n
    # clean up distributed code\n    torch.distributed.barrier()\n    if rank == 1:\n        time.sleep(1)\n    print(f\'\\n----> about to cleanup worker with rank {rank}\')\n    # cleanup(rank)\n    torch.distributed.destroy_process_group()\n    print(f\'clean up done successfully! {rank}\'\n
Run Code Online (Sandbox Code Playgroud)\n
\n

交叉发布:

\n\n