dataframe/numpy Databricks 的深度学习管道中的数组转换:可扩展性问题?
dataframe/numpy array conversion in Databricks ' Deep Learning Pipelines: scalability issue?
Databricks 的深度学习管道是一个带有 Python API 的 Spark 包,旨在在 Spark 上启用从 Tensorflow/Keras 到 运行 的深度学习模型,并采用 DataFrame
作为输入。
这听起来很酷,因为这可以在分布式数据集上以分布式方式 运行 图像识别(特别是),从而确保可扩展性。
然而,在 Github 上阅读 sparkdl
包(深度学习管道的 Python 库)的代码后,我观察到一些事情让我质疑其可扩展性整个事情可能是。
首先,sparkdl
使用图像文件夹(需要分类)作为输入并将其加载到 Spark DataFrame
。
然后,为了在这些图像上训练深度学习模型,sparkdl
的 "fit" 方法执行以下操作。
- 它将
DataFrame
转换为 4D numpy
数组 (#dataset_size,
Height, Width, #channel) 使用 Spark 的 collect() 方法
DataFrames
。因此,在这个阶段,整个数据都存储在
驱动节点。
- 使用 Spark 的
broadcast()
函数将这个 4D numpy
数组广播到每个工作节点。
- 使用广播数组作为输入执行实际训练(例如通过 Keras 中的
model.fit()
)。
我了解上述过程确保以分布式方式完成训练,因为每个节点都使用本地数据。
但是使用 collect 将 DataFrame
(请注意,它包含您的所有数据)转换为 numpy
数组会使内存成为瓶颈(不仅在驱动程序节点,而且在每个工作节点)。
所以最后,我们无法处理超过单台机器可以处理的数据集。我们可能在训练阶段获得速度提升,但我们无法利用 Spark 的主要优势(即处理 "big" 数据,本质上需要分布式存储)。
Databricks 有非常聪明的人在这个项目上工作了几个月,所以我想这一定比我想象的要多。
我怀疑这种 numpy
转换发生的主要原因是 Keras 模型通常将多维数组作为输入,而 DataFrames
最多只能存储一维数组。
我不是 Spark 和分布式计算方面的专家,所以我正在找人告诉我我是否遗漏了什么and/or 如果我完全错了。
感谢您的阅读。首先post这里,如果我可以改进这个,请告诉我。
您似乎在描述 KerasImageFileEstimator
and in that case your observation is correct and it is indeed limited to datasets, that can be stored in local memory. The purpose of this Estimator
is not to distribute over the data, but to distribute over a setparameters 并为单个数据集创建多个模型。这些可以稍后用于创建集成模型或用于超参数调整。本质上,Spark 在这里用作美化的任务队列。
它的行为类似于 Databricks 的其他工具,例如 spark-sklearn
or methods from other packages, like Distributed Keras。
但是,此行为并不适用于 spark-deep-learning
提供的所有工具。例如 DeepImagePredictor
使用 Python udfs
对数据进行分布式处理。
Databricks 的深度学习管道是一个带有 Python API 的 Spark 包,旨在在 Spark 上启用从 Tensorflow/Keras 到 运行 的深度学习模型,并采用 DataFrame
作为输入。
这听起来很酷,因为这可以在分布式数据集上以分布式方式 运行 图像识别(特别是),从而确保可扩展性。
然而,在 Github 上阅读 sparkdl
包(深度学习管道的 Python 库)的代码后,我观察到一些事情让我质疑其可扩展性整个事情可能是。
首先,sparkdl
使用图像文件夹(需要分类)作为输入并将其加载到 Spark DataFrame
。
然后,为了在这些图像上训练深度学习模型,sparkdl
的 "fit" 方法执行以下操作。
- 它将
DataFrame
转换为 4Dnumpy
数组 (#dataset_size, Height, Width, #channel) 使用 Spark 的 collect() 方法DataFrames
。因此,在这个阶段,整个数据都存储在 驱动节点。 - 使用 Spark 的
broadcast()
函数将这个 4Dnumpy
数组广播到每个工作节点。 - 使用广播数组作为输入执行实际训练(例如通过 Keras 中的
model.fit()
)。
我了解上述过程确保以分布式方式完成训练,因为每个节点都使用本地数据。
但是使用 collect 将 DataFrame
(请注意,它包含您的所有数据)转换为 numpy
数组会使内存成为瓶颈(不仅在驱动程序节点,而且在每个工作节点)。
所以最后,我们无法处理超过单台机器可以处理的数据集。我们可能在训练阶段获得速度提升,但我们无法利用 Spark 的主要优势(即处理 "big" 数据,本质上需要分布式存储)。
Databricks 有非常聪明的人在这个项目上工作了几个月,所以我想这一定比我想象的要多。
我怀疑这种 numpy
转换发生的主要原因是 Keras 模型通常将多维数组作为输入,而 DataFrames
最多只能存储一维数组。
我不是 Spark 和分布式计算方面的专家,所以我正在找人告诉我我是否遗漏了什么and/or 如果我完全错了。
感谢您的阅读。首先post这里,如果我可以改进这个,请告诉我。
您似乎在描述 KerasImageFileEstimator
and in that case your observation is correct and it is indeed limited to datasets, that can be stored in local memory. The purpose of this Estimator
is not to distribute over the data, but to distribute over a setparameters 并为单个数据集创建多个模型。这些可以稍后用于创建集成模型或用于超参数调整。本质上,Spark 在这里用作美化的任务队列。
它的行为类似于 Databricks 的其他工具,例如 spark-sklearn
or methods from other packages, like Distributed Keras。
但是,此行为并不适用于 spark-deep-learning
提供的所有工具。例如 DeepImagePredictor
使用 Python udfs
对数据进行分布式处理。