节点嵌入训练加快300倍:开源高性能图嵌入系统GraphVite技术解读

2019 年 8 月 11 日

节点嵌入训练加快300倍:开源高性能图嵌入系统GraphVite技术解读


GraphVite是一个专为高速、大规模的训练场景设计的通用图嵌入系统,已于本周正式开源。该系统旨在提供一个包含一系列图嵌入方法的通用高性能框架,进一步推动图学习算法的研究与发展。GraphVite支持多GPU并行,可以扩展到百万级甚至十亿级的图,在百万节点的图上,只需要约一分钟就能完成节点表示的学习。GraphVite由唐建教授带领的MilaGraph团队开发,相关论文已发表于WWW19会议。本文是AI前线第88篇论文导读,我们将对GraphVite及其技术实现进行具体介绍。



GraphVite 总览


目前,GraphVite 已为 3 种应用提供了完整的训练和评价框架,包括节点嵌入、知识图谱嵌入以及图和高维数据可视化。此外,它还包含了 9 种流行的模型以及这些模型在一系列标准数据集上的基准测试结果。


GitHub 项目入口:https://github.com/DeepGraphLearning/graphvite


GraphVite现支持的三种任务


GraphVite 现支持的三种任务


为了展示 GaphVite 的速度,MilaGraph 提供了在三种应用上最好的开源实现与 GraphVite 的训练速度报告,报告基于 24 个 CPU 线程以及 4 个 Tesla V100GPU 的硬件系统。在 Youtube 数据集上,节点嵌入任务的训练速度如下:


Youtube数据集上节点嵌入任务训练时间


Youtube 数据集上节点嵌入任务训练时间


在 FB15k 数据库上实现的知识图谱任务报告如下:



在 MNIST 数据集上实现的高维数据可视化任务报告如下:



可以看出在以上三个任务中,相较于目前最好的开源实现,GraphVite 最多可以提升 300 多倍的速度。并且,在提高了速度的同时,GraphVite 没有任何性能上的牺牲,这点可以从该项目提供的基准测试报告中发现。在使用与上述速度报告相同硬件的情况下,GraphVite 的说明文档中还提供了使用 GraphVite 实现的所有模型的基准测试结果。在节点嵌入任务上,作者在 Youtube、Flicke 和 Friendster-small 三个数据集上提供了每个模型的 micro-F1 和 macro-F1 指标。


Youtube数据集上三种不同模型的结果报告


Youtube 数据集上三种不同模型的结果报告


在知识图谱嵌入任务上,作者对 TransE、DistMult、ComplE、SimplE 和 RotatE 四种方法进行了测试。


Youtube数据集上五种不同模型的结果报告


Youtube 数据集上五种不同模型的结果报告


作者在两个流行的数据集上对图及高维数据可视化任务进行了测试。LargeVis 所需的训练时间和资源如下表所示。请注意,超过 95%的 GPU 内存成本来自 KNN Graph 的构建,并且可以在必要时与速度进行权衡。


在MNIST和ImageNet数据集上LargeVis的测试结果


在 MNIST 和 ImageNet 数据集上 LargeVis 的测试结果


其中,MNIST 数据集上 3D 可视化结果如下:



与类似的工作 Pytorch-BigGraph 相比,GraphVite 速度更快,测试结果如下:



同时,GraphVite 还比前者多了节点嵌入以及可视化两个功能,为研究和开发提供了更多的便利。


理解 GraphVite


GraphVite 为什么可以这么快?这是因为 GraphVite 根据 CPU 和 GPU 各自的优势,解决了混合节点嵌入系统的三大挑战。


混合节点嵌入系统的难点主要包含:1)基于 mini-batch 的 SGD 方法无法直接用关于大型网络上的节点嵌入,2)由于 GPU 与 CPU 总线带宽的差异,在 CPU 与 GPU 之间的数据转送会成为系统瓶颈,3) 多 CPU 与 GPU 设备间的同步成本巨大。


GraphVite 使用了并行在线增广方法在 CPU 上有效地扩充网络规模。同时使用了并行负采样方法对多 GPU 的嵌入训练进行协调。GraphVite 还使用了一种协作策略来降低 CPU 和 GPU 之间的同步成本。


GraphVite系统结构图,灰色及黄色部分分别表示并行数据增广过程与嵌入训练过程。


GraphVite 系统结构图,灰色及黄色部分分别表示并行数据增广过程与嵌入训练过程。


并行在线增广


对于节点嵌入方法,其第一阶段需要使用随机遍历来扩充原始网络。由于增广网络通常比原始网络要大一到两个数量级,因此,如果原始网络已经非常大,则其网络结构将很难被加载到主存储器中。GraphVite 采用了并行在线增广,可以在不显示网络增强的情况下生成增广的边样本。


作者首先绘制一个出发节点(depature node),其选择概率与每个节点的度成正比。然后从出发节点开始执行随机游走,并在特定的增广距离 s 内挑选节点对产生边样本。由于随机游走中生成边样本具有相关性,因此训练效果可能会变差。作者受到强化学习中广泛使用的经验回放方法的启发,收集边样本到样本池,并在对它混洗(shuffle)后再转发到 GPU 进行嵌入训练。当每个线程预先分配有独立的样池时,上述方法可以并行化处理。算法 2 给出了并行在线增广的详细过程:



为了更好的训练效果,对样本池进行混洗非常重要,但同时它也会减慢网络增广的速度。原因是普通的洗牌方法包含大量随机内存访问,并且不能由 CPU 缓存加速。如果服务器有多个 CPU 插槽,速度损失将更加严重。为了缓解这个问题,作者提出了一种伪混洗技术,它以更加缓存友好的方式对相关样本进行洗牌,并显着提高系统的速度。


并行负采样


在嵌入训练阶段,作者将训练任务分为多个子任务并将它们分配给多个 GPU 设备。子任务必须设计成具有很少的共享数据的形式以最小化 GPU 之间的同步成本。为了了解如何将模型参数分配给多个 GPU 而不重叠,作者首先介绍了ε-梯度可交换的概念:



其中,作者将 0-梯度可交换称为梯度可交换。由于节点嵌入训练过程的稀疏性质,在网络中会存在很多形成梯度可交换对的集合。例如,对于两个边缘样本集例如,对于两个边缘样本集 X1,X2⊆E,如果它们不共享任何源节点或目标节点,则 X1 和 X2 是梯度可交换的。即使 X1 和 X2 共享一些节点,如果学习率α和迭代次数有界,它们仍然可以是ε-梯度可交换的。



基于节点嵌入中观察到的梯度交换性,作者提出了一种用于嵌入训练阶段的并行负采样算法。对于 n 个 GPU,我们将顶点和上下文行分别划分为 n 个分区(上图的左上角)。这导致样本池的 n×n 分区网格,其中每个边缘属于其中一个块。这样,任何不共享行或列的块都是可梯度交换的。只要限制每个块上的迭代次数,同一行或列中的块都是ε-梯度可交换的。


作者将集(episode)定义为并行负抽样中使用的块级步骤。在每一集中,我们分别向 n 个 GPU 发送 n 个正交块及其对应的顶点和上下文分区。然后,每个 GPU 使用 ASGD 更新自己的嵌入分区。因为这些块是相互梯度可交换的并且不共享参数矩阵中的任何行,所以多个 GPU 可以在没有任何同步的情况下同时执行 ASGD。在每集结束时,我们从所有 GPU 收集更新的参数并分配另外 n 个正交块。这里ε-梯度可交换由 n 个正交块中的总样本数控制,我们将其定义为集的大小。较小的集有利于ε-梯度可交换嵌入式训练。但是同时也会导致更频繁的同步。因此作者调整了集的大小,以便在速度和ε-梯度可交换之间有一个很好的权衡。上图给出了具有 4 个分区的并行负采样的示例。


虽然作者使用等于 n 的分区数量来说明了负采样的有效性,但是并行负采样可以很容易地推广到任何数量大于 n 的分区的情况,只需在每集中处理 n 个子组中的正交块。算法 3 给出了用于多个 GPU 的混合系统的并行负采样算法的详细步骤:



协作策略


我们的并行负采样使不同的 GPU 能够同时训练节点嵌入,只需要在集之间进行同步。但是,应该注意到,样本池也在 CPU 和 GPU 之间共享。如果它们在样本池上同步,则只有同一阶段的设备可以同时访问样本池,这意味着硬件在一半时间内处于空闲状态。为了提高效率,作者提出了一种协作策略来降低同步成本。


作者主存储器中分配两个样本池,让 CPU 和 GPU 始终在不同的样本池上工作。 CPU 首先填充样本池并将其传递给 GPU。之后,并行在线增广和并行负采样分别在 CPU 和 GPU 上执行。当 CPU 填满新的样本池时,将交换这两个池。通过协作策略,CPU 和 GPU 之间的同步成本降低,混合系统的速度几乎翻倍。


实验


作者使用了 Youtube、Reiendster-small、Hyperlink-PLD 和 Friendster 四个数据库对 GraphVite 的性能进行了测试。部分实验结果已在第一章中展示,详细的实验结果在论文原文以及 GraphVite官方网站https://graphvite.io/)的 Docs 中都有详细的展示。


快速入门


GraphVite 可以在 CUDA>=9.2 的 Linux 系统上运行,兼容 Python2.7 和 Python3.5/3.6/3.7 版本。GraphVite 对待新手十分友好,它提供了关于节点嵌入任务的快速入门示例供用户学习。用户可以选择通过 Conda 源进行安装或使用源码编译,使用 Conda 安装仅需在命令行输入命令:


conda install -c milagraph graphvite
复制代码


如果仅需要嵌入训练而不要测试部分,还可以选择更加轻量级的最小化 GraphVite 系统:


conda install -c milagraph graphvite-mini
复制代码


或者用户也可以选择使用源码编译:


git clone https://github.com/DeepGraphLearning/graphvitecd graphviteconda install -y --file conda/requirements.txtmkdir buildcd build && cmake .. && make && cd -cd python && python setup.py install && cd -
复制代码


安装完成 GraphVite 后,直接执行即可查看示例,在终端输入:


conda install -c milagraph graphvite-mini
复制代码


示例需要运行约一分多钟的时间,然后会输出结果:


Batch id: 6000loss = 0.371641
macro-F1@20%: 0.236794micro-F1@20%: 0.388110
复制代码


2019 年 8 月 11 日 14:002132

评论

发布
暂无评论
发现更多内容

Java语言变量的命名规范

倔强的攻城狮

Java

架构师训练营第 1 期 - 第三周作业提交

Todd-Lee

极客大学架构师训练营

发展区块链技术 打造竞争新优势

CECBC区块链专委会

面试官:开发过Maven插件吗?我:开发过啊。。。

冰河

maven 插件开发 互联网工程

组合模式及单例模式

garlic

极客大学架构师训练营

PHP 7:真实世界的应用开发(中文翻译)

GanymedeNil

php

编程的本质和未来

小宋头

第三周 代码重构学习总结

钟杰

极客大学架构师训练营

Week 3 总结

黄立

设计模式

架构师训练营第 1 期第三周课后练习题

Leo乐

极客大学架构师训练营

架构师训练营第三周作业

xs-geek

极客大学架构师训练营

架构师训练营第三周总结

xs-geek

极客大学架构师训练营

架构师训练营-week03-总结

大刘

极客大学架构师训练营

第三周 代码重构作业

钟杰

极客大学架构师训练营

Week 3 作业1

黄立

CSS 选择器 — 重学CSS

三钻

CSS 前端 前端进阶

架构师训练营第三周作业

Shunyi

极客大学架构师训练营

第三周作业

华美而火锅

Apache Pulsar 9月月报:正在快速成长的下一代分布式消息流平台

Apache Pulsar

大数据 开源 云原生 Apache Pulsar 消息中间件

硬核测试:Pulsar 与 Kafka 在金融场景下的性能分析

Apache Pulsar

大数据 开源 云原生 Apache Pulsar 消息中间件

第三周-代码重构-作业

刘希文

SQL 是什么

Rayjun

sql

组合设计模式编写程序

石头

极客大学 极客大学架构师训练营

好好吃个饭吧,今天想吃什么?你说了算。

叶小鍵

布莱恩·万辛克 减肥、廋身 好好吃饭

刘华:公有云不仅是自建机房的替代品

刘华Kenneth

架构 DevOps 敏捷 弹性

央行数字货币渐行渐近:未来金融竞争终极场所

CECBC区块链专委会

数字货币 银行

2020.09.28-2020.10.04 学习总结

icydolphin

极客大学架构师训练营

3.手写单例模式设计

博古通今小虾米

架构师训练营第 1 期 - 第三周总结

Todd-Lee

极客大学架构师训练营

区块链治理为什么如此重要?

CECBC区块链专委会

区块链

架构师训练营第 1 期第三周总结

Leo乐

极客大学架构师训练营

节点嵌入训练加快300倍:开源高性能图嵌入系统GraphVite技术解读-InfoQ