在读xgboost源代码的时候,debug的代码是单机版本,同时xgboost也有分布式版本,而xgboost的分布式版本是就分布式通信框架rabit的。下图是基于rabit进行求和(图片来源xgboost导读和实战):

rabit-sum

上图中共有7个运算单元,每个单元存储一个数据,在进行求和时,首先构建一个树型结构可以用来提高节点之间的通信效率。root节点做最终的求和运算,计算完成后将最终结果分发给其余计算节点,便于容错处理。该框架主要用于计算属性候选分割点

相比rabit,对于我们的比赛代码的分布式改进相对容易,下图是我们的结构设计:

tianchi

在上述结构设计中,我们设计一个管理节点,负责分发任务和收集计算结果。分发任务是按照商家ID进行的,不涉及商家特征生成数据的拷贝。收集的结果是每个计算节点上的训练误差。为了便于进行试验,我们在代码测试阶段使用20个商家,一个管理节点,两个计算节点。具体代码如下:

计算节点代码:

管理节点代码:

阅读上述代码,任务队列中共有4个任务,以商家ID来表示,故结果队列也应该有4个任务结果。由于我们实验中使用两个计算节点,故每个计算节点完成两个任务,当计算节点完成任务之后,将结果(训练误差)放入共享结果队列就好。对于管理节点和计算节点,管理节点负责分发任务和收集结果,而计算节点负责具体运算。对比可以体现出“瘦管理,胖计算”的特点。

由于是实验代码,故没有做参数返回检查之类的工作,假设程序能够正常运转。首先,在可扩展性方面,当我们的计算节点增加之后,计算节点的代码要进行修改,故没有良好的扩展性。其次,在某个计算节点中途宕掉,比如我强行KILL掉,容错能力怎样呢?再者,共享队列的通信方式,目前是存储有限个浮点类型数据,当数据量大的时候,通信效率如何?当然,我们的设计不需要考虑计算节点之间的通信。

参考文章:分布式进程