引言
GraphLearn(GL)是阿里巴巴开源的一个大规模图神经网络平台,本文将对GL的接口做基本介绍,帮助用户快速上手。项目地址:https://github.com/alibaba/graph-learn 。
图神经网络(Graph Neural Networks, GNNs)将深度神经网络技术应用于图结构上,通过递归地聚合邻域特征信息来表征顶点,GNNs的算法框架通常为Sample-Aggregate-Combine,如下Algorithm 1所示。
GNNs应用在推荐系统、数据挖掘、自然语言处理、知识图谱等领域中,比如在阿里的一个典型的推荐场景中,利用“用户-商品”,“商品-商品”的二部图预测一个用户是否会购买某个商品。
根据图神经网络的Sample-Aggregate-Combine框架,我们不难想象,一个完整的图神经网络的任务从端到端,可以粗略地分为图数据准备、构图、采样、查询、模型构建、训练、预测几个阶段。
从一键运行到深度定制
GL基于大规模异构图的场景,提供了一套简洁灵活的API,加速图神经网络的开发。
图神经网络学习有两种方式,一种是在全图上通过邻接矩阵计算,比如GCN/GAT等算法,这种方式受到内存的限制;另一种方式是对图采样,做mini-batch的计算,比如GraphSAGE等,这种方式更具有扩展性。GL支持这两大类型的算法,提供了GraphEngine API、Data Model API以及Graph learning models。
Graph Engine构造了一个全局唯一的Graph对象,在这个对象上进行查询、采样等操作。基于Graph Engine的接口,你可以遍历图、得到邻居样本、得到所需属性,从而自己组织数据,构造模型。
Data Model是GL的基础数据模型,由种子节点(seed nodes/edges)和邻域(receptive fields /multi-hops neighbors)组成。通过上层的Encoders可以转换为多种NN引擎对应的数据格式。基于Data Model,系统接手了样本数据的准备,你可以专注于模型的开发。
Graph learning models将Data model的数据转换为Embedding,并提供了多个built-in的GNNs models。Graph learning models可以直接调用,如果在自己的数据上运行,只需要简单适配即可。
从裸数据到GNN样本,只差一行python
Graph Engine包含图对象模块、采样模块和查询模块,这些 Graph 上的模块接口通过一套Gremlin-like API表达。如何从裸数据构造单机或分布式的图、如何在图上游走、如何遍历、如何采样邻域、查询哪些field,以及如何用这些数据构造图神经网络模型所需的样本,整个过程只需要一句python表示,类似data-flow的查询语句:
gl.Graph().node().edge().init().V().outV().sample().by().values()
我们将这一行代码拆分到图对象模块、采样模块和查询模块的接口中进行解释。
图对象
图对象模块用于将结构化的图数据转换为逻辑图对象。GL的入口非常简单,载入graphlearn库,构建一个 Graph 逻辑对象,后续所有的操作都在这个 Graph 对象上进行。
import graphlearn as gl
g = gl.Graph()
• 图数据格式:灵活的schema,多变的数据类型
GL图数据格式灵活,支持float,int,string类型的属性,支持带权重、标签。在现实的场景中,数据格式多变,通过config文件描述非常复杂,容易写错;有些GNN系统不支持多种类型的属性。
下面的示例描述了数据中存在string和float类型的两列属性和权重、标签列。
decoder = gl.Decoder(attr_types=["string", "float"], weighted=True, labeled=True)
• 数据源载入和拓扑描述:同构、异构、多数据源,通通支持
GL提供了 node 和 edge 两个简单的接口来支持顶点和边的数据源载入,同时在这两个接口中描述图的拓扑结构,比如“buy”边的源顶点类型是“user”,目的顶点类型是“item”。这个拓扑结构在异构图中十分重要,是后续采样路径meta-path的依据,也是查询的实体类型的基础。
g.node(data_source, node_type, decoder) \
.node(data_source, node_type, decoder) \
.edge(data_source, (src_node_type, dst_node_type, edge_type), decoder)
• Graph Engine启动:快速拉起大规模分布式图引擎
GL提供单机的版本, 通过init 接口快速启动Graph Engine,至此,图对象已经构造完毕,查询、采样操作就可以在 Graph 上进行了。
g.init()
在大规模的场景下,图顶点可达亿级别,边可达千亿级别,不管是图结构还是图属性,都无法完全载入单机内存。GL提供分布式的Graph Engine,速度非常快,使用上也非常简单,只需要在 init 中加几个参数。
g.init({"server_count": N, "client_count": M}, task_name, job_index)
采样
采样在GL中通过游走路径和采样策略进行描述。如下示例中,表达的是一个遍历和二跳邻居采样,即遍历图获得64个用户,对每个用户根据边的权重采样50个他们购买的商品的相似商品。
q = g.V("user").bath(64).outV("buy").sample(5).outV("similar-to").sample(10).by("edge_weight").values()
除了采样邻居,GL也提供了负采样,只需要将示例中的 outV 改为 outNeg 即可。GL提供了多种内置的采样策略,也支持自定义采样策略的实现,详细内容可见我们的系列文档中关于“采样算法”的文章。
查询
GL提供了 Nods
和 Edges
两个基础的数据类型,作为遍历、采样的结果。为了获取 Nodes 的int类型的属性,可以调用如下接口进行查询,得到的是numpy array数据结构。
nodes = g.run(q)
nodes[2].int_atrs # nodes is a list of Nodes, include Nodes of user,
# Nodes of item for 1 hop, Nodes of item of 2 hop.
g.run(q)
可以多次执行,遍历图中的顶点和他们的边,直到遍历完毕。因此,上述采样和查询的结果可以作为generator接入tf或pytorch等NN引擎作为数据源,从而深度定制GNN模型。
GL也提供了数据模型的封装,接管数据采样流程和样本组织,下文将简要描述数据模型。
那些Dirty work系统帮你做了
为了便于用户能更专注于探索模型,而非数据采样和样本组织,在模型编程接口层面我们封装了EgoGraph,用于产生接管样本和邻域产生的过程。
EgoGraph包含多种内置采样器和负采样器,覆盖有监督学习和无监督学习场景。EgoGraph 中的数据类型为numpy array,可以根据不同的NN引擎转化为不同的格式的 EgoTensor 。EgoFlow 用于将 EgoGraoh 处理并转换为 EgoTensor ,并构成数据产生的pipline。
GL提供Encoder的模块,用于将顶点、边或子图根据他们的邻域信息转换为Embedding。
基于Embedding进行模型构建,GL封装了多个built-in的模型,包括:
• GraphSAGE
• GCN
• GAT
• DeepWalk
• TransE
• ...
在GL中运行以上模型,只需要一键执行python脚本。比如我们要执行一个二部图的GraphSAGE算法,样例数据已经准备好了,在examples/data目录下,运行脚本就可以得到数据,模型训练可直接调用如下脚本。
cd examples/tf/bipartite_graphsage
python train_unsupervised.py
我们也将模型进行了抽象,包括Layers、Aggregators的复用,以赋予开发者和用户快速开发更多GNNs模型的能力。GNNs是近年来图数据分析与应用的热点研究问题,学术届和工业界都在不断提出新的模型,我们也将继续探索,不断完善模型,并提升大规模下的性能。
总结
GL的接口设计致力为不同需求的用户提供dive into GNNs的入口,从图语义的角度提供简单、高效的算子,为用户快速实现和调试GNNs算法提供端到端的解决方式,详细的API手册见:https://github.com/alibaba/graph-learn/blob/master/docs/concept_api.md。
GL上的GNNs模型正在快速发展迭代,我们也将把更多在阿里的大规模业务上经过验证的GNNs模型开源出来,欢迎大家加入到GL的共建中。
项目地址:https://github.com/alibaba/graph-learn
本文作者:沈雯婷