ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

DGL 分布式 GraphSAGE 训练完整实战指南:从 NFS 集群搭建到 GraphBolt 加速

DGL 分布式 GraphSAGE 训练完整实战指南:从 NFS 集群搭建到 GraphBolt 加速 人工智能机器学习深度学习图计算【免费下载链接】dglPython package built to ease deep learning on graph, on top of existing DL frameworks.项目地址https://gitcode.com/gh_mirrors/dg/dgl点击查看免费下载本指南基于 DGL 官方分布式示例 examples/distributed/graphsage 展开系统讲解如何在多机集群上完成 GraphSAGE 的分布式训练涵盖 NFS 分布式文件系统搭建、IP 配置、图分区、任务启动、有监督与无监督训练以及 GraphBolt 数据格式转换与性能优化。读者按本文操作后即可在自己的集群上跑通 ogbn-products 等大规模图数据的分布式节点分类任务并理解每一步背后的 DGL 源码实现原理。概览分布式训练的整体流程分布式训练与单机训练的核心区别在于图数据、节点特征、模型参数与采样过程都需要跨多台机器协同。DGL 官方示例将整个流程拆解为五个步骤Step 0搭建分布式文件系统NFS/Ceph让所有机器共享代码与数据文件Step 1编写 IP 配置文件ip_config.txt声明集群内所有机器地址Step 2使用 Metis 等算法将图划分为与机器数相等的分区Step 3通过 tools/launch.py 一键在集群上启动采样与训练进程Step 4可选增强将分区转换为 GraphBolt 格式获得更小的分区体积与更快的采样速度。开始之前请先安装示例所需的 Python 依赖pip3 install ogb环境要求本示例依赖 PyTorch 1.12.0 及以上版本README 中的明确要求。此外 DGL 的分布式模块dgl.distributed也是运行前提。示例目录中共有三个脚本构成完整的训练闭环文件作用examples/distributed/graphsage/partition_graph.py加载 Reddit / ogbn-products / ogbn-papers100M 数据集并调用dgl.distributed.partition_graph完成图分区examples/distributed/graphsage/node_classification.py有监督 GraphSAGE 分布式节点分类训练与评估examples/distributed/graphsage/node_classification_unsupervised.py无监督训练基于链接预测任务 下游 Logistic Regression 评估Step 0搭建分布式文件系统分布式训练要求所有机器都能访问相同的代码和数据。如果你的集群已经具备多机同步的共享目录例如挂载了统一的存储可以跳过本步否则需要自建一套分布式文件系统NFS 和 Ceph 都是常见选择。本示例以 NFS 为例给出完整配置过程。服务器端配置在存储服务器上安装 NFS 内核服务sudo apt-get install nfs-kernel-server假设用户账号为ubuntu在 home 目录下创建共享工作目录mkdir -p /home/ubuntu/workspace假设集群所有服务器位于192.168.0.0~192.168.255.255网段将/etc/exports配置修改为sudo vim /etc/exports # add the following line /home/ubuntu/workspace 192.168.0.0/16(rw,sync,no_subtree_check)服务器内网 IP 可通过ifconfig或ip命令查看。如果服务器 IP 不以192.168开头可以根据实际网段改用以下两条规则之一覆盖10.x.x.x与172.16.x.x私有网段/home/ubuntu/workspace 10.0.0.0/8(rw,sync,no_subtree_check) /home/ubuntu/workspace 172.16.0.0/12(rw,sync,no_subtree_check)修改完成后重启 NFS 服务即完成服务器端配置sudo systemctl restart nfs-kernel-server配置选项说明rw允许读写sync要求服务端同步写入磁盘保证多机数据一致性no_subtree_check禁用子树检查以提升性能。更细粒度的 NFS 调优参数可参考 NFS 官方 ArchWiki 文档。客户端配置客户端机器需要安装 NFS 客户端工具sudo apt-get install nfs-common可以手动挂载共享目录mkdir -p /home/ubuntu/workspace sudo mount -t nfs nfs-server-ip:/home/ubuntu/workspace /home/ubuntu/workspace也可以写入/etc/fstab让系统开机自动挂载# vim /etc/fstab ## append the following line to the file nfs-server-ip:/home/ubuntu/workspace /home/ubuntu/workspace nfs defaults 0 0然后执行mount -a使配置生效。最后所有机器进入共享目录克隆 DGL 仓库保证workspace下代码完全一致cd /home/ubuntu/workspace git clone https://gitcode.com/gh_mirrors/dg/dglStep 1配置 IP 文件与免密 SSH训练前需要编写集群的 IP 配置文件ip_config.txt。文件每行一个 IP 地址行数即参与训练的机器数。例如 4 台机器的集群配置如下172.31.19.1 172.31.23.205 172.31.29.175 172.31.16.98关键约束主节点node-0即文件第一行对应的机器必须能够免密 SSH 登录到其余所有节点。因为 tools/launch.py 正是通过 SSH 在每台机器上拉起训练进程的。从源码看launcher 通过ssh -o StrictHostKeyCheckingno -p {port} {ip} {cmd}在远程主机执行命令见 launch.py 的execute_remote实现并支持通过--ssh_port与--ssh_username参数指定 SSH 端口和用户名。免密登录可通过ssh-keygen生成密钥、将公钥追加到各节点~/.ssh/authorized_keys的方式配置具体步骤可参考通用的 passwordless SSH 配置教程。Step 2图分区Partition分区脚本的用法示例提供了 partition_graph.py 脚本用于对 Reddit、ogbn-products、ogbn-papers100M 等内置数据集进行分区。要在 4 台机器上训练就需要把图切成 4 份。以下命令在 node-0 上执行使用 Metis 算法将 ogbn-products 划分为 4 份python3 partition_graph.py --dataset ogbn-products --num_parts 4 --balance_train --balance_edges分区结果会写入名为data的目录。该脚本还保证分区在节点数、边数和带标签节点数三个维度上尽量均衡这对后续训练负载均衡至关重要。分区脚本参数详解从 partition_graph.py 的 argparse 定义可以看到完整参数列表参数默认值说明--datasetreddit数据集名称支持reddit、ogbn-products、ogbn-papers100M--num_parts4分区数量通常等于集群机器数--part_methodmetis分区算法默认 Metis--balance_trainFalse是否按训练节点数均衡分区会作为balance_ntypes传入底层--undirectedFalse是否先将图转为无向图调用dgl.to_bidirected并复制节点特征--balance_edgesFalse是否按边数均衡分区--num_trainers_per_machine1每台机器的 trainer 数量该值会写入节点特征trainer_id--outputdata分区输出路径--use_graphboltFalse是否同时生成 GraphBolt 数据格式详见后文底层实现partition_graph分区脚本最终调用dgl.distributed.partition_graph其完整签名位于 python/dgl/distributed/partition.py。从源码注释可以看出分区过程分三步1运行分区算法如 Metis为节点分配所属分区2基于节点分配结果构造分区图结构3按分区结果切分节点特征与边特征。分区时会引入HALO 节点即属于其他分区、但被包含进本分区以提升采样效率的节点。每个分区还包含独立的local nodes/edges真正归属本分区的节点/边。halo_hops参数默认 1控制 HALO 范围跳数。分区文件的组织格式源自 partition.py 源码注释data_root_dir/ |-- graph_name.json # 分区配置文件JSON记录原图信息与各分区文件路径 |-- node_map.npy # 每个节点所属分区 id可选 |-- edge_map.npy # 每条边所属分区 id可选 |-- part0/ # 分区 0 的数据 |-- node_feats.dgl # 节点特征二进制格式 |-- edge_feats.dgl # 边特征二进制格式 |-- graph.dgl # 该分区图结构二进制格式 |-- part1/ # 分区 1 的数据 |-- ...其中graph_name.json如data/ogbn-products.json就是后续 launch 阶段--part_config指定的文件JSON 中记录graph_name、part_method、num_parts、halo_hops、node_map等元数据。Step 3启动分布式训练任务有监督节点分类DGL 提供 tools/launch.py 一键启动整个集群的训练任务。part_config和ip_config参数填写的是相对于 workspace 的路径注意workspace 即examples/distributed/graphsage/目录需通过--workspace显式指定。下面的命令在每台机器上各启动 1 个进程同时承担采样与训练python3 ~/workspace/dgl/tools/launch.py \ --workspace ~/workspace/dgl/examples/distributed/graphsage/ \ --num_trainers 1 \ --num_samplers 0 \ --num_servers 1 \ --part_config data/ogbn-products.json \ --ip_config ip_config.txt \ python3 node_classification.py --graph_name ogbn-products --ip_config ip_config.txt --num_epochs 30 --batch_size 1000默认情况下代码在 CPU 上运行。如果有 GPU只需在用户命令中追加--num_gpus参数python3 ~/workspace/dgl/tools/launch.py \ --workspace ~/workspace/dgl/examples/distributed/graphsage/ \ --num_trainers 4 \ --num_samplers 0 \ --num_servers 1 \ --part_config data/ogbn-products.json \ --ip_config ip_config.txt \ python3 node_classification.py --graph_name ogbn-products --ip_config ip_config.txt --num_epochs 30 --batch_size 1000 --num_gpus 4launch.py 的关键参数对照 launch.py 的参数解析代码各参数含义如下参数默认值说明--workspace必填工作目录也是各机器上执行任务时相对路径的基准launcher 会将该目录内容同步rsync到各节点--num_trainers必填正整数每台机器上的 trainer 进程数--num_samplers0每个 trainer 进程对应的独立 sampler 进程数0 表示采样在 trainer 进程内完成--num_servers必填正整数每台机器上的 server 进程数负责托管分布式图与特征存储--num_omp_threads自动计算每个 trainer 的 OMP 线程数未指定时按cpu_count // 2 // num_trainers计算--num_server_threads1server 进程内 OMP 线程数server 与 trainer 同机时建议保持较小值--part_config必填分区配置文件workspace 内相对路径即 Step 2 生成的data/ogbn-products.json--ip_config必填IP 配置文件workspace 内相对路径--graph_formatcsc各分区图结构格式支持csr、csc、coo可逗号分隔多选如csr,csc--ssh_port22SSH 连接端口--ssh_username空指定 SSH 用户名命令形如ssh bob1.2.3.4 CMD--extra_envs[]追加环境变量例如--extra_envs NCCL_DEBUGINFO LD_LIBRARY_PATH...launcher 会检查--num_trainers、--num_samplers、--num_servers、--num_server_threads等参数的合法性并在udf_command中检测到不含python时直接报错仅支持 Python 可执行命令。当--num_trainers 1时launcher 还会将用户命令包装进torch.distributed.run见wrap_udf_in_torch_dist_launcherlaunch.py以--nproc_per_node、--nnodes、--node_rank、--master_addr、--master_port参数初始化 PyTorch 分布式进程组。无监督训练链接预测示例还提供基于链接预测目标的无监督训练使用DistEdgeDataLoader构造正负边样本python3 ~/workspace/dgl/tools/launch.py \ --workspace ~/workspace/dgl/examples/distributed/graphsage/ \ --num_trainers 1 \ --num_samplers 0 \ --num_servers 1 \ --part_config data/ogbn-products.json \ --ip_config ip_config.txt \ python3 node_classification_unsupervised.py --graph_name ogbn-products --ip_config ip_config.txt --num_epochs 30 --batch_size 1000 --remove_edge无监督脚本的关键实现node_classification_unsupervised.py使用dgl.dataloading.negative_sampler.Uniform(args.num_negs)生成负样本通过DistEdgeDataLoader迭代(input_nodes, pos_graph, neg_graph, blocks)--remove_edge开启后训练时排除反向边excludereverse_id避免信息泄露--debug可开启断言验证边排除功能是否生效损失函数CrossEntropyLoss通过fn.u_dot_v计算正/负边两端节点 embedding 的内积得分再用binary_cross_entropy_with_logits优化训练完成后生成全图节点 embedding 并保存为emb.pt随后训练一个 sklearn LogisticRegression 分类器compute_acc在验证集/测试集上评估 embedding 质量。使用 GraphBolt 运行分布式训练为什么用 GraphBoltGraphBolt 是 DGL 面向大规模图采样的下一代数据格式FusedCSCSamplingGraph。使用 GraphBolt 需要先将图分区为 GraphBolt 数据格式。注意转换后 DGL 与 GraphBolt 两种分区会同时保存在data目录下互不覆盖方便随时切换训练方式。如果已经用 DGL 格式完成分区可以直接在线转换python3 -c import dgl; dgl.distributed.dgl_partition_to_graphbolt(ogbn-products.json)也可以分区时直接生成 GraphBolt 格式--use_graphboltpython3 partition_graph.py --dataset ogbn-products --num_parts 2 --balance_train --balance_edges --use_graphboltdgl_partition_to_graphbolt的完整签名位于 python/dgl/distributed/partition.py。它将 DGL 分区转换为FusedCSCSamplingGraph新图以fused_csc_sampling_graph.pt文件存放于原分区旁。该 API 还支持store_eids是否保存边 ID默认 True、store_inner_node/store_inner_edge是否保存内部节点/边 mask、graph_formatscsc必存可额外指定coo与n_jobs并行转换任务数等可选参数。分区体积对比GraphBolt 明显更小README 中给出了两个数据集的实测对比数据。相比 DGL 格式GraphBolt 分区体积大幅缩小ogbn-products 与 ogbn-papers100M 分别缩减到约16%和19%。ogbn-products数据格式文件名Part 0Part 1DGLgraph.dgl1.5GB1.6GBGraphBoltfused_csc_sampling_graph.pt255MB265MBogbn-papers100M数据格式文件名Part 0Part 1DGLgraph.dgl23GB22GBGraphBoltfused_csc_sampling_graph.pt4.4GB4.1GB分区体积减小的直接收益是共享内存shared memory用free命令的shared字段衡量占用随之下降因为 server 进程需要常驻内存的图结构更小了。不过需要注意进程峰值内存free命令的used字段并不会下降。用 GraphBolt 启动训练分区准备好后只需在用户命令中追加--use_graphboltpython3 ~/workspace/dgl/tools/launch.py \ --workspace ~/workspace/dgl/examples/distributed/graphsage/ \ --num_trainers 4 \ --num_samplers 0 \ --num_servers 2 \ --part_config data/ogbn-products.json \ --ip_config ip_config.txt \ python3 node_classification.py --graph_name ogbn-products --ip_config ip_config.txt --num_epochs 10 --use_graphbolt在训练脚本侧--use_graphbolt会传入dgl.distributed.initialize(args.ip_config, use_graphboltargs.use_graphbolt)见 node_classification.py使 DistGraph 初始化时按 GraphBolt 分区加载图结构。采样性能对比README 报告了 CPU 模式下每 epoch 采样时间的对比。相比 DGLGraphBolt 采样器速度更快ogbn-products 与 ogbn-papers100M 的采样时间分别缩减到约80%和77%。表中Min/Max是所有节点机器上所有 trainer 进程的统计值。ogbn-products数据格式每 Epoch 采样时间CPU测试准确率10 epochssharedused峰值DGLMin: 1.2884s, Max: 1.4159sMin: 64.38%, Max: 70.42%2.4GB7.8GBGraphBoltMin: 1.0589s, Max: 1.1400sMin: 61.68%, Max: 71.23%1.1GB7.8GBogbn-papers100M数据格式每 Epoch 采样时间CPU测试准确率10 epochssharedused峰值DGLMin: 5.5570s, Max: 6.1900sMin: 29.12%, Max: 34.33%84GB43GBGraphBoltMin: 4.5046s, Max: 4.7718sMin: 29.11%, Max: 33.49%67GB43GB需要注意两点其一两种格式训练 10 个 epoch 后得到的测试准确率相当差距在 1~2 个百分点内波动说明 GraphBolt 在提速的同时不牺牲模型收敛质量其二这些数据是特定集群环境下的实测结果实际数值会随硬件、网络与参数配置变化。深入理解训练脚本的分布式执行链路初始化链路训练脚本的main函数node_classification.py依次执行dgl.distributed.initialize(args.ip_config, use_graphbolt...)读取 IP 配置初始化 DGL 分布式运行时th.distributed.init_process_group(backendargs.backend)初始化 PyTorch 进程组默认gloo后端CPU 场景常用dgl.distributed.DistGraph(args.graph_name, part_configargs.part_config)加载分布式图每个进程只持有本分区数据g.rank()标识当前分区编号通过dgl.distributed.node_split(train_mask, pb, force_evenTrue)把训练/验证/测试节点均匀切分到各 trainer若分区时指定了num_trainers_per_machine会依据节点特征trainer_id精确切分组装DistNodeDataLoaderNeighborSampler([int(fanout) for fanout in args.fan_out.split(,)])进入训练循环。训练循环会逐项统计sample_time、forward_time、backward_time、update_time每--log_every步打印一次吞吐samples/sec与 GPU 显存占用方便定位性能瓶颈。推理阶段的按层全邻居聚合DistSAGE.inferencenode_classification.py实现了分布式逐层推理每一层使用NeighborSampler([-1])表示包含全部入边即全邻居聚合将整图节点按 batch 前向传播中间结果写入持久化的dgl.distributed.DistTensor并通过g.barrier()同步各 trainer。这与训练阶段的多层 block 采样是互补的两套策略训练用有限 fanout 控制计算量推理用全邻居保证表征质量。常用训练超参数训练脚本 的默认超参数如下均可通过命令行覆盖参数默认值说明--num_epochs20训练轮数--num_hidden16隐藏层维度--num_layers2SAGE 层数--fan_out10,25每层采样邻居数逗号分隔--batch_size1000训练 batch 大小--batch_size_eval100000推理 batch 大小--log_every20日志打印间隔--eval_every5每隔多少 epoch 评估一次--lr0.003Adam 学习率--dropout0.5Dropout 概率--num_gpus0GPU 数量0 表示 CPU 训练--backendglooPyTorch 分布式后端--n_classes0类别数0 表示从标签自动推断总结与最佳实践文件系统先行多机训练前务必保证代码与数据在所有节点同步NFS 挂载是最简单的方案节点间免密 SSH 是 launcher 正常工作的前提。分区数量与机器数对齐--num_parts一般等于机器数配合--balance_train与--balance_edges可获得更均匀的负载。进程角色分离默认配置--num_trainers 1 --num_samplers 0 --num_servers 1每机一个进程同时采样与训练规模增大时可增加--num_trainers配 GPU 时--num_gpus 4即每机 4 个 trainer或拆分 sampler 进程。优先考虑 GraphBolt分区体积可缩减至 DGL 格式的约五分之一采样更快、共享内存占用更低且不影响最终准确率DGL 与 GraphBolt 分区可共存切换只需加--use_graphbolt。关注真实瓶颈训练日志中的 sample / forward / backward / update 四段耗时统计可以帮助你判断瓶颈究竟在采样、通信还是计算。更多可参考的仓库资源分布式分区核心实现、分布式训练启动器、有监督训练脚本、无监督训练脚本。赞分享人工智能机器学习深度学习图计算【免费下载链接】dglPython package built to ease deep learning on graph, on top of existing DL frameworks.项目地址https://gitcode.com/gh_mirrors/dg/dgl点击查看免费下载相关推荐DGL分布式GraphSAGE训练实战指南DGL分布式GraphSAGE训练实战指南 概述 本文将详细介绍如何使用DGLDeep Graph Library框架进行分布式GraphSAGE模型训练。人工智能机器学习深度学习图计算使用 DGL Sparse 与 GraphBolt 完成 GraphSAGE 小批量训练实战指南使用 DGL Sparse 与 GraphBolt 完成 GraphSAGE 小批量训练实战指南 本文基于 DGL 官方指南 docs/source/guide人工智能机器学习深度学习图计算DGL 分布式训练完全指南从图划分到集群启动的完整实战DGL 分布式训练完全指南从图划分到集群启动的完整实战 导读 本文是 DGLDeep Graph Library用户指南第 7 章「分布式训练」的中文完整人工智能机器学习深度学习图计算创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表