本文是对《GraphVite: A High-Performance CPU-GPU Hybrid System for Node Embedding》一文的浅显翻译与理解,如有侵权即刻删除。
朋友们,我们在github创建了一个图学习笔记库,总结了相关文章的论文、代码和我个人的中文笔记,能够帮助大家更加便捷地找到对应论文,欢迎star~
Chinese-Reading-Notes-of-Graph-Learning
更多相关文章,请移步:文献阅读总结:网络表示学习/图学习
Title
《GraphVite: A High-Performance CPU-GPU Hybrid System for Node Embedding》
——WWW2019
Author: Zhaocheng Zhu
总结
文章提出了一种加速现有算法在CPU和GPU上运行效率的框架GraphVite,框架主要包含三个部分:在CPU上的网络结构扩展;在GPU上的训练和负采样;将两者结合起来的策略。
对常见算法而言,模型可以分为两个阶段,即网络扩展阶段和嵌入训练阶段,简略算法如下:
算法中第一阶段是比较容易实现并行化的,第二阶段可以通过异步随机梯度下降实现并行化。在绝大多数现行节点嵌入模型中,两阶段按照顺序执行,每个阶段由一系列CPU线程并行化。
由于在GPU上训练神经网络的成功,文章试想借助GPU来进行节点嵌入的学习,提出了CPU-GPU的混合式模型。但对于大规模的数据集,会对主存造成极大负担,而且从CPU将参数转化进GPU也会面临较高难度。因为GPU的计算速度要远大于管道传输数据的速度,因此整体效率会受到管道速度的限制,那么这种混合式系统甚至还要差于完全在CPU上的并行。此外,混合式系统有着巨大的同步损耗,因为系统分布在多个CPU和GPU上,这需要子任务间数据的共享。一个传统的做法是频繁共享数据,这会导致大的同步损耗,因此需要一种策略来最小化设备间的损耗。
因而,针对上述问题,文章提出了GraphVite模型,大致框架如下。
1 并行网络扩展
节点嵌入算法使用随机游走对网络拓扑结构进行扩展,由于扩展后的结构比原结构要大一到两个数量级,因此难以将其加载进主存中。因此文章提出并行扩展,即在没有显式网络扩展的情况下即时生成扩展的边缘样本。
首先绘制一个出发节点,其概率与每个节点的度成正比。其次从出发节点执行随机游走,注意到在相似随机游走中采样的边之间存在联系,可能会降低优化性能,算法将边采样到一个样本池中,并在转移到GPU进行嵌入训练之前乱序化。当每个线程预先分配有独立的样本池时,就可以并行处理对边的采样,算法如下。
伪随机:随机样本池对优化而言是很重要的,但通用的随机包含了大量的随机存储器访问,并且不能被CPU缓存加速,当使用多个CPU时,这种负面影响甚至比一个更大。为解决该问题,文章提出伪随机技术,即以更易于缓存的方式对相关样本进行随机。注意到许多具有联系的边都共享了源节点或目标节点,当这种联系出现在数量为s的一组样本中时,文章将样本池划分为s个区块,从而将有关联的样本分散到不同区块中,最终对CPU缓存起到了很大帮助。
2 并行负采样
在嵌入训练阶段,文章将训练任务拆分并分配给多个GPU,子任务必须设计为几乎没有共享数据,以最大程度地减少GPU之间的同步成本。
在此,首先引入对ε梯度可互换的定义。
定义即如果交换两个梯度下降步骤的阶数导致矢量差的范数不超过ε,即可认为函数L是ε梯度可互换的。具体来说,如果两条边没有共享任何源节点或目标节点,那么它们是完全梯度可互换的。即便它们共享了一些节点,如果学习率和交互数量有所限制,那么它们依然可以是ε梯度可互换的。
文章提出了并行负采样的方法,对n个GPU,方法将源节点和目标节点分别分割为n个部分,从而得到了n*n的矩阵作为样本池,m每条边属于其中的一个区块。通过这种方法,任何没有共享行或列的区块都是完全梯度可互换的,共享同一行或同一列的,则为ε梯度可互换的。
文章定义episode作为区块步,每个episode,都输送n个正交区块及其源节点目标节点到n个GPU中去,每个GPU更新各自的嵌入,由于梯度可互换性,它们之间并不共享任何参数矩阵,从而可以不需要任何同步地执行ASGD。每个episode的最终,会将更新过的参数汇总,并分配新的n个区块给GPU。
文章将控制ε梯度可互换性的n个区块样本总数称为episode size,size越小,可互换性越好,但小的size会使得同步更为密集,因此需要调整为合适的值,下图给出了具体的并行负采样流程。
对GPU1的第一次取样,源节点为1,目标节点为1,则负采样节点即矩阵中(1,1)对应的区块内容,而对比四个GPU看,可以发现,在同一时间,每个GPU的取样有策略地错开了相同的行列,这就保证了GPU之间没有需要共享的信息,下图为并行负采样算法。
3 协作策略
需要注意,样本池在CPU和GPU之间是共享的,如果它们同步样本池,同一时间就只有处于相同状态的指令可以访问样本池,这意味着设备大半时间是空闲的。为解决该问题,文章提出协作策略来减少同步性损耗。文章分配两个样本池在主存中,令CPU和GPU总是工作在不同的样本池上,从而使得网络扩展和并行负采样也能够同时进行。
4 讨论
Batched Transfer:在负采样过程中,样本池按区块分配给GPU,有时对GPU的显存而言比较大。代替将整个样本区块复制给GPU,文章通过较小的粒度输送样本区块,这种情况下损耗可以忽略不计。
Bus Usage Optimization:当切分数量与GPU数量一致时,系统可以通过固定每个GPU切分数量的方法,进一步优化总线利用率。
Single GPU Case:对单个GPU,系统同样适用,最大能够达到一千二百万的节点嵌入训练。