Files
dgl/docs/source/guide_cn/distributed-preprocessing.rst
Minjie Wang 8a07ab7737 [Doc] Tutorials re-organization (#2683)
* reorg

* change titles

* rm some stale API doc; minor fix

* fix docs

* add warning

* rm new-tutorial run in ci

* lint
2021-02-20 17:42:45 +08:00

63 lines
4.3 KiB
ReStructuredText
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
.. _guide_cn-distributed-preprocessing:
7.1 分布式训练所需的图数据预处理
------------------------------------------
:ref:`(English Version) <guide-distributed-preprocessing>`
DGL要求预处理图数据以进行分布式训练这包括两个步骤1)将一张图划分为多张子图(分区)2)为节点和边分配新的ID。
DGL提供了一个API以执行这两个步骤。该API支持随机划分和一个基于
`Metis <http://glaros.dtc.umn.edu/gkhome/views/metis>`__ 的划分。Metis划分的好处在于
它可以用最少的边分割以生成分区从而减少了用于分布式训练和推理的网络通信。DGL使用最新版本的Metis
并针对真实世界中具有幂律分布的图进行了优化。在图划分后API以易于在训练期间加载的格式构造划分结果。
**Note**: 图划分API当前在一台机器上运行。 因此如果一张图很大,用户将需要一台大内存的机器来对图进行划分。
未来DGL将支持分布式图划分。
默认情况下,为了在分布式训练/推理期间定位节点/边API将新ID分配给输入图的节点和边。
分配ID后该API会相应地打乱所有节点数据和边数据。在训练期间用户只需使用新的节点和边的ID。
与此同时,用户仍然可以通过 ``g.ndata['orig_id']````g.edata['orig_id']`` 获取原始ID。
其中 ``g````DistGraph`` 对象(详细解释,请参见:ref:`guide-distributed-apis`)。
DGL将图划分结果存储在输出目录中的多个文件中。输出目录里始终包含一个名为xxx.json的JSON文件其中xxx是提供给划分API的图的名称。
JSON文件包含所有划分的配置。如果该API没有为节点和边分配新ID它将生成两个额外的NumPy文件`node_map.npy``edge_map.npy`
它们存储节点和边ID与分区ID之间的映射。对于具有十亿级数量节点和边的图两个文件中的NumPy数组会很大
这是因为图中的每个节点和边都对应一个条目。在每个分区的文件夹内有3个文件以DGL格式存储分区数据。
`graph.dgl` 存储分区的图结构以及节点和边上的一些元数据。`node_feats.dgl``edge_feats.dgl` 存储属于该分区的节点和边的所有特征。
.. code-block:: none
data_root_dir/
|-- xxx.json # JSON中的分区配置文件
|-- node_map.npy # 存储在NumPy数组中的每个节点的分区ID可选
|-- edge_map.npy # 存储在NumPy数组中的每个边的分区ID可选
|-- part0/ # 分区0的数据
|-- node_feats.dgl # 以二进制格式存储的节点特征
|-- edge_feats.dgl # 以二进制格式存储的边特征
|-- graph.dgl # 以二进制格式存储的子图结构
|-- part1/ # 分区1的数据
|-- node_feats.dgl
|-- edge_feats.dgl
|-- graph.dgl
负载均衡
~~~~~~~~~~~~~~
在对图进行划分时默认情况下Metis仅平衡每个子图中的节点数。根据当前的任务情况这可能带来非最优的配置。
例如,在半监督节点分类的场景里,训练器会对局部分区中带标签节点的子集进行计算。
一个仅平衡图中节点(带标签和未带标签)的划分可能会导致计算负载不平衡。为了在每个分区中获得平衡的工作负载,
划分API通过在 :func:`dgl.distributed.partition_graph` 中指定 ``balance_ntypes``
在每个节点类型中的节点数上实现分区间的平衡。用户可以利用这一点将训练集、验证集和测试集中的节点看作不同类型的节点。
以下示例将训练集内和训练集外的节点看作两种类型的节点:
.. code:: python
dgl.distributed.partition_graph(g, 'graph_name', 4, '/tmp/test', balance_ntypes=g.ndata['train_mask'])
除了平衡节点的类型之外, :func:`dgl.distributed.partition_graph` 还允许通过指定
``balance_edges`` 来平衡每个类型节点在子图中的入度。这平衡了不同类型节点的连边数量。
**Note**: 传给 :func:`dgl.distributed.partition_graph` 的图名称是一个重要的参数。
:class:`dgl.distributed.DistGraph` 使用该名称来识别一个分布式的图。一个有效的图名称应该仅包含字母和下划线。