9

我已经阅读了我能找到的关于 torch.distributed.barrier() 的所有文档,但仍然无法理解它是如何在这个脚本中使用的,并且非常感谢一些帮助。

因此,torch.distributed.barrier 的官方文档说它“同步所有进程。这个集体阻止进程,直到整个组进入这个函数,如果 async_op 为 False,或者如果在 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

我无法将代码中的注释与官方文档中所述的此函数的功能联系起来。它如何确保只有第一个进程在两次调用 torch.distributed.barrier() 之间执行代码,为什么它只在第二次调用之前检查本地排名是否为 0?

提前致谢!

4

1 回答 1

19

首先你需要了解等级。简而言之:在多处理上下文中,我们通常假设等级 0 是第一个进程或基本进程。然后对其他进程进行不同的排序,例如1、2、3,总共四个进程。

有些操作不需要并行完成,或者您只需要一个进程进行一些预处理或缓存,以便其他进程可以使用该数据。

在您的示例中,在非基本进程(等级 1、2、3)输入的第一个 if 语句中,它们将阻塞(或“等待”),因为它们遇到障碍。他们在那里等待,因为barrier()阻塞直到所有进程都到达障碍,但基本进程还没有到达障碍。

所以此时非基础进程(1、2、3)被阻塞,但基础进程(0)继续。基本进程将执行一些操作(在这种情况下是预处理和缓存数据),直到它到达第二个 if 语句。在那里,基本进程将遇到障碍。至此,所有进程都已停在屏障处,意味着可以解除屏障,所有进程都可以继续进行。因为基础进程准备了数据,所以其他进程现在可以使用该数据。

也许最重要的是要理解:

  • 当进程遇到障碍时,它将阻塞
  • 屏障的位置并不重要(例如,并非所有进程都必须输入相同的 if 语句)
  • 一个进程被一个屏障阻塞,直到所有进程都遇到一个屏障,然后所有进程的屏障都被解除
于 2020-01-16T09:24:29.343 回答