如何提供Spark MLlib模型?

时间:2016-11-10 17:24:27

标签: apache-spark machine-learning apache-spark-mllib

我正在评估基于生产ML的应用程序的工具,我们的一个选项是Spark MLlib,但是我有一些关于如何在训练后提供模型的问题?

例如,在Azure ML中,一旦经过培训,该模型将作为Web服务公开,可以从任何应用程序中使用,这与Amazon ML类似。

如何在Apache Spark中提供/部署ML模型?

4 个答案:

答案 0 :(得分:17)

一方面,使用spark构建的机器学习模型无法以传统方式在Azure ML或Amazon ML中提供服务。

Databricks声称能够使用它的笔记本部署模型,但我还没有尝试过。

另一方面,您可以通过三种方式使用模型:

  • 在应用程序内动态训练然后应用预测。这可以在火花应用程序或笔记本中完成。
  • 训练模型并保存,如果它实现MLWriter然后加载应用程序或笔记本并根据您的数据运行它。
  • 使用Spark训练模型并使用jpmml-spark将其导出为PMML格式。 PMML允许不同的统计和数据挖掘工具使用相同的语言。通过这种方式,可以在工具和应用程序之间轻松移动预测解决方案,而无需自定义编码。例如从Spark ML到R.

这是三种可能的方式。

当然,你可以想到一个架构,你可以在其中使用RESTful服务,你可以使用spark-jobserver来构建每个示例来训练和部署,但需要一些开发。它不是一个开箱即用的解决方案。

您也可以使用像Oryx 2这样的项目来创建完整的lambda架构来训练,部署和提供模型。

不幸的是,描述上述每个解决方案都是相当广泛的,并不适合SO的范围。

答案 1 :(得分:7)

一种选择是使用MLeap在线提供Spark PipelineModel,不依赖于Spark / SparkContext 。不必使用SparkContext很重要,因为它会将单个记录的评分时间从~100ms减少到一位数微秒

要使用它,您必须:

  • 使用MLeap实用程序序列化Spark模型
  • 在MLeap中加载模型(不需要SparkContext或任何Spark依赖项)
  • 使用JSON(非DataFrame)创建输入记录
  • 使用MLeap为您的记录打分

MLeap与Spark MLlib中提供的所有管道阶段(在撰写本文时除了LDA之外)很好地集成在一起。但是,如果您使用自定义Estimators / Transformers,事情可能会变得更复杂。

有关自定义变换器/估算器,性能和集成的详细信息,请查看MLeap FAQ

答案 2 :(得分:2)

你正在比较两个相当不同的东西。 Apache Spark是一个计算引擎,虽然您提到亚马逊和Microsoft解决方案正在提供服务。这些服务也可能在场景背后有Spark和MLlib。它们可以帮助您免于自己构建Web服务的麻烦,但是您需要额外付费。

Domino Data Lab,Cloudera或IBM等公司提供的产品可以在您自己的Spark群集上部署,并可以轻松地在您的模型周围构建服务(具有不同程度的灵活性)。

当然,您可以使用各种开源工具自行构建服务。具体哪个?这一切都取决于你所追求的。用户应该如何与模型交互?是否应该有某种UI或jest REST API?您是否需要更改模型或模型本身的某些参数?这些工作更多是批量还是实时性质?您可以自然地构建一体化解决方案,但这将是一项巨大的努力。

我个人的建议是,如果可以,可以利用亚马逊,谷歌,微软或其他任何可用的服务。需要内部部署吗?检查Domino Data Lab,他们的产品已经成熟,可以轻松使用模型(从构建到部署)。 Cloudera更专注于集群计算(包括Spark),但在成熟之前需要一段时间。

[编辑]我建议您查看Apache PredictionIO开源机器学习服务器 - 这个有很多潜力的惊人项目。

答案 3 :(得分:0)

我已经能够使它起作用。注意事项:使用Spark ML API的Python 3.6 +(不是MLLIB,但请确保其工作方式相同)

基本上,请按照MSFT's AzureML github中提供的示例进行操作。

警告词:将按原样提供代码,但是示例run()方法的末尾有错误:

        #Get each scored result
        preds = [str(x['prediction']) for x in predictions]
        result = ",".join(preds)
        # you can return any data type as long as it is JSON-serializable
        return result.tolist()

应该是:

        #Get each scored result
        preds = [str(x['prediction']) for x in predictions]
        #result = ",".join(preds)
        # you can return any data type as long as it is JSON-serializable
        output = dict()
        output['predictions'] = preds
        return json.dumps(output)

也完全同意MLeap评估答案,这可以使流程运行得更快,但我想我会专门回答这个问题