如何提供Spark MLlib模型的服务?

46

我正在评估用于生产ML应用程序的工具,其中之一是Spark MLlib,但我对训练后如何提供模型有一些问题?

例如,在Azure ML中,一旦训练完成,模型会被公开为Web服务,可以从任何应用程序中使用,并且在Amazon ML中也是类似的情况。

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

4个回答

27
一方面,使用Spark构建的机器学习模型无法像在Azure ML或Amazon ML中传统方式一样服务。Databricks声称可以通过其笔记本部署模型,但我还没有尝试过。
另一方面,您有三种使用模型的方法:
  • 在应用程序内实时训练,然后进行预测。这可以在Spark应用程序或笔记本中完成。
  • 训练模型并保存它(如果实现了MLWriter),然后在应用程序或笔记本中加载并运行它以针对数据。
  • 使用jpmml-spark将Spark训练的模型导出为PMML格式。PMML允许不同的统计和数据挖掘工具使用相同的语言。这样,预测解决方案可以在各种工具和应用程序之间轻松移动,而无需进行定制编码。例如从Spark ML到R。
以上是三种可能的方法。
当然,您可以考虑一个架构,在其中您拥有RESTful服务,并使用spark-jobserver等工具来训练和部署模型,但需要进行一些开发。这不是一个开箱即用的解决方案。
您还可以使用像Oryx 2这样的项目创建完整的Lambda体系结构,以训练、部署和提供模型。
不幸的是,描述上述每个解决方案都非常广泛,不适合在SO的范围内进行。

1
我会给spark-jobserver一个机会。你可以轻松地缓存模型(甚至是完整的spark管道),并快速回答与机器学习相关的查询,例如分类或查询。它还为您提供了缓存聚合表的机会,并快速返回包含此数据或其部分的JSON,以进行可视化或在另一个应用程序中进行进一步处理。 - Elmar Macek

16

一种选择是使用 MLeap 在线提供一个 Spark PipelineModel,而且不需要依赖于 Spark/SparkContext。不必使用 SparkContext 是重要的,因为它将单个记录的评分时间从约 100 毫秒降至一位数微秒

要使用它,您必须:

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

MLeap 与 Spark MLlib 中所有可用的 Pipeline Stages 都很好地集成在一起(写作时除了 LDA 外)。但是,如果您正在使用自定义 Estimators/Transformers,则可能会变得更加复杂。

有关自定义 Transformer/Estimator、性能和集成的更多信息,请查看 MLeap FAQ


MLeap的功能列表看起来像Spark ML管道中缺失的拼图。然而,当我尝试序列化一个包含“Imputer”的简单pyspark ML管道时,我未能使其工作。所有示例都显示各种转换器,这些转换器对我也有效,但可悲的是,“Imputer”似乎不受支持 :( - botchniaque

4
您正在比较两种非常不同的东西。Apache Spark是一个计算引擎,而您提到的Amazon和Microsoft解决方案则提供服务。这些服务也可能在幕后使用MLlib与Spark。它们可以帮助您避免自己构建Web服务的麻烦,但需要额外支付费用。
许多公司,如Domino Data Lab、Cloudera或IBM,都提供可以部署在自己的Spark集群上并轻松构建模型服务的产品(具有各种灵活性)。
当然,您也可以使用各种开源工具自己构建服务。具体来说,取决于您的目标。用户应该如何与模型交互?是否需要一些UI或只是REST API?您需要更改模型本身或模型的某些参数吗?作业是批处理还是实时处理?您当然可以构建全能解决方案,但这将需要巨大的努力。
我个人的建议是,如果可以的话,请利用Amazon、Google、Microsoft或其他可用的服务。需要本地部署?请检查Domino Data Lab,他们的产品成熟且允许轻松地使用模型(从构建到部署)。Cloudera更专注于集群计算(包括Spark),但他们还需要一段时间才能成熟。

[编辑] 我建议查看Apache PredictionIO,这是一个开源的机器学习服务器 - 一个非常棒且具有很大潜力的项目。


0

我已经成功让它工作了。注意事项:Python 3.6+使用Spark ML API(不是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的评估答案,这可以使过程运行得更快,但我仍然想特别回答这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接