crackcell's dustbin home projects
首页 > 在生产环境中使用Spark模型 > 正文

在生产环境中使用Spark模型

1 前言

最近在新做的策略项目中尝试引入Spark。在离线模式使用Spark相当爽,使用基于DataFrame的新MLlib的统一pipeline,数据处理模型调优等一气呵成。但在真正准备把模型在生产环境使用的时候,遇到了一些选择。

2 应用Spark模型的几种方法

2.1 离线批量预测

serving_spark_model_offline_batch_predict.png

  • 离线完成训练,保存到本地文件
  • 预测的时候,加载模型文件,执行离线批量预测

2.2 在线预测1:重新实现线上部分

serving_spark_model_online_self_predict.png

  • 离线完成训练,将MLlib模型保存成自定义格式。例如,对于LR模型,将截距、参数向量保存到JSON文件中
  • 自己动手实现一个在线预测服务:加载模型文件,重写模型的预测部分。对于LR之类的简单模型,工作量还好。复杂一点的模型会比较棘手
  • 在人人车的实践中,我用Go实现了一个线上预测服务
  • 1使用的这种方式

2.3 在线预测2:引入通用的模型交换格式

serving_spark_model_online_generic_predict.png

  • 和上一个类似,只是诸如PMML的中间格式替代自定义格式,同时引入一个解析通用格式的预测服务
  • 利用jpmml-sparkml在离线环境中将MLlib pipeline导出PMML

格式模型

2.4 在线越策3:整合Spark运行时

serving_spark_model_online_spark_predict.png

  • 这种方法直接在预测服务使用Spark。MLlib模型的MLReader和MLWriter已经实现了模型的序列化。预测部分也是现成的,实现很简单
  • 但也有一个明显的问题,MLlib绑定了Spark运行时,但实际模型的预测部分并不需要。进而导致这种方法运行效率比较低
  • 这种方法,我也实际用了,工作量相比于用Go重写小了很多,但性能也大幅下降

3 总结

总的来看,个人感觉上面几种方法都有明显的缺陷,要么工作量大,要么效率不好。归根结底,MLlib作为算法框架跟Spark这种执行框架不应该紧耦合。比较理想的架构应该像Apache Beam倡导的那样,完全解耦,算法框架抽象出算法和模型,底层可以使用不同的执行器:离线训练可以用Spark执行器,在线预测使用本地的Java执行器。

Date: Thu Feb 23 17:43:51 2017

Author: Menglong TAN

Created: 2017-03-23 Thu 00:31

Emacs 24.5.1 (Org mode 8.2.10)

Validate

Modified theme and code from Tom Preston-Werner.