Home Blogs Readings Notes Jupyter Seafile

详解pyspark以及添加xgboost支持

16 Jun 2018

随着数据累积的不断增长,单机已经不能满足建模的性能需求。而xgb作为一个非常常用的模型,在spark支持上目前对java和scala的支持较好,但是没有pyspark的支持。鉴于使用成本,需要对pyspark进行调整和扩展支持xgb。

Table of Contents

1 技术难点

2 pyspark架构相关材料

pyspark的实现总体来说是用py4j作为中间层将数据以二进制的方式在scala进程和python进程之间进行数据交换,在python进程内进行python函数的加工逻辑,在原始的spark框架内对二进制的数据进行RDD级别的操作。其主要流程如下:

官方的架构图如下:

3 关于性能的考量

pyspark的性能损失主要在数据的序列化上,但是性能损失是否严重有待探讨。所以对性能提升主要可以从两个方面着手:

综合看到的材料来说,pyspark其实性能相较于java版来说并无明显降低。可以酌情优化。

4 XGB中pyspark支持

首先不得不说的是官方的对python支持的重要性认识严重不足,这个是造成xgboost的pyspark不能很好支持的主要原因。其实通过现有封装代码的阅读,我们可以发现,其实对java版xgb的封装成本是非常小的。接下来就针对性的说下pyspark对算法部分的封装方法。

首先通览下pyspark相关源码目录下的代码结构。主要有以下文件:

haiy@~/spark-1.6.1/python/pyspark$ ls
__init__.py         join.py             sql/
accumulators.py     ml/                 statcounter.py
broadcast.py        mllib/              status.py
cloudpickle.py      profiler.py         storagelevel.py
conf.py             rdd.py              streaming/
context.py          rddsampler.py       tests.py
daemon.py           resultiterable.py   traceback_utils.py
files.py            serializers.py      worker.py
heapq3.py           shell.py
java_gateway.py     shuffle.py

简单来说整个源码目录下的文件可以分为两类:

那么接下来从哪儿开始呢?分三步即可,

4.1 认识py4j

py4j,’A Bridge between Python and Java’。其slogan简洁明了。话不多说,show me code。按照教程来,详细的代码参照这个:

4.2 pyspark中的代码封装流程

4.3 pysparkWithXGBoost支持

5 pyspark模型上线

上面讲了pyspark和xgb的训练过程,那么对于企业场景来说,仅仅考虑这些还是不够的,我们还要考虑这个玩意怎么上线?比较navie的方式是直接用pyspark 来导出pipeline model,然后serving。经过评测,这种方式实际的预测耗时在100ms~。对于一些要求较高的场景不够的。那么该如何解决呢?

前面我们大概知道了spark中的pipeline是如何加载模型的,那么在scala源码中其加载方式其实也是一致的。

那么耗时的地方在哪儿呢?从模型的预测流程来说,我们首先要创建sparkContext,然后将数据转换成spark能够支持的数据结构DataFrame,dense Vector, 预测后数据还要转成单机的传统数据结构,通常以json形式输出。而在模型预测里真正对我们有用的关键信息是model的参数信息。

所以如果需要优化的话那么根本的优化点是将数据环境从分布式转换成单机的,也就是剔掉对sparkContext的依赖,将预测的数据结构直接做成单机的。

spark官方的砖厂已经做了这个支持。开源方案内比较好用的是mleap,其文档中的性能对比测试已经做到微秒级还是很promising的。

Refs

pyspark参考资料

pyspark性能对比参考资料

XGB项目中pyspark支持相关

pyspark模型上线相关

xgb on yarn

gpu xgb

需要搞清楚的是为什么GPU可以加速,基于GPU的xgb提速还是非常明显的

不靠谱的xgb on yarn分布式

TASK_DIR=`pwd`
git clone --recursive https://github.com/dmlc/xgboost
git checkout v0.60
mkdir xgboost-package
cp -r xgboost xgboost-packages/
wget "http://ftp.gnu.org/gnu/gcc/gcc-4.8.2/gcc-4.8.2.tar.bz2"
tar -jxvf gcc-4.8.2.tar.bz2
cd gcc-4.8.2
mkdir ./contrib/download_prerequisites
cd ..
mkdir gcc-build-4.8.2
cd  gcc-build-4.8.2
../gcc-4.8.2/configure --enable-checking=release --enable-languages=c,c++ --disable-multilib --prefix=$TASK_DIR

make -j10
make install
export PATH=$TASK_DIR/bin:$PATH
cp -r $TASK_DIR/lib64 $TASK_DIR/xgboost-packages

wget "https://cmake.org/files/v3.5/cmake-3.5.2.tar.gz"
tar -zxf cmake-3.5.2.tar.gz
cd cmake-3.5.2
./bootstrap --prefix=${TASK_DIR}
gmake
make -j10
make install
-->
Fork me on GitHub