Как работает torch.distributed.barrier () - PullRequest
1 голос
/ 16 января 2020

Я прочитал все документы, которые смог найти о torch.distributed.barrier (), но все еще не могу понять, как он используется в этом скрипте , и был бы очень признателен за помощь.

Таким образом, официальный представитель делает c torch.distributed.barrier и говорит: «Синхронизирует все процессы. Этот коллективный блок обрабатывает процесс до тех пор, пока вся группа не войдет в эту функцию, если async_op имеет значение False или если asyn c рабочий дескриптор вызывается в wait (). "

Используется в сценарии в двух местах:

Первое место

    if args.local_rank not in [-1, 0] and not evaluate:
        torch.distributed.barrier()  # Make sure only the first process in distributed training process the dataset, and the others will use the cache

        ... (preprocesses the data and save the preprocessed data)

    if args.local_rank == 0 and not evaluate:
        torch.distributed.barrier() 

Второе место

    if args.local_rank not in [-1, 0]:
        torch.distributed.barrier()  # Make sure only the first process in distributed training will download model & vocab

        ... (loads the model and the vocabulary)

    if args.local_rank == 0:
        torch.distributed.barrier()  # Make sure only the first process in distributed training will download model & vocab

У меня проблемы с привязкой комментария в коде к функциональности этой функции, указанной в официальном do c. Как убедиться, что только первый процесс выполняет код между двумя вызовами torch.distributed.barrier () и почему он проверяет, равен ли локальный ранг 0 перед вторым вызовом?

Заранее спасибо!

1 Ответ

3 голосов
/ 16 января 2020

Для начала нужно понять ряды. Короче говоря: в контексте многопроцессорности мы обычно предполагаем, что ранг 0 является первым процессом или базовым процессом. Затем другие процессы ранжируются по-разному, например, 1, 2, 3, всего четыре процесса.

Некоторые операции не нужно выполнять параллельно, или вам просто нужен один процесс для некоторой предварительной обработки или кэширования, так что что другие процессы могут использовать эти данные.

В вашем примере, в первом операторе if вводятся неосновные процессы (ранг 1, 2, 3), они будут блокироваться (или «ждать»), потому что сталкиваются с барьером. Они ждут там, потому что barrier() блокирует, пока все процессы не достигли барьера, но базовый процесс еще не достиг барьера.

Так что на этом этапе неосновные процессы ( 1, 2, 3) заблокированы, но базовый процесс (0) продолжается. Базовый процесс будет выполнять некоторые операции (в данном случае предварительную обработку и кеширование данных), пока не достигнет второго оператора if. Там базовый процесс столкнется с барьером. На этом этапе все процессы остановились на барьере, что означает, что барьер может быть снят и все процессы могут продолжаться. Поскольку базовый процесс подготовил данные, другие процессы теперь могут использовать эти данные.

Возможно, наиболее важная вещь для понимания:

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