提交 d0efa540 编写于 作者: W wizardforcel

2021-01-19 22:05:43

上级 b602b5be
......@@ -376,9 +376,9 @@ transform = transforms.Compose(
毕竟,实现模型是我们开发流程中最重要的一步。 在某种程度上,我们为此步骤构建了整个管道。 除了构建网络架构之外,我们还需要考虑许多细节来优化实现(在工作量,时间以及代码效率方面)。
在本次会议中,我们将讨论 PyTorch 软件包本身和`ignite`(PyTorch 的推荐训练者实用程序)中提供的性能分析和瓶颈工具。 第一部分介绍了瓶颈和性能分析实用程序,当模型开始表现不佳并且您需要知道哪里出了问题时,这是必不可少的。 本课程的第二部分介绍了训练模块`ignite`
在本次会议中,我们将讨论 PyTorch 软件包本身和`ignite`(PyTorch 的推荐训练者实用程序)中提供的性能分析和瓶颈工具。 第一部分介绍了瓶颈和性能分析实用程序,当模型开始表现不佳并且您需要知道哪里出了问题时,这是必不可少的。 本课程的第二部分介绍了训练模块`ignite`
训练网络并不是真正必需的组件,但它是一个很好的帮助程序实用程序,可以节省大量时间来编写样板文件和修复错误。 有时,它可以将程序的行数减少一半,这也有助于提高可读性。
训练网络并不是真正必需的组件,但它是一个很好的帮助程序实用程序,可以节省大量时间来编写样板文件和修复错误。 有时,它可以将程序的行数减少一半,这也有助于提高可读性。
#### 瓶颈和性能分析
......@@ -443,7 +443,7 @@ python -m torch.utils.bottleneck /path/to/source/script.py [args]
Ignite 是一种神经网络训练工具,可将某些样板代码抽象出来,以使代码简洁明了。 Ignite 的核心是`Engine`模块。 该模块非常强大,因为:
* 它基于默认/自定义训练或评估者运行模型。
* 它基于默认/自定义训练或评估者运行模型。
* 它可以接受处理程序和指标,并对其执行操作。
* 它可以创建触发器并执行回调。
......@@ -492,11 +492,11 @@ evaluator.run(val_loader)
函数`create_supervised_trainer``create_supervised_evaluator`返回一个`Engine`对象,该对象具有类似于`training_loop`的功能来执行代码的公共模式,如先前给出的那样。 除了给定的参数,这两个函数还接受一个设备(CPU 或 GPU),该设备返回在我们指定的设备上运行的训练器或评估器`Engine`实例。 现在情况越来越好了吧? 我们传递了定义的模型,所需的优化器以及正在使用的损失函数,但是在有了训练器和`evaluator`对象之后我们该怎么办?
`Engine`对象定义了`run`方法,该方法使循环根据传递给`run`函数的时期和加载器开始执行。 与往常一样,`run`方法使`trainer`循环从零到历元数。 对于每次迭代,我们的训练都会通过加载程序进行梯度更新。
`Engine`对象定义了`run`方法,该方法使循环根据传递给`run`函数的时期和加载器开始执行。 与往常一样,`run`方法使`trainer`循环从零到历元数。 对于每次迭代,我们的训练都会通过加载程序进行梯度更新。
训练完成后,`evaluator``val_loader`开始,并通过使用评估数据集运行相同的模型来确保情况得到改善。
那很有趣,但仍然缺少一些片段。 如果用户需要在每个时期之后运行`evaluator`,或者如果用户需要训练将模型的精度打印到终端,或者将其绘制到 Visdom,Turing 或 Network 图上,该怎么办? 在前面的设置中,有没有办法让知道验证准确率是什么? 您可以通过覆盖`Engine`的默认记录器来完成大部分操作,该记录器本质上是保存在`trainer_logger`变量中的 Python 记录器,但实际的答案是事件。
那很有趣,但仍然缺少一些片段。 如果用户需要在每个时期之后运行`evaluator`,或者如果用户需要训练将模型的精度打印到终端,或者将其绘制到 Visdom,Turing 或 Network 图上,该怎么办? 在前面的设置中,有没有办法让知道验证准确率是什么? 您可以通过覆盖`Engine`的默认记录器来完成大部分操作,该记录器本质上是保存在`trainer_logger`变量中的 Python 记录器,但实际的答案是事件。
#### 活动
......@@ -510,7 +510,7 @@ Ignite 打开了一种通过事件或触发器与循环进行交互的特殊方
* `ITERATION_COMPLETED`
* `EXCEPTION_RAISED`
在这些事件上设置函数触发器的最佳和推荐方法是使用 Python 装饰器。 训练`on`方法接受这些事件之一作为参数,并返回一个装饰器,该装饰器设置要在该事件上触发的自定义函数。 这里给出了一些常见事件和用例:
在这些事件上设置函数触发器的最佳和推荐方法是使用 Python 装饰器。 训练`on`方法接受这些事件之一作为参数,并返回一个装饰器,该装饰器设置要在该事件上触发的自定义函数。 这里给出了一些常见事件和用例:
```py
@trainer.on(Events.ITERATION_COMPLETED)
......
......@@ -43,7 +43,7 @@ DDP 材料如下:
1. [DDP 注释](https://pytorch.org/docs/stable/notes/ddp.html)提供了一个入门示例,并简要介绍了其设计和实现。 如果这是您第一次使用 DDP,请从本文档开始。
2. [分布式数据并行入门](../intermediate/ddp_tutorial.html)解释了 DDP 训练的一些常见问题,包括不平衡的工作量,检查点和多设备模型。 请注意,DDP 可以轻松与[单机模型并行最佳实践](../intermediate/model_parallel_tutorial.html)教程中描述的单机多设备模型并行性结合。
3. [启动和配置分布式数据并行应用程序](https://github.com/pytorch/examples/blob/master/distributed/ddp/README.md)文档显示了如何使用 DDP 启动脚本。
4. [带有 Amazon AWS 的 PyTorch 分布式训练](aws_distributed_training_tutorial.html)演示了如何在 AWS 上使用 DDP。
4. [带有 Amazon AWS 的 PyTorch 分布式训练](aws_distributed_training_tutorial.html)演示了如何在 AWS 上使用 DDP。
### TorchElastic
......
......@@ -4,15 +4,15 @@
**作者**[Shen Li](https://mrshenli.github.io/)
**编辑**[朱 Joe](https://github.com/gunandrose4u)
**编辑**[Joe Zhu](https://github.com/gunandrose4u)
先决条件:
* [PyTorch 分布式概述](../beginner/dist_overview.html)
* [DistributedDataParallel API 文档](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html)
* [DistributedDataParallel 注意事项](https://pytorch.org/docs/master/notes/ddp.html)
* [`DistributedDataParallel` API 文档](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html)
* [`DistributedDataParallel`注意事项](https://pytorch.org/docs/master/notes/ddp.html)
[DistributedDataParallel](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel) (DDP)在模块级别实现可在多台计算机上运行的数据并行性。 使用 DDP 的应用程序应产生多个进程,并为每个进程创建一个 DDP 实例。 DDP 在[火炬。分布式](https://pytorch.org/tutorials/intermediate/dist_tuto.html)程序包中使用集体通信来同步梯度和缓冲区。 更具体地说,DDP 为`model.parameters()`给定的每个参数注册一个 Autograd 挂钩,当在后向传递中计算相应的梯度时,挂钩将触发。 然后,DDP 使用该信号触发跨进程的梯度同步。 有关更多详细信息,请参考 [DDP 设计说明](https://pytorch.org/docs/master/notes/ddp.html)
[`DistributedDataParallel`](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel)(DDP)在模块级别实现可在多台计算机上运行的数据并行性。 使用 DDP 的应用程序应产生多个进程,并为每个进程创建一个 DDP 实例。 DDP 在[火炬。分布式](https://pytorch.org/tutorials/intermediate/dist_tuto.html)程序包中使用集体通信来同步梯度和缓冲区。 更具体地说,DDP 为`model.parameters()`给定的每个参数注册一个 Autograd 挂钩,当在后向传递中计算相应的梯度时,挂钩将触发。 然后,DDP 使用该信号触发跨进程的梯度同步。 有关更多详细信息,请参考 [DDP 设计说明](https://pytorch.org/docs/master/notes/ddp.html)
推荐的使用 DDP 的方法是为每个模型副本生成一个进程,其中一个模型副本可以跨越多个设备。 DDP 进程可以放在同一台计算机上,也可以在多台计算机上,但是 GPU 设备不能在多个进程之间共享。 本教程从一个基本的 DDP 用例开始,然后演示了更高级的用例,包括检查点模型以及将 DDP 与模型并行结合。
......
......@@ -12,7 +12,7 @@
## 设置
PyTorch 中包含的分布式软件包(即`torch.distributed`)使研究人员和从业人员可以轻松地并行化他们在跨进程和机器集群的计算。 为此,它利用了传递消息的语义,从而允许每个进程将数据传递给任何其他进程。 与多处理(HTG1)包相反,进程可以使用不同的通信后端,而不仅限于在同一台计算机上执行。
PyTorch 中包含的分布式软件包(即`torch.distributed`)使研究人员和从业人员可以轻松地并行化他们在跨进程和机器集群的计算。 为此,它利用了传递消息的语义,从而允许每个进程将数据传递给任何其他进程。 与多处理包相反,进程可以使用不同的通信后端,而不仅限于在同一台计算机上执行。
为了开始,我们需要同时运行多个进程的能力。 如果您有权访问计算群集,则应咨询本地系统管理员或使用您喜欢的协调工具。 (例如 [pdsh](https://linux.die.net/man/1/pdsh)[clustershell](https://cea-hpc.github.io/clustershell/)[其他](https://slurm.schedmd.com/))。出于本教程的目的,我们将使用以下模板使用一台计算机并分叉多个进程。
......@@ -144,7 +144,7 @@ def run(rank, size):
* `dist.broadcast(tensor, src, group)`:将`tensor``src`复制到所有其他进程。
* `dist.reduce(tensor, dst, op, group)`:将`op`应用于所有`tensor`,并将结果存储在`dst`中。
* `dist.all_reduce(tensor, op, group)`:与 reduce 相同,但是结果存储在所有进程中。
* `dist.all_reduce(tensor, op, group)`:与`reduce`相同,但是结果存储在所有进程中。
* `dist.scatter(tensor, src, scatter_list, group)`:将第`i`个张量`scatter_list[i]`复制到第`i`个过程。
* `dist.gather(tensor, dst, gather_list, group)`:从`dst`中的所有进程复制`tensor`
* `dist.all_gather(tensor_list, tensor, group)`:将所有进程中的`tensor`从所有进程复制到`tensor_list`
......@@ -216,7 +216,7 @@ def partition_dataset():
```
假设我们有 2 个副本,则每个进程的`train_set` 60000/2 = 30000 个样本。 我们还将批量大小除以副本数,以使*整个*批量大小保持为 128。
假设我们有 2 个副本,则每个进程的`train_set``60000/2 = 30000`个样本。 我们还将批量大小除以副本数,以使*整个*批量大小保持为 128。
现在,我们可以编写我们通常的前向后优化训练代码,并添加一个函数调用来平均模型的梯度。 (以下内容主要是受 [PyTorch MNIST 官方示例](https://github.com/pytorch/examples/blob/master/mnist/main.py)的启发)。
......
......@@ -9,7 +9,7 @@
* [PyTorch 分布式概述](../beginner/dist_overview.html)
* [RPC API 文档](https://pytorch.org/docs/master/rpc.html)
本教程使用两个简单的示例来演示如何使用 [torch.distributed.rpc](https://pytorch.org/docs/master/rpc.html) 包构建分布式训练,该包首先在 PyTorch v1.4 中作为原型功能引入。 这两个示例的源代码可以在 [PyTorch 示例](https://github.com/pytorch/examples)中找到。
本教程使用两个简单的示例来演示如何使用[`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)包构建分布式训练,该包首先在 PyTorch v1.4 中作为原型功能引入。 这两个示例的源代码可以在 [PyTorch 示例](https://github.com/pytorch/examples)中找到。
先前的教程[分布式数据并行入门](ddp_tutorial.html)[使用 PyTorch](dist_tuto.html) 编写分布式应用程序,描述了 [DistributedDataParallel](https://pytorch.org/docs/stable/_modules/torch/nn/parallel/distributed.html) ,该模型支持特定的训练范例,该模型可在多个过程之间复制模型 每个进程都处理输入数据的拆分。 有时,您可能会遇到需要不同训练范例的场景。 例如:
......@@ -46,7 +46,7 @@ class Policy(nn.Module):
```
首先,让我们准备一个帮助程序,以在`RRef`的所有者工作程序上远程运行功能。 您将在本教程的示例中的多个地方发现该功能。 理想情况下, torch.distributed.rpc 软件包应立即提供这些帮助程序功能。 例如,如果应用程序可以直接调用`RRef.some_func(*arg)`,然后将其转换为`RRef`所有者的 RPC,将会更容易。 在 [pytorch / pytorch#31743](https://github.com/pytorch/pytorch/issues/31743) 中跟踪了此 API 的进度。
首先,让我们准备一个帮助程序,以在`RRef`的所有者工作程序上远程运行功能。 您将在本教程的示例中的多个地方发现该功能。 理想情况下,`torch.distributed.rpc`软件包应立即提供这些帮助程序功能。 例如,如果应用程序可以直接调用`RRef.some_func(*arg)`,然后将其转换为`RRef`所有者的 RPC,将会更容易。 在 [pytorch / pytorch#31743](https://github.com/pytorch/pytorch/issues/31743) 中跟踪了此 API 的进度。
```py
from torch.distributed.rpc import rpc_sync
......@@ -263,7 +263,7 @@ mp.spawn(
```
以下是使用 world_size = 2 进行训练时的一些示例输出。
以下是使用`world_size = 2`进行训练时的一些示例输出。
```py
Episode 10 Last reward: 26.00 Average reward: 10.01
......@@ -299,11 +299,11 @@ Solved! Running reward is now 475.3163778435275!
```
在此示例中,我们展示了如何使用 RPC 作为通信工具来跨工作人员传递数据,以及如何使用 RRef 引用远程对象。 的确,您可以直接在`ProcessGroup` `send``recv` API 之上构建整个结构,也可以使用其他通信/ RPC 库。 但是,通过使用 torch.distributed.rpc ,您可以在后台获得本机支持并不断优化性能。
在此示例中,我们展示了如何使用 RPC 作为通信工具来跨工作人员传递数据,以及如何使用 RRef 引用远程对象。 的确,您可以直接在`ProcessGroup` `send``recv` API 之上构建整个结构,也可以使用其他通信/ RPC 库。 但是,通过使用`torch.distributed.rpc`,您可以在后台获得本机支持并不断优化性能。
接下来,我们将展示如何将 RPC 和 RRef 与分布式 Autograd 和分布式优化器结合起来执行分布式模型并行训练。
## 使用 Distributed Autograd 和 Distributed Optimizer 的分布式 RNN
## 使用分布式 Autograd 和分布式优化器的分布式 RNN
在本节中,我们将使用 RNN 模型来展示如何使用 RPC API 构建分布式模型并行训练。 示例 RNN 模型非常小,可以轻松地放入单个 GPU 中,但是我们仍将其层划分为两个不同的工人来演示这一想法。 开发人员可以应用类似的技术在多个设备和机器上分布更大的模型。
......@@ -336,7 +336,7 @@ class Decoder(nn.Module):
```
使用上述子模块,我们现在可以使用 RPC 将它们组合在一起以创建 RNN 模型。 在下面的代码中,`ps`代表参数服务器,该服务器托管嵌入表和解码器的参数。 构造函数使用[远程](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.remote) API 在参数服务器上创建`EmbeddingTable`对象和`Decoder`对象,并在本地创建`LSTM`子模块。 在前进过程中,训练使用`EmbeddingTable` `RRef`查找远程子模块,然后使用 RPC 将输入数据传递到`EmbeddingTable`,并获取查找结果。 然后,它通过本地`LSTM`层运行嵌入,最后使用另一个 RPC 将输出发送到`Decoder`子模块。 通常,要实施分布式模型并行训练,开发人员可以将模型分为多个子模块,调用 RPC 远程创建子模块实例,并在必要时使用`RRef`查找它们。 正如您在下面的代码中看到的那样,它看起来与单机模型并行训练非常相似。 主要区别是用 RPC 功能替换了`Tensor.to(device)`
使用上述子模块,我们现在可以使用 RPC 将它们组合在一起以创建 RNN 模型。 在下面的代码中,`ps`代表参数服务器,该服务器托管嵌入表和解码器的参数。 构造函数使用[远程](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.remote) API 在参数服务器上创建`EmbeddingTable`对象和`Decoder`对象,并在本地创建`LSTM`子模块。 在前进过程中,训练使用`EmbeddingTable` `RRef`查找远程子模块,然后使用 RPC 将输入数据传递到`EmbeddingTable`,并获取查找结果。 然后,它通过本地`LSTM`层运行嵌入,最后使用另一个 RPC 将输出发送到`Decoder`子模块。 通常,要实施分布式模型并行训练,开发人员可以将模型分为多个子模块,调用 RPC 远程创建子模块实例,并在必要时使用`RRef`查找它们。 正如您在下面的代码中看到的那样,它看起来与单机模型并行训练非常相似。 主要区别是用 RPC 功能替换了`Tensor.to(device)`
```py
class RNNModel(nn.Module):
......@@ -443,7 +443,7 @@ def run_trainer():
```
最后,让我们添加一些粘合代码以启动参数服务器和训练流程。
最后,让我们添加一些粘合代码以启动参数服务器和训练流程。
```py
def run_worker(rank, world_size):
......
......@@ -9,13 +9,13 @@
* [PyTorch 分布式概述](../beginner/dist_overview.html)
* [RPC API 文档](https://pytorch.org/docs/master/rpc.html)
本教程介绍了一个简单的示例,该示例使用 PyTorch 的[分布式 RPC 框架](https://pytorch.org/docs/stable/rpc.html)实现参数服务器。 参数服务器框架是一种范例,其中一组服务器存储参数(例如大型嵌入表),并且多个训练人员查询参数服务器以检索最新参数。 这些训练可以在本地运行训练循环,并偶尔与参数服务器同步以获得最新参数。 有关参数服务器方法的更多信息,请查阅[本文](https://www.cs.cmu.edu/~muli/file/parameter_server_osdi14.pdf)
本教程介绍了一个简单的示例,该示例使用 PyTorch 的[分布式 RPC 框架](https://pytorch.org/docs/stable/rpc.html)实现参数服务器。 参数服务器框架是一种范例,其中一组服务器存储参数(例如大型嵌入表),并且多个训练人员查询参数服务器以检索最新参数。 这些训练可以在本地运行训练循环,并偶尔与参数服务器同步以获得最新参数。 有关参数服务器方法的更多信息,请查阅[本文](https://www.cs.cmu.edu/~muli/file/parameter_server_osdi14.pdf)
使用分布式 RPC 框架,我们将构建一个示例,其中多个训练师使用 RPC 与同一个参数服务器进行通信,并使用 [RRef](https://pytorch.org/docs/stable/rpc.html#torch.distributed.rpc.RRef) 访问远程参数服务器实例上的状态。 每位训练师将通过使用分布式 Autograd 跨多个节点拼接 Autograd 图,以分布式方式启动其专用的反向传递。
使用分布式 RPC 框架,我们将构建一个示例,其中多个训练器使用 RPC 与同一个参数服务器进行通信,并使用 [RRef](https://pytorch.org/docs/stable/rpc.html#torch.distributed.rpc.RRef) 访问远程参数服务器实例上的状态。 每位训练器将通过使用分布式 Autograd 跨多个节点拼接 Autograd 图,以分布式方式启动其专用的反向传递。
**注意**:本教程介绍了分布式 RPC 框架的用法,该方法可用于将模型拆分到多台计算机上,或用于实现参数服务器训练策略,在该策略中,网络训练可以获取托管在另一台计算机上的参数。 相反,如果您要跨多个 GPU 复制模型,请参阅[分布式数据并行教程](https://pytorch.org/tutorials/intermediate/ddp_tutorial.html)。 还有另一个 [RPC 教程](https://pytorch.org/tutorials/intermediate/rpc_tutorial.html),涵盖了强化学习和 RNN 用例。
**注意**:本教程介绍了分布式 RPC 框架的用法,该方法可用于将模型拆分到多台计算机上,或用于实现参数服务器训练策略,在该策略中,网络训练可以获取托管在另一台计算机上的参数。 相反,如果您要跨多个 GPU 复制模型,请参阅[分布式数据并行教程](https://pytorch.org/tutorials/intermediate/ddp_tutorial.html)。 还有另一个 [RPC 教程](https://pytorch.org/tutorials/intermediate/rpc_tutorial.html),涵盖了强化学习和 RNN 用例。
让我们从熟悉的地方开始:导入我们所需的模块并定义一个简单的 ConvNet,它将在 MNIST 数据集上进行训练。 以下网络是从 [pytorch / examples 仓库](https://github.com/pytorch/examples/tree/master/mnist)中定义的网络中广泛采用的。
让我们从熟悉的地方开始:导入我们所需的模块并定义一个简单的 ConvNet,它将在 MNIST 数据集上进行训练。 以下网络是从[`pytorch/examples`仓库](https://github.com/pytorch/examples/tree/master/mnist)中定义的网络中广泛采用的。
```py
import argparse
......@@ -117,7 +117,7 @@ class ParameterServer(nn.Module):
```
接下来,我们将定义前进通道。 请注意,无论模型输出的设备如何,我们都会将输出移至 CPU,因为分布式 RPC 框架当前仅支持通过 RPC 发送 CPU 张量。 由于有可能在调用者/被调用者上使用不同的设备(CPU / GPU),因此我们有意禁用通过 RPC 发送 CUDA 张量,但在将来的版本中可能会支持此功能。
接下来,我们将定义前进通道。 请注意,无论模型输出的设备如何,我们都会将输出移至 CPU,因为分布式 RPC 框架当前仅支持通过 RPC 发送 CPU 张量。 由于有可能在调用者/被调用者上使用不同的设备(CPU/GPU),因此我们有意禁用通过 RPC 发送 CUDA 张量,但在将来的版本中可能会支持此功能。
```py
class ParameterServer(nn.Module):
......@@ -132,7 +132,7 @@ class ParameterServer(nn.Module):
```
接下来,我们将定义一些其他功能,可用于训练和验证。 第一个`get_dist_gradients`将采用 Distributed Autograd 上下文 ID,并调用`dist_autograd.get_gradients` API,以检索由分布式 Autograd 计算的梯度。 可以在[分布式 Autograd 文档](https://pytorch.org/docs/stable/rpc.html#distributed-autograd-framework)中找到更多信息。 请注意,由于该框架当前仅支持通过 RPC 发送张量,因此我们还会迭代生成的字典并将每个张量转换为 CPU 张量。 接下来,`get_param_rrefs`将迭代我们的模型参数,并将它们包装为(本地) [RRef](https://pytorch.org/docs/stable/rpc.html#torch.distributed.rpc.RRef) 。 训练者节点将通过 RPC 调用此方法,并将返回要优化的参数列表。 这是[分布式优化器](https://pytorch.org/docs/stable/rpc.html#module-torch.distributed.optim)的输入,它需要所有必须优化的参数作为`RRef`的列表。
接下来,我们将定义一些其他功能,可用于训练和验证。 第一个`get_dist_gradients`将采用分布式 Autograd 上下文 ID,并调用`dist_autograd.get_gradients` API,以检索由分布式 Autograd 计算的梯度。 可以在[分布式 Autograd 文档](https://pytorch.org/docs/stable/rpc.html#distributed-autograd-framework)中找到更多信息。 请注意,由于该框架当前仅支持通过 RPC 发送张量,因此我们还会迭代生成的字典并将每个张量转换为 CPU 张量。 接下来,`get_param_rrefs`将迭代我们的模型参数,并将它们包装为(本地) [RRef](https://pytorch.org/docs/stable/rpc.html#torch.distributed.rpc.RRef) 。 训练者节点将通过 RPC 调用此方法,并将返回要优化的参数列表。 这是[分布式优化器](https://pytorch.org/docs/stable/rpc.html#module-torch.distributed.optim)的输入,它需要所有必须优化的参数作为`RRef`的列表。
```py
# Use dist autograd to retrieve gradients accumulated for this model.
......@@ -155,7 +155,7 @@ def get_param_rrefs(self):
```
最后,我们将创建用于初始化参数服务器的方法。 请注意,所有过程中只有一个参数服务器实例,并且所有训练都将与同一参数服务器对话并更新相同的存储模型。 如`run_parameter_server`所示,服务器本身不采取任何独立的操作; 它等待来自训练者的请求(尚未定义),并通过运行所请求的功能对其作出响应。
最后,我们将创建用于初始化参数服务器的方法。 请注意,所有过程中只有一个参数服务器实例,并且所有训练都将与同一参数服务器对话并更新相同的存储模型。 如`run_parameter_server`所示,服务器本身不采取任何独立的操作; 它等待来自训练者的请求(尚未定义),并通过运行所请求的功能对其作出响应。
```py
# The global parameter server instance.
......@@ -233,7 +233,7 @@ class TrainerNet(nn.Module):
```
完全定义好训练之后,现在该编写我们的神经网络训练循环,该循环将创建我们的网络和优化器,通过网络运行一些输入并计算损失。 训练循环看起来很像本地训练计划,但由于我们的网络在机器之间分布,因此进行了一些修改。
完全定义好训练之后,现在该编写我们的神经网络训练循环,该循环将创建我们的网络和优化器,通过网络运行一些输入并计算损失。 训练循环看起来很像本地训练计划,但由于我们的网络在机器之间分布,因此进行了一些修改。
下面,我们初始化`TrainerNet`并构建一个`DistributedOptimizer`。 请注意,如上所述,我们必须传入要优化的所有全局参数(跨参与分布式训练的所有节点)。 另外,我们传入要使用的本地优化器,在这种情况下为 SGD。 请注意,我们可以像创建本地优化器一样配置基础优化器算法-`optimizer.SGD`的所有参数都将正确转发。 例如,我们传入一个自定义学习率,它将用作所有本地优化器的学习率。
......@@ -250,7 +250,7 @@ def run_training_loop(rank, num_gpus, train_loader, test_loader):
接下来,我们定义我们的主要训练循环。 我们遍历了 PyTorch 的 [DataLoader](https://pytorch.org/docs/stable/data.html) 提供的可迭代项。 在编写典型的前向/后向/优化器循环之前,我们首先将逻辑包装在[分布式 Autograd 上下文](https://pytorch.org/docs/stable/rpc.html#torch.distributed.autograd.context)中。 请注意,这需要记录在模型的前向传递中调用的 RPC,以便可以构造一个适当的图,其中包括在后向传递中所有参与的分布式工作者。 分布式 Autograd 上下文返回`context_id`,它用作用于累积和优化与特定迭代对应的梯度的标识符。
与调用典型的`loss.backward()`会启动此本地工作程序的向后传递相反,我们调用`dist_autograd.backward()`并传递我们的 context_id `loss`,这是我们希望向后传递的根 开始。 另外,我们将此`context_id`传递到优化程序调用中,该调用程序必须能够在所有节点上查找由该特定向后传递计算出的相应梯度。
与调用典型的`loss.backward()`会启动此本地工作程序的向后传递相反,我们调用`dist_autograd.backward()`并传递我们的`context_id``loss`,这是我们希望向后传递的根 开始。 另外,我们将此`context_id`传递到优化程序调用中,该调用程序必须能够在所有节点上查找由该特定向后传递计算出的相应梯度。
```py
def run_training_loop(rank, num_gpus, train_loader, test_loader):
......@@ -298,7 +298,7 @@ def get_accuracy(test_loader, model):
```
接下来,类似于我们将`run_parameter_server`定义为负责初始化 RPC 的`ParameterServer`的主循环的方式,让我们为训练者定义一个类似的循环。 所不同的是,我们的训练必须执行上面定义的训练循环:
接下来,类似于我们将`run_parameter_server`定义为负责初始化 RPC 的`ParameterServer`的主循环的方式,让我们为训练者定义一个类似的循环。 所不同的是,我们的训练必须执行上面定义的训练循环:
```py
# Main loop for trainers.
......@@ -316,9 +316,9 @@ def run_worker(rank, world_size, num_gpus, train_loader, test_loader):
```
请注意,类似于`run_parameter_server``rpc.shutdown()`默认情况下将等待该节点退出之前,所有训练器和 ParameterServer 的所有工作人员都调用`rpc.shutdown()`。 这样可确保节点正常终止,并且没有一个节点脱机,而另一个节点则期望其联机。
请注意,类似于`run_parameter_server``rpc.shutdown()`默认情况下将等待该节点退出之前,所有训练器和`ParameterServer`的所有工作人员都调用`rpc.shutdown()`。 这样可确保节点正常终止,并且没有一个节点脱机,而另一个节点则期望其联机。
现在,我们已经完成了特定于训练器和参数服务器的代码,剩下的就是添加代码以启动训练器和参数服务器。 首先,我们必须接受适用于我们的参数服务器和训练的各种参数。 `world_size`对应于将参加训练的节点总数,并且是所有训练器和参数服务器的总和。 我们还必须为每个单独的进程传递唯一的`rank`,从 0(将在其中运行单个参数服务器的地方)到`world_size - 1``master_addr``master_port`是可用于标识等级 0 进程在何处运行的参数,并且各个节点将使用它们来相互发现。 要在本地测试此示例,只需将`localhost`和相同的`master_port`传递给所有产生的实例。 请注意,出于演示目的,此示例仅支持 0-2 个 GPU,尽管可以扩展该模式以使用其他 GPU。
现在,我们已经完成了特定于训练器和参数服务器的代码,剩下的就是添加代码以启动训练器和参数服务器。 首先,我们必须接受适用于我们的参数服务器和训练的各种参数。 `world_size`对应于将参加训练的节点总数,并且是所有训练器和参数服务器的总和。 我们还必须为每个单独的进程传递唯一的`rank`,从 0(将在其中运行单个参数服务器的地方)到`world_size - 1``master_addr``master_port`是可用于标识等级 0 进程在何处运行的参数,并且各个节点将使用它们来相互发现。 要在本地测试此示例,只需将`localhost`和相同的`master_port`传递给所有产生的实例。 请注意,出于演示目的,此示例仅支持 0-2 个 GPU,尽管可以扩展该模式以使用其他 GPU。
```py
if __name__ == '__main__':
......@@ -362,7 +362,7 @@ if __name__ == '__main__':
```
现在,我们将根据命令行参数创建一个与参数服务器或训练器相对应的过程。 如果传入的等级为 0,我们将创建一个`ParameterServer`,否则,将创建一个`TrainerNet`。 请注意,我们正在使用`torch.multiprocessing`启动与我们要执行的功能相对应的子进程,并使用`p.join()`从主线程等待该进程完成。 在初始化训练的情况下,我们还使用 PyTorch 的[数据加载器](https://pytorch.org/docs/stable/data.html)来指定 MNIST 数据集上的训练和测试数据加载器。
现在,我们将根据命令行参数创建一个与参数服务器或训练器相对应的过程。 如果传入的等级为 0,我们将创建一个`ParameterServer`,否则,将创建一个`TrainerNet`。 请注意,我们正在使用`torch.multiprocessing`启动与我们要执行的功能相对应的子进程,并使用`p.join()`从主线程等待该进程完成。 在初始化训练的情况下,我们还使用 PyTorch 的[数据加载器](https://pytorch.org/docs/stable/data.html)来指定 MNIST 数据集上的训练和测试数据加载器。
```py
processes = []
......@@ -407,6 +407,6 @@ for p in processes:
```
要在本地运行示例,请在单独的终端窗口中为服务器和要生成的每个工作程序运行以下命令工作程序:`python rpc_parameter_server.py --world_size=WORLD_SIZE --rank=RANK`。 例如,对于世界大小为 2 的主节点,命令为`python rpc_parameter_server.py --world_size=2 --rank=0`。 然后可以在单独的窗口中使用命令`python rpc_parameter_server.py --world_size=2 --rank=1`启动训练师,这将开始使用一台服务器和一台训练师进行训练。 请注意,本教程假定使用 0 到 2 个 GPU 进行训练,并且可以通过将`--num_gpus=N`传递到训练脚本中来配置此参数。
要在本地运行示例,请在单独的终端窗口中为服务器和要生成的每个工作程序运行以下命令工作程序:`python rpc_parameter_server.py --world_size=WORLD_SIZE --rank=RANK`。 例如,对于世界大小为 2 的主节点,命令为`python rpc_parameter_server.py --world_size=2 --rank=0`。 然后可以在单独的窗口中使用命令`python rpc_parameter_server.py --world_size=2 --rank=1`启动训练器,这将开始使用一台服务器和一台训练器进行训练。 请注意,本教程假定使用 0 到 2 个 GPU 进行训练,并且可以通过将`--num_gpus=N`传递到训练脚本中来配置此参数。
您可以传入命令行参数`--master_addr=ADDRESS``--master_port=PORT`来指示主工作者正在侦听的地址和端口,例如,以测试在其他机器上运行训练者和主节点的功能。
\ No newline at end of file
......@@ -9,9 +9,9 @@
* [PyTorch 分布式概述](../beginner/dist_overview.html)
* [单机模型并行最佳实践](https://pytorch.org/tutorials/intermediate/model_parallel_tutorial.html)
* [分布式 RPC 框架](https://pytorch.org/tutorials/intermediate/rpc_tutorial.html)入门
* RRef 辅助函数: [RRef.rpc_sync()](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.RRef.rpc_sync)[RRef.rpc_async()](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.RRef.rpc_async)[RRef.remote()](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.RRef.remote)
* RRef 辅助函数: [`RRef.rpc_sync()`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.RRef.rpc_sync)[`RRef.rpc_async()`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.RRef.rpc_async)[`RRef.remote()`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.RRef.remote)
本教程使用 Resnet50 模型来演示如何使用 [torch.distributed.rpc](https://pytorch.org/docs/master/rpc.html) API 实现分布式管道并行性。 可以将其视为[单机模型并行最佳实践](model_parallel_tutorial.html)中讨论的多 GPU 管道并行性的分布式对应物。
本教程使用 Resnet50 模型来演示如何使用[`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html) API 实现分布式管道并行性。 可以将其视为[单机模型并行最佳实践](model_parallel_tutorial.html)中讨论的多 GPU 管道并行性的分布式对应物。
注意
......@@ -183,7 +183,7 @@ class DistResNet50(nn.Module):
## 步骤 3:定义训练循环
定义模型后,让我们实施训练循环。 我们使用专门的“主”工作人员来准备随机输入和标签,并控制分布式反向传递和分布式优化器步骤。 它首先创建`DistResNet50`模块的实例。 它指定每个批量的微批数量,并提供两个 RPC 工作程序的名称(即“ worker1”和“ worker2”)。 然后,它定义损失函数,并使用`parameter_rrefs()`帮助器创建`DistributedOptimizer`以获取参数`RRefs`的列表。 然后,主训练循环与常规本地训练非常相似,除了它使用`dist_autograd`向后启动并为反向和优化器`step()`提供`context_id`之外。
定义模型后,让我们实施训练循环。 我们使用专门的“主”工作人员来准备随机输入和标签,并控制分布式反向传递和分布式优化器步骤。 它首先创建`DistResNet50`模块的实例。 它指定每个批量的微批数量,并提供两个 RPC 工作程序的名称(即`worker1``worker2`)。 然后,它定义损失函数,并使用`parameter_rrefs()`帮助器创建`DistributedOptimizer`以获取参数`RRefs`的列表。 然后,主训练循环与常规本地训练非常相似,除了它使用`dist_autograd`向后启动并为反向和优化器`step()`提供`context_id`之外。
```py
import torch.distributed.autograd as dist_autograd
......
......@@ -11,7 +11,7 @@
* [使用分布式 RPC 框架](rpc_param_server_tutorial.html)实施参数服务器
* [RPC 异步执行装饰器](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)
本教程演示了如何使用 [@ rpc.functions.async_execution](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) 装饰器来构建批量 RPC 应用程序,该装饰器通过减少阻止的 RPC 线程数和合并被调用方上的 CUDA 操作来帮助加快训练速度。 这与与 TorchServer 进行[批量推断具有相同的想法。](https://pytorch.org/serve/batch_inference_with_ts.html)
本教程演示了如何使用[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器来构建批量 RPC 应用程序,该装饰器通过减少阻止的 RPC 线程数和合并被调用方上的 CUDA 操作来帮助加快训练速度。 这与与 TorchServer 进行[批量推断具有相同的想法。](https://pytorch.org/serve/batch_inference_with_ts.html)
注意
......@@ -26,13 +26,13 @@
* [torch.futures.Future](https://pytorch.org/docs/master/futures.html) 类型封装了异步执行,还支持安装回调函数。
* 一个 [@ rpc.functions.async_execution](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) 装饰器,允许应用程序告诉被调用方目标函数将返回将来的函数,并且在执行期间可以暂停并产生多次。
使用这两个工具,应用程序代码可以将用户功能分解为多个较小的功能,将它们作为`Future`对象上的回调链接在一起,然后返回包含最终结果的`Future`。 在被调用方,当获取`Future`对象时,它还将安装后续的 RPC 响应准备和通讯作为回调,这将在最终结果准备好时触发。 这样,被调用者不再需要阻塞一个线程并等待直到最终返回值准备就绪。 有关简单示例,请参考 [@ rpc.functions.async_execution](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) 的 API 文档。
使用这两个工具,应用程序代码可以将用户功能分解为多个较小的功能,将它们作为`Future`对象上的回调链接在一起,然后返回包含最终结果的`Future`。 在被调用方,当获取`Future`对象时,它还将安装后续的 RPC 响应准备和通讯作为回调,这将在最终结果准备好时触发。 这样,被调用者不再需要阻塞一个线程并等待直到最终返回值准备就绪。 有关简单示例,请参考[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) 的 API 文档。
除了减少被调用方上的空闲线程数之外,这些工具还有助于使批量 RPC 处理更容易,更快捷。 本教程的以下两节演示了如何使用 [@ rpc.functions.async_execution](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) 装饰器来构建分布式批更新参数服务器和批量强化学习应用程序。
## 批量更新参数服务器
考虑具有一个参数服务器(PS)和多个训练师的同步参数服务器训练应用程序。 在此应用程序中,PS 保留参数并等待所有训练师报告坡度。 在每次迭代中,它都会等到收到所有训练者的梯度后,再一次更新所有参数。 下面的代码显示 PS 类的实现。 `update_and_fetch_model`方法是用`@rpc.functions.async_execution`装饰的,将由训练师调用。 每次调用都会返回一个`Future`对象,该对象将填充有更新的模型。 大多数训练师发起的调用仅将梯度累积到`.grad`字段,立即返回,并在 PS 上产生 RPC 线程。 最后到达的训练师将触发优化器步骤,并消耗所有先前报告的梯度。 然后,它使用更新的模型设置`future_model`,该模型又通过`Future`对象通知其他训练师的所有先前请求,并将更新后的模型发送给所有训练师
考虑具有一个参数服务器(PS)和多个训练器的同步参数服务器训练应用程序。 在此应用程序中,PS 保留参数并等待所有训练器报告坡度。 在每次迭代中,它都会等到收到所有训练者的梯度后,再一次更新所有参数。 下面的代码显示 PS 类的实现。 `update_and_fetch_model`方法是用`@rpc.functions.async_execution`装饰的,将由训练器调用。 每次调用都会返回一个`Future`对象,该对象将填充有更新的模型。 大多数训练器发起的调用仅将梯度累积到`.grad`字段,立即返回,并在 PS 上产生 RPC 线程。 最后到达的训练器将触发优化器步骤,并消耗所有先前报告的梯度。 然后,它使用更新的模型设置`future_model`,该模型又通过`Future`对象通知其他训练器的所有先前请求,并将更新后的模型发送给所有训练器
```py
import threading
......@@ -90,7 +90,7 @@ class BatchUpdateParameterServer(object):
```
对于训练师,它们都使用来自 PS 的相同参数集进行初始化。 在每次迭代中,每位训练师首先进行前进和后退操作,以局部生成梯度。 然后,每个训练师都使用 RPC 向 PS 报告其梯度,并通过同一 RPC 请求的返回值取回更新的参数。 在训练师的实施中,目标功能是否标记有`@rpc.functions.async_execution`都没有关系。 训练师只需使用`rpc_sync`调用`update_and_fetch_model`,这会阻塞训练师,直到返回更新的模型。
对于训练器,它们都使用来自 PS 的相同参数集进行初始化。 在每次迭代中,每位训练器首先进行前进和后退操作,以局部生成梯度。 然后,每个训练器都使用 RPC 向 PS 报告其梯度,并通过同一 RPC 请求的返回值取回更新的参数。 在训练器的实施中,目标功能是否标记有`@rpc.functions.async_execution`都没有关系。 训练器只需使用`rpc_sync`调用`update_and_fetch_model`,这会阻塞训练器,直到返回更新的模型。
```py
batch_size, image_w, image_h = 20, 64, 64
......
# 将分布式 DataParallel 与分布式 RPC 框架相结合
# 将分布式`DataParallel`与分布式 RPC 框架相结合
> 原文:<https://pytorch.org/tutorials/advanced/rpc_ddp_tutorial.html>
**作者**[Pritam Damania](https://github.com/pritamdamania87)
本教程使用一个简单的示例演示如何将 [DistributedDataParallel](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel) (DDP)与 [Distributed RPC Framework](https://pytorch.org/docs/master/rpc.html) 结合使用,以将分布式数据并行性与分布式模型并行性结合在一起,以训练简单模型。 该示例的源代码可以在中找到[](https://github.com/pytorch/examples/tree/master/distributed/rpc/ddp_rpc)
本教程使用一个简单的示例演示如何将[`DistributedDataParallel`](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel)(DDP)与[分布式 RPC 框架](https://pytorch.org/docs/master/rpc.html)结合使用,以将分布式数据并行性与分布式模型并行性结合在一起,以训练简单模型。 该示例的源代码可以在中找到[](https://github.com/pytorch/examples/tree/master/distributed/rpc/ddp_rpc)
先前的教程[分布式数据并行入门](https://pytorch.org/tutorials/intermediate/ddp_tutorial.html)[分布式 RPC 框架入门](https://pytorch.org/tutorials/intermediate/rpc_tutorial.html)分别描述了如何执行分布式数据并行训练和分布式模型并行训练。 虽然,有几种训练范例,您可能想将这两种技术结合起来。 例如:
1. 如果我们的模型具有稀疏部分(较大的嵌入表)和密集部分(FC 层),则可能需要将嵌入表放在参数服务器上,并使用 [DistributedDataParallel](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel) [分布式 RPC 框架](https://pytorch.org/docs/master/rpc.html)可用于在参数服务器上执行嵌入查找。
2.[PipeDream](https://arxiv.org/abs/1806.03377) 论文中所述,启用混合并行性。 我们可以使用[分布式 RPC 框架](https://pytorch.org/docs/master/rpc.html)在多个工作程序之间流水线化模型的各个阶段,并使用 [DistributedDataParallel](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel) 复制每个阶段(如果需要)。
1. 如果我们的模型具有稀疏部分(较大的嵌入表)和密集部分(FC 层),则可能需要将嵌入表放在参数服务器上,并使用[`DistributedDataParallel`](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel)[分布式 RPC 框架](https://pytorch.org/docs/master/rpc.html)可用于在参数服务器上执行嵌入查找。
2.[PipeDream](https://arxiv.org/abs/1806.03377) 论文中所述,启用混合并行性。 我们可以使用[分布式 RPC 框架](https://pytorch.org/docs/master/rpc.html)在多个工作程序之间流水线化模型的各个阶段,并使用[`DistributedDataParallel`](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel)复制每个阶段(如果需要)。
在本教程中,我们将介绍上述情况 1。 我们的设置中共有 4 个工人,如下所示:
1. 1 个 Master,负责在参数服务器上创建嵌入表(nn.EmbeddingBag)。 主人还会在两个教练上驱动训练循环。
1. 1 个主机,负责在参数服务器上创建嵌入表(`nn.EmbeddingBag`)。 主人还会在两个教练上驱动训练循环。
2. 1 参数服务器,它基本上将嵌入表保存在内存中,并响应来自主服务器和训练器的 RPC。
3. 2 个训练,用于存储 FC 层(线性线性),并使用 [DistributedDataParallel](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel) 在它们之间进行复制。 训练人员还负责执行前进,后退和优化器步骤。
3. 2 个训练,用于存储 FC 层(线性线性),并使用 [DistributedDataParallel](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel) 在它们之间进行复制。 训练人员还负责执行前进,后退和优化器步骤。
整个训练过程执行如下:
1. 主服务器在参数服务器上创建一个嵌入表,并为其保留一个 [RRef](https://pytorch.org/docs/master/rpc.html#rref)
2. 然后,主持人开始在训练师上进行训练循环,并将嵌入表 RRef 传递给训练师
3. 训练创建一个`HybridModel`,该`HybridModel`首先使用主机提供的嵌入表 RRef 执行嵌入查找,然后执行包装在 DDP 中的 FC 层。
2. 然后,主持人开始在训练器上进行训练循环,并将嵌入表 RRef 传递给训练器
3. 训练创建一个`HybridModel`,该`HybridModel`首先使用主机提供的嵌入表 RRef 执行嵌入查找,然后执行包装在 DDP 中的 FC 层。
4. 训练者执行模型的正向传递,并使用 [Distributed Autograd](https://pytorch.org/docs/master/rpc.html#distributed-autograd-framework) 使用损失执行反向传递。
5. 作为向后遍历的一部分,将首先计算 FC 层的梯度,并通过 DDP 中的 allreduce 将其同步到所有训练器。
6. 接下来,Distributed Autograd 将梯度传播到参数服务器,在该服务器中更新嵌入表的梯度。
5. 作为向后遍历的一部分,将首先计算 FC 层的梯度,并通过 DDP 中的`allreduce`将其同步到所有训练器。
6. 接下来,分布式 Autograd 将梯度传播到参数服务器,在该服务器中更新嵌入表的梯度。
7. 最后,[分布式优化器](https://pytorch.org/docs/master/rpc.html#module-torch.distributed.optim)用于更新所有参数。
注意
如果您将 DDP 和 RPC 结合使用,则应始终使用[分布式 Autograd](https://pytorch.org/docs/master/rpc.html#distributed-autograd-framework) 进行向后传递。
现在,让我们详细介绍每个部分。 首先,我们需要先设置所有工人,然后才能进行任何训练。 我们创建 4 个过程,使等级 0 和 1 是我们的训练,等级 2 是主控制器,等级 3 是参数服务器。
现在,让我们详细介绍每个部分。 首先,我们需要先设置所有工人,然后才能进行任何训练。 我们创建 4 个过程,使等级 0 和 1 是我们的训练,等级 2 是主控制器,等级 3 是参数服务器。
我们使用 TCP init_method 在所有 4 个工作器上初始化 RPC 框架。 RPC 初始化完成后,主服务器使用 [rpc.remote](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.remote) 在参数服务器上创建 [EmbeddingBag](https://pytorch.org/docs/master/generated/torch.nn.EmbeddingBag.html) 。 然后,主控制器通过使用 [rpc_async](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.rpc_async) 在每个教练上调用`_run_trainer`,循环遍历每个教练并开始训练循环。 最后,主人在退出之前等待所有训练结束。
训练师首先使用 [init_process_group](https://pytorch.org/docs/stable/distributed.html#torch.distributed.init_process_group) 为 world_size = 2 的 DDP 初始化`ProcessGroup`(对于两个训练师)。 接下来,他们使用 TCP init_method 初始化 RPC 框架。 请注意,RPC 初始化和 ProcessGroup 初始化中的端口不同。 这是为了避免两个框架的初始化之间的端口冲突。 初始化完成后,训练师只需等待主服务器的`_run_trainer` RPC。
训练器首先使用 [init_process_group](https://pytorch.org/docs/stable/distributed.html#torch.distributed.init_process_group)`world_size = 2`的 DDP 初始化`ProcessGroup`(对于两个训练器)。 接下来,他们使用 TCP `init_method`初始化 RPC 框架。 请注意,RPC 初始化和`ProcessGroup`初始化中的端口不同。 这是为了避免两个框架的初始化之间的端口冲突。 初始化完成后,训练器只需等待主服务器的`_run_trainer` RPC。
参数服务器只是初始化 RPC 框架,并等待来自训练者和主服务器的 RPC。
......@@ -110,7 +110,7 @@ if __name__=="__main__":
```
在讨论训练师的详细信息之前,让我们介绍一下训练师使用的`HybridModel`。 如下所述,使用对参数服务器上嵌入表(emb_rref)的 RRef 和用于 DDP 的`device`初始化`HybridModel`。 模型的初始化在 DDP 中包装了 [nn.Linear](https://pytorch.org/docs/master/generated/torch.nn.Linear.html) 层,以在所有训练器之间复制和同步该层。
在讨论训练器的详细信息之前,让我们介绍一下训练器使用的`HybridModel`。 如下所述,使用对参数服务器上嵌入表(`emb_rref`)的 RRef 和用于 DDP 的`device`初始化`HybridModel`。 模型的初始化在 DDP 中包装了 [nn.Linear](https://pytorch.org/docs/master/generated/torch.nn.Linear.html) 层,以在所有训练器之间复制和同步该层。
该模型的前进方法非常简单。 它使用 [RRef 帮助程序](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.RRef.rpc_sync)在参数服务器上执行嵌入查找,并将其输出传递到 FC 层。
......@@ -140,7 +140,7 @@ class HybridModel(torch.nn.Module):
接下来,让我们看看 Trainer 上的设置。 训练者首先使用对参数服务器上嵌入表的 RRef 及其自身等级创建上述`HybridModel`
现在,我们需要检索要使用 [DistributedOptimizer](https://pytorch.org/docs/master/rpc.html#module-torch.distributed.optim) 优化的所有参数的 RRef 列表。 为了从参数服务器中检索嵌入表的参数,我们定义了一个简单的辅助函数`_retrieve_embedding_parameters`,该函数基本上遍历了嵌入表的所有参数并返回 RRef 的列表。 训练通过 RPC 在参数服务器上调用此方法,以接收所需参数的 RRef 列表。 由于 DistributedOptimizer 始终将需要优化的参数的 RRef 列表,因此我们甚至需要为 FC 层的本地参数创建 RRef。 这是通过遍历`model.parameters()`,为每个参数创建 RRef 并将其附加到列表来完成的。 请注意,`model.parameters()`仅返回本地参数,不包含`emb_rref`
现在,我们需要检索要使用 [DistributedOptimizer](https://pytorch.org/docs/master/rpc.html#module-torch.distributed.optim) 优化的所有参数的 RRef 列表。 为了从参数服务器中检索嵌入表的参数,我们定义了一个简单的辅助函数`_retrieve_embedding_parameters`,该函数基本上遍历了嵌入表的所有参数并返回 RRef 的列表。 训练通过 RPC 在参数服务器上调用此方法,以接收所需参数的 RRef 列表。 由于 DistributedOptimizer 始终将需要优化的参数的 RRef 列表,因此我们甚至需要为 FC 层的本地参数创建 RRef。 这是通过遍历`model.parameters()`,为每个参数创建 RRef 并将其附加到列表来完成的。 请注意,`model.parameters()`仅返回本地参数,不包含`emb_rref`
最后,我们使用所有 RRef 创建我们的 DistributedOptimizer,并定义 CrossEntropyLoss 函数。
......@@ -184,7 +184,7 @@ def _run_trainer(emb_rref, rank):
```
现在,我们准备介绍在每个训练上运行的主要训练循环。 `get_next_batch`只是一个辅助函数,用于生成随机输入和训练目标。 我们针对多个时期和每个批量运行训练循环:
现在,我们准备介绍在每个训练上运行的主要训练循环。 `get_next_batch`只是一个辅助函数,用于生成随机输入和训练目标。 我们针对多个时期和每个批量运行训练循环:
1. 为分布式 Autograd 设置[分布式 Autograd 上下文](https://pytorch.org/docs/master/rpc.html#torch.distributed.autograd.context)
2. 运行模型的正向传递并检索其输出。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册