<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>GNN on bitJoy</title><link>https://bitjoy.net/tags/gnn/</link><description>Recent content in GNN on bitJoy</description><generator>Hugo -- 0.148.2</generator><language>en</language><lastBuildDate>Wed, 04 May 2022 10:55:37 +0800</lastBuildDate><atom:link href="https://bitjoy.net/tags/gnn/index.xml" rel="self" type="application/rss+xml"/><item><title>《DistDGL： Distributed Graph Neural Network Training for Billion-Scale Graphs》论文阅读</title><link>https://bitjoy.net/posts/2022-05-04-aws-distdgl-paper-reading/</link><pubDate>Wed, 04 May 2022 10:55:37 +0800</pubDate><guid>https://bitjoy.net/posts/2022-05-04-aws-distdgl-paper-reading/</guid><description>&lt;h1 id="前言">前言&lt;/h1>
&lt;p>工业界的图规模都非常大，少说也是上千万的顶点+上亿的边，单机训练不现实，必须借助多机分布式训练。然而目前主流的图训练框架PyG、DGL对图的多机分布式训练支持都不太好。工业界好像阿里的Euler、百度的PGL可以支持分布式训练。今天介绍一下亚马逊DGL针对分布式训练所做的优化。&lt;/p>
&lt;h1 id="摘要">摘要&lt;/h1>
&lt;p>GNN广泛应用在推荐、搜索、风控等领域，在这些领域，图的规模往往非常大，有数以亿计的顶点和万亿的边。为支持大规模图的分布式训练，本文提出了DistDGL，它能以mini-batch的方式在多机上进行分布式训练。DistDGL基于DGL框架，它将图数据分布在多台机器上，并基于数据分布，将计算也分布在多台机器上（owner-compute rule）。DistDGL以同步更新的方式进行训练。为了减小分布式训练的通信开销，DistDGL使用一个高效、轻量的图分割算法对图进行分割，在分割时设计了多个负载均衡约束，使得每个分割的子图达到较好的负载均衡。此外，为了减小跨机器的通信，DistDGL在每个子图中保留了halo nodes（正文会介绍到），并且使用了稀疏embedding更新策略。这些优化策略使得DistDGL在分布式训练时能达到较好的高并行效率和内存可扩展性。实验结果表明，在分布式训练时，随着计算资源的增大，DistDGL的训练速度可以线性增长。在16台机器组成的分布式环境中，DistDGL仅用13秒就可以完成1亿节点+30亿边的一个epoch的训练。DistDGL是DGL的一部分，已开源在：&lt;a href="https://github.com/dmlc/dgl/tree/master/python/dgl/distributed">https://github.com/dmlc/dgl/tree/master/python/dgl/distributed&lt;/a>。&lt;/p>
&lt;h1 id="简介">简介&lt;/h1>
&lt;p>GNN很有用，但是现实世界中的网络都很大，比如Facebook的社交网络、Amazon的用户商品关系网络等。&lt;/p>
&lt;p>GNN分布式训练的难点：&lt;/p>
&lt;ul>
&lt;li>GNN中每个训练样本（顶点）不是独立的，是相互依赖的，比如为了训练顶点A，必须采样A的邻居，随着GNN层数的增大，采样的邻居数目呈指数上升。而CV、NLP中每条样本是相互独立的。&lt;/li>
&lt;li>GNN的多机分布式训练的通信数据主要是图数据（顶点和边，及其属性），而CV、NLP的分布式训练的通信数据主要是网络参数、梯度等，需要通信的数据类型不同，导致CV、NLP的分布式训练优化技术无法直接迁移到GNN的分布式训练中。&lt;/li>
&lt;li>此外，神经网络大多采用同步更新的分布式训练策略（难道不是异步？），因此需要尽量做到不同机器或者worker的负载均衡。由于图的特殊结构，不同顶点的度差异很大，即不同子图的负载差异很大，所以如何实现GNN训练时的负载均衡，也是一个难点。&lt;/li>
&lt;/ul>
&lt;h1 id="背景介绍">背景介绍&lt;/h1>
&lt;h2 id="gnn">GNN&lt;/h2>
&lt;p>以消息传递的方式来解读GNN，每一层GNN可以用下面的公式来概括。\(\mathbf{h}_v^{(l+1)}\)和\(\mathbf{h}_v^{l}\)分别表示节点\(v\)在第\(l+1\)层和第\(l\)层的向量表示。\(f\)表示节点\(v\)和每个邻居\(u\)计算消息；\(\oplus\)表示邻居聚合函数；\(g\)用来更新节点表示。&lt;/p>
&lt;p>&lt;img alt="image" loading="lazy" src="https://bitjoy.net/posts/2022-05-04-aws-distdgl-paper-reading/DistDGL-formula-1.png">&lt;/p>
&lt;p>作者将GNN的参数分为两部分，一部分是网络参数，即上面的\(f\)、\(\oplus\)和\(g\)。另一部分是节点本身的embedding参数，对于transductive模型来说，节点本身有embedding，故有这部分参数；但对于inductive模型，节点本身没有embedding参数，节点的embedding表示是通过网络参数生成的。&lt;/p>
&lt;p>为了区分这两部分参数，作者将网络参数称为稠密参数dense parameters，所有dense参数在每个mini-batch都需要被全部更新。作者将顶点本身的embedding参数称为稀疏参数sparse parameters，每个mini-batch只需要更新该batch涉及到的顶点的稀疏参数即可。&lt;/p>
&lt;h2 id="mini-batch-training">Mini-batch training&lt;/h2>
&lt;p>GNN进行mini-batch训练时的基本流程如下：&lt;/p>
&lt;ol>
&lt;li>从训练集中随机采样N个顶点，这部分顶点称为target vertices&lt;/li>
&lt;li>对每个target vertex随机采样最多K个邻居顶点&lt;/li>
&lt;li>对每个target vertex，通过聚合其邻居的信息得到target vertex的表示&lt;/li>
&lt;/ol>
&lt;p>上述流程是一层GNN的训练过程，如果GNN有多层，则邻居采样的过程会递归进行下去。&lt;/p>
&lt;h1 id="方法">方法&lt;/h1>
&lt;h2 id="distdgl分布式训练框架">DistDGL分布式训练框架&lt;/h2>
&lt;p>&lt;img alt="image" loading="lazy" src="https://bitjoy.net/posts/2022-05-04-aws-distdgl-paper-reading/DistDGL-fig2.png">&lt;/p>
&lt;p>DistDGL的核心可以用上面的图来表示。DistDGL包含三个组件：&lt;/p>
&lt;ul>
&lt;li>Trainer，即图中的GNN Training Component，其中放大的GNN Training Component只是右边3个之一的放大图而已。Trainer主要是用来训练的，即进行前向传播和反向传播的。&lt;/li>
&lt;li>Sampler，即图中的Sampling Component，用来采样邻居的。&lt;/li>
&lt;li>KVStore，即图中的KVStore Component，用来存储顶点和边的特征，以及相应的embedding。&lt;/li>
&lt;/ul>
&lt;p>对照背景介绍中的mini-batch training过程，DistDGL的训练过程如下：&lt;/p>
&lt;ol>
&lt;li>Trainer随机采样N个顶点作为target vertices&lt;/li>
&lt;li>Trainer向Sampler请求采样target vertices的邻居&lt;/li>
&lt;li>Trainer向KVStore请求target vertices及其邻居的属性信息&lt;/li>
&lt;li>Trainer开始分布式训练，并使用AllReduce方式同步更新dense参数（网络参数）；并将sparse参数（embedding）存储到KVStore中&lt;/li>
&lt;/ol>
&lt;h2 id="主要优化点">主要优化点&lt;/h2>
&lt;h3 id="图分割及负载均衡">图分割及负载均衡&lt;/h3>
&lt;p>这是DistDGL最核心的优化点。为了实现高效的分布式训练，DistDGL首先使用METIS图分割算法把图分割成多个子图，不同子图分布式存储在不同机器上；然后把不同子图的计算也分配到存储数据的机器上。做到数据在哪里，计算就在哪里（owner-compute rule），最大程度利用数据和计算的局部性，减小网络通信。&lt;/p>
&lt;p>如下图所示，METIS算法以最小割的方式分割图网络，即如果每条边都有不同的权重的话，METIS希望分割的时候切割的边的权重之和最小，由此可以尽量把有密切连接的节点分割到同一个子图中。&lt;/p>
&lt;p>我没仔细研究METIS算法，我理解METIS还需要一个约束，即需要分割成多少个子图，或者每个子图最多有多少个顶点之类的。要不然什么都不分割，直接输出全图，则割最小是0。&lt;/p>
&lt;p>如果某一条边被分割了，其所连的两个顶点被分割到两个不同的子图中了，称这样的顶点为HALO vertices（通俗理解就是边缘点）。如果需要采样HALO顶点的邻居，则需要跨子图进行采样，涉及到网络通信。为了避免网络通信成为瓶颈，DistDGL会在两个子图中都保留HALO顶点的另一端顶点。在这种情况下，如果只涉及到HALO顶点的一跳采样的话，不需要跨子图通信。DistDGL通过冗余存储HALO顶点，以减小网络通信。由于GNN网络的邻居采样一般只会有2-3跳，所以这种策略应该能避免大部分跨子图通信。&lt;/p>
&lt;p>由于同一批数据只需要在开始训练时做一次分割，相对于漫长的N个epoch训练时间来说，分割图的时间开销被分摊了，可以忽略不计。&lt;/p>
&lt;p>&lt;img alt="image" loading="lazy" src="https://bitjoy.net/posts/2022-05-04-aws-distdgl-paper-reading/DistDGL-fig4.png">&lt;/p>
&lt;p>分割完图之后，DistDGL把不同子图分配到不同机器上。在训练的时候，由于trainer、sampler和KVStore需要互相交换数据，为了提高数据交换效率，DistDGL把属于同一个子图的trainer、sampler和KVStore分配到了同一台机器上，则三者之间的通信可以直接通过共享内存的方式进行内存拷贝，大幅减小了网络通信带来的延时。&lt;/p>
&lt;p>如下图所示，同一台机器上的Trainer、Sampler和KVStore是共享内存的。&lt;/p>
&lt;p>&lt;img alt="image" loading="lazy" src="https://bitjoy.net/posts/2022-05-04-aws-distdgl-paper-reading/DistDGL-fig3.png">&lt;/p>
&lt;p>文中还提到在METIS分割图的时候，增加了很多约束条件，以达到负载均衡的目的。我理解默认METIS在进行分割的时候，可能只保证不同子图的顶点数大致相同，在这个约束下去最小化割。然而子图的顶点数相同，并不代表子图的负载也相同，还涉及到子图中边的数目，不同类型顶点的数目分布等等。因此DistDGL在METIS子图分割时还增加了很多约束条件，使得分割的子图在训练的时候尽量达到负载均衡。&lt;/p>
&lt;h3 id="分布式kvstore">分布式KVStore&lt;/h3>
&lt;p>DistDGL把顶点和边的属性特征及embedding存储在分布式KVStore中，DistDGL开发了自己的分布式KVStore，而不是使用现成的比如Reddis，原因是更方便自定义功能，比如把属于同一个子图的顶点、边、特征存储到同一个机器上，优化了网络传输，实现稀疏embedding的异步更新等。&lt;/p>
&lt;h3 id="分布式sampler">分布式Sampler&lt;/h3>
&lt;p>Trainer训练和Sampler采样是并行进行的，简单理解就是，Trainer在训练当前Epoch数据的时候，Sampler就已经在异步采样下一个Epoch的数据了，充分利用计算资源，实现流水线作业。类似的，局部采样和远程网络RPC通信也可以overlap“同步”进行，使得局部采样感受不到远程通信的等待时间。&lt;/p></description></item><item><title>CS224W（1.12）Lecture 1. Introduction; Machine Learning for Graphs</title><link>https://bitjoy.net/posts/2022-04-27-cs224w-0112-lecture-1-introduction-machine-learning-for-graphs/</link><pubDate>Wed, 27 Apr 2022 14:36:06 +0800</pubDate><guid>https://bitjoy.net/posts/2022-04-27-cs224w-0112-lecture-1-introduction-machine-learning-for-graphs/</guid><description>&lt;h1 id="前言">前言&lt;/h1>
&lt;p>最近的工作涉及到图神经网络，打算系统学习下这方面的内容。首先搜集了相关的教材，发现市面上的教材大多数是罗列论文的形式，不太适合初学者入门。后来找到了斯坦福CS224W这门公开课，打算入坑，一是之前学习过&lt;a href="https://bitjoy.net/categories/stanford-cs224n-nlp-with-deep-learning/">斯坦福CS224N&lt;/a>，感觉不错；二是CS224W这门课的老师是GraphSAGE的作者Jure Leskovec，有大佬背书错不了。&lt;/p>
&lt;ul>
&lt;li>CS224W主页：&lt;a href="http://web.stanford.edu/class/cs224w/">http://web.stanford.edu/class/cs224w/&lt;/a>&lt;/li>
&lt;li>Winter 2021版主页：&lt;a href="http://snap.stanford.edu/class/cs224w-2020/">http://snap.stanford.edu/class/cs224w-2020/&lt;/a>&lt;/li>
&lt;li>Winter 2021版视频：&lt;a href="https://www.youtube.com/playlist?list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn">https://www.youtube.com/playlist?list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn&lt;/a>，Jure Leskovec是斯洛文尼亚人，英语不是很标准，建议打开YouTube的字幕。&lt;/li>
&lt;/ul>
&lt;h1 id="背景介绍">背景介绍&lt;/h1>
&lt;p>图（Graph）是描述实体（entity）和关系（relation）的一种通用语言形式，它由节点（vertex或node）和连接节点的边组成，很多数据类型都可以用图的形式来描述。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2022-04-27-cs224w-0112-lecture-1-introduction-machine-learning-for-graphs/cs224w-graph-demo.png">
图1 图及其应用实例&lt;/p>
&lt;p>目前常见的图有两类：&lt;/p>
&lt;ul>
&lt;li>第一类是网络（network），也称为自然图，例如：
&lt;ul>
&lt;li>社交网络，全球70亿人形成一个大网络&lt;/li>
&lt;li>通信网络，例如通过电话、邮件、交易等形成的网络&lt;/li>
&lt;li>生物医药网络，例如基因、蛋白质之间形成的网络&lt;/li>
&lt;li>大脑中的成千上万的神经元形成的网络&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>第二类是通过抽象表示形成的图，例如
&lt;ul>
&lt;li>人工组织形成的信息网络、知识网络&lt;/li>
&lt;li>软件中的代码调用形成的网络&lt;/li>
&lt;li>分子网络、场景图、基于粒子的物理模拟等&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>现有的机器学习工具箱主要针对图像、文本和语音，对图的机器学习处理工具相对较少，因为图是不规则的数据，难以处理。对图的处理主要有以下难点：&lt;/p>
&lt;ul>
&lt;li>图不是欧几里得数据结构，没有固定的大小和拓扑结构&lt;/li>
&lt;li>图上的节点没有固定的顺序，也没有参考点，是去中心化的&lt;/li>
&lt;li>图会随着时间动态变化，并且图中常常会融合多模态信息&lt;/li>
&lt;/ul>
&lt;p>本课程的两个重点：&lt;/p>
&lt;ul>
&lt;li>Deep learning in graphs，即图上的深度学习算法&lt;/li>
&lt;li>Representation learning，即图表示学习，将图中的节点嵌入到一个低维稠密向量中，使得网络中相似节点的embedding距离接近&lt;/li>
&lt;/ul>
&lt;p>本课程的主要内容包括：&lt;/p>
&lt;ul>
&lt;li>传统方法：Graphlets，Graph Kernels&lt;/li>
&lt;li>节点嵌入方法：DeepWalk，Node2Vec&lt;/li>
&lt;li>图神经网络：GCN，GraphSAGE，GAT，Theory of GNNs&lt;/li>
&lt;li>知识图谱：TransE，BetaE&lt;/li>
&lt;li>图上的深度生成网络&lt;/li>
&lt;li>图在生物医药，科学和工业上的应用&lt;/li>
&lt;/ul>
&lt;h1 id="图机器学习应用">图机器学习应用&lt;/h1>
&lt;p>图可以有很多应用场景，这些应用可以分为节点水平的（nodel level）、边水平的（edge level）、子图水平的（subgraph level）和图水平的（graph level）。下面逐一举例：&lt;/p>
&lt;ul>
&lt;li>Node-level：节点分类（node classification），例如预测节点的属性。节点回归？例如AlphaFolde使用GNN预测每个氨基酸在三维空间中的位置坐标，从而预测蛋白质的结构。感觉和GNN关系不太大吧？具体得看论文了。&lt;/li>
&lt;li>Edge-level：链接预测（link prediction），预测两个节点之间是否存在边。例如在推荐系统中，预测user是否会购买item等。另外还可以用于预测药物的副作用，例如任意两种药组合吃，是否会产生副作用，产生哪种副作用，都是针对边的任务。&lt;/li>
&lt;li>Sub-graph level：地图导航，预测预期到达时间（ETA）。DeepMind和Google Maps合作的一个工作，很有意思：&lt;a href="https://www.deepmind.com/blog/traffic-prediction-with-advanced-graph-neural-networks">https://www.deepmind.com/blog/traffic-prediction-with-advanced-graph-neural-networks&lt;/a>。简单来说，把每条路分段（supersegment），每段表示成一个点，一条路的相邻段（点）连边，交叉路口的段（点）连边。通过GNN的消息传递，一条路的拥堵信息，可以传递到相邻的路。很自然的想法，也符合实际情况，比如在这条路拥堵了，司机可能就会走相邻的路，进而会影响相邻的路的ETA。问题是，GNN对图很敏感，不同地区、地段的路网图差异很大，有的路网小，有的路网大，因此不同training run之间的方差很大。一开始想到用lr decay来缓解。后来使用MetaGradients让模型自动调整学习率。使用多个loss，多目标学习防止过拟合。&lt;/li>
&lt;li>Graph-level：例如新药发现：节点是原子、边是各种键，生成一个graph，就是一种新的复合物。物理模拟：动态图，节点表示粒子，有属性比如速度、动量，然后下一个时刻有新的位置，不断进化变化，类似RNN，可以模拟出粒子的动态变化过程。&lt;/li>
&lt;/ul>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2022-04-27-cs224w-0112-lecture-1-introduction-machine-learning-for-graphs/cs224w-graph-applications.png">
图2 图机器学习应用场景&lt;/p>
&lt;h1 id="图的表示方法">图的表示方法&lt;/h1>
&lt;p>构成图的基本要素包括顶点集合&lt;em>&lt;strong>N&lt;/strong>&lt;/em>和边集合&lt;em>&lt;strong>E&lt;/strong>&lt;/em>，可以用\(G(N,E)\)来表示一张图。&lt;/p>
&lt;p>根据边是否有方向，可以将图分为无向图和有向图，无向图即图中的边没有方向，有向图即图中的边有方向。&lt;/p>
&lt;p>对于无向图G，每个顶点的度就是该顶点所连边的数目，由于一条边连接了两个顶点，贡献了2个度，所以所有顶点的平均度数=2E/N。&lt;/p>
&lt;p>对于有向图，顶点的度可分为入度和出度，如图3所示，顶点C的入度为2，出度为1。所有顶点的平均入度=平均出度=E/N。如果某个顶点的入度为0，则称该顶点为源点，例如顶点G；如果某个顶点的出度为0，则称该顶点为槽点（sink），就像水槽一样，只进不出；如果某个顶点的入度和出度都为0，则称该顶点为孤立点。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2022-04-27-cs224w-0112-lecture-1-introduction-machine-learning-for-graphs/cs224w-graph-degrees.png">
图3 图的表示方法和顶点的度&lt;/p></description></item></channel></rss>