跨 Spark 执行器安装 Python 包 - 未找到 python 包,引发 ModuleNotFoundError

问题描述 投票:0回答:1

我有一个关于使用 Databricks 和 Mlflow 在 Spark 工作节点上安装新包的正确方法的问题。

我目前拥有的有以下:

  1. 一个训练脚本(使用 cv2,即 opencv2-python 库),它将调整后的 ML 模型及其依赖项记录在 mlflow 模型注册表中
  2. 一个推理脚本,它读取记录的 ML 模型以及保存的 conda 环境,作为 Spark_udf
  3. 安装步骤,通过 pip install(包装在 subprocess.call 中)读取 conda 环境并将所有软件包安装到所需版本
  4. 然后是对新数据调用 Spark_udf 的实际预测。

最后一步失败并出现 ModuleNotFoundError。

SparkException: Job aborted due to stage failure: Task 8 in stage 95.0 
failed 4 times, most recent failure: Lost task 8.3 in stage 95.0 (TID 577 
(xxx.xxx.xxx.xxx executor 0): org.apache.spark.api.python.PythonException: 
'ModuleNotFoundError: No module named 'cv2''

我一直在密切关注这篇文章的内容,它似乎涵盖了同样的问题:

  • “此类问题的一个主要原因是使用 udfs。有时 udfs 不会分发到集群工作节点。”
  • “udfs 或主 Spark 程序中使用的相应依赖模块可能会丢失或无法从集群工作节点中访问。”

所以目前看来,尽管使用 Spark_udf 和 conda 环境记录到 mlflow,但 cv2 模块的安装仅发生在我的驱动程序节点上,而不是工作节点上。如果这是真的,我现在需要以编程方式向执行程序/工作节点指定这些额外的依赖项(即 cv2 Python 模块)。

所以我所做的是,在我的推理脚本中导入 cv2,并检索 cv2 的 init 文件的路径,并将其添加到 Spark 上下文中,类似于博客中任意“A.py”文件的操作方式上面发帖了。

import cv2
spark.sparkContext.addFile(os.path.abspath(cv2.__file__))

但这似乎并没有带来任何改变。我认为部分原因是我想添加的不仅仅是一个

__init__.py
文件,而是让工作节点可以访问整个 cv2 库;然而,上述解决方案似乎只适用于
__init__.py
。我确信在 cv2 的所有子模块中添加所有文件也不是可行的方法,但我无法弄清楚如何使用与上面的
addFile()
类似的命令轻松实现这一点。

类似地,我还尝试了另一个选项,

addPyFile()
,将其指向 cv2 模块的根(
__init__
的父级):

import cv2
spark.sparkContext.addPyFile(os.path.dirname(cv2.__file__))

但这也没有帮助,我仍然遇到同样的错误。此外,我希望这个过程是自动的,即不必在推理代码中手动设置模块路径。

我遇到的类似帖子:

  • 在 pyspark 中运行 spacy,但出现 ModuleNotFoundError: No module named 'spacy',这里唯一的答案建议“重新启动 Spark 会话”——但不确定在我的具体情况下这意味着什么,有一个活动的 Databricks 笔记本和一个正在运行的集群。
  • PySpark Worker on rdd.collect()中的ModuleNotFoundError,这里的答案指出“您不允许从执行器任务访问spark上下文”,这可能解释了为什么我上面的两种方法都失败了(
    addFile
    addPyFile
    )。但如果这是不允许的,那么正确的解决方法是什么?
  • PySpark:ModuleNotFoundError:没有名为“app”的模块,这里有一个信息丰富的答案,指出“您的Python代码在驱动程序上运行,但您的udf在执行器PVM上运行。(...)在两个驱动程序中使用相同的环境和执行者。”,但确实不清楚如何在笔记本内部以编程方式执行此操作。
python apache-spark databricks distributed-computing azure-databricks
1个回答
0
投票

我在我的项目中遇到了同样的问题,我的代码需要所有执行器节点中而不是头节点中的一些特定包。对于 DBX(Databricks)来说,这是一个非常棘手的问题。

DBX 中的虚拟环境功能是作为笔记本范围实现的,这意味着无论您想为该笔记本使用什么包,您都应该安装 它位于笔记本的开头。但关于集群的 LTS 版本有一个问题:

Databricks Runtime

11.3
LTS 及更高版本:
%pip
%sh pip
!pip
安装库

Databricks 运行时

10.4
LTS:
%pip
安装库

Databricks Runtime

9.1
LTS:您必须将其单独安装在集群上,或者制作一个轮子并安装轮子。这种情况是最麻烦的情况,我强烈建议升级到11.3及以上版本才能拥有该功能。

您可以了解更多

[here][1]

© www.soinside.com 2019 - 2024. All rights reserved.