Распределенный код PyTorch останавливается на нескольких узлах при использовании бэкэнда MPI - PullRequest
0 голосов
/ 03 декабря 2018

Я пытаюсь запустить код Pytorch на трех узлах, используя openMPI, но код просто останавливается без каких-либо ошибок или вывода.В конечном итоге моя цель - распределить граф Pytorch по этим узлам.

Три моих узла подключены к одной локальной сети и имеют SSH-доступ друг к другу без пароля и имеют схожие характеристики:

  • Ubuntu 18.04
  • Cuda 10.0
  • OpenMPI, собранный и установленный из источника
  • PyTorch, собранный и установленный из источника

Приведенный ниже код работает наодин узел - несколько процессов, как:

> mpirun -np 3 -H 192.168.100.101:3 python3 run.py

Со следующим выводом:

INIT 0 of 3 Init env://
INIT 1 of 3 Init env://
INIT 2 of 3 Init env://
RUN 0 of 3 with tensor([0., 0., 0.])
RUN 1 of 3 with tensor([0., 0., 0.])
RUN 2 of 3 with tensor([0., 0., 0.])
Rank  1  has data  tensor(1.)
Rank  0  has data  tensor(1.)
Rank  2  has data  tensor(1.)

Но когда я размещаю код на трех узлах и запускаю следующую команду на каждом узле отдельно, он делаетНичего:

> mpirun -np 3 -H 192.168.100.101:1,192.168.100.102:1,192.168.100.103:1 python3 run.py

Пожалуйста, дайте некоторое представление о каких-либо изменениях в коде или конфигурациях для MPI для запуска данного кода Pytorch на нескольких узлах?

#!/usr/bin/env python
import os
import torch
import torch.distributed as dist
from torch.multiprocessing import Process

def run(rank, size):
    tensor = torch.zeros(size)
    print(f"RUN {rank} of {size} with {tensor}")

    # incrementing the old tensor
    tensor += 1

    # sending tensor to next rank
    if rank == size-1:
       dist.send(tensor=tensor, dst=0)
    else:
       dist.send(tensor=tensor, dst=rank+1)

    # receiving tensor from previous rank
    if rank == 0:
        dist.recv(tensor=tensor, src=size-1)
    else:
        dist.recv(tensor=tensor, src=rank-1)

    print('Rank ', rank, ' has data ', tensor[0])


def init_processes(rank, size, fn, backend, init):
    print(f"INIT {rank} of {size} Init {init}")
    dist.init_process_group(backend, init, rank=rank, world_size=size)
    fn(rank, size)


if __name__ == "__main__":
    os.environ['MASTER_ADDR'] = '192.168.100.101'
    os.environ['BACKEND'] = 'mpi'
    os.environ['INIT_METHOD'] = 'env://'
    world_size = int(os.environ['OMPI_COMM_WORLD_SIZE'])
    world_rank = int(os.environ['OMPI_COMM_WORLD_RANK'])

    init_processes(world_rank, world_size, run, os.environ['BACKEND'], os.environ['INIT_METHOD'])

NB NCCL не вариант для меняиз-за аппаратного обеспечения на основе arm64.

1 Ответ

0 голосов
/ 01 апреля 2019

Извиняюсь за поздний ответ на этот вопрос, но я мог решить эту проблему, добавив - mca btl_tcp_if_include eth1 flag к команде mpirun.

Причиной остановки стало то, что openMPI по умолчанию пытается найти и связаться с другими узлами через локальный петлевой сетевой интерфейс, например, lo .Мы должны явно указать, какой интерфейс (ы) должен быть включен (или исключен) для определения местоположения других узлов.

Надеюсь, это спасет чей-то день:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...