如何从 ML 库例如 PyTorch 或 Tensorflow访问 GPU 中的 Spark DataFrame 数据

问题描述

目前我正在研究 Apache Spark 3.0 与 Rapids GPU 加速的使用。在官方 spark-rapids 文档中,我遇到了 this page,其中指出:

在某些情况下,您可能希望访问 GPU 上的原始数据,最好不要复制它。一个用例是在执行特征提取后将数据导出到 ML 框架。

对我来说,这听起来好像可以将来自某些上游 Spark ETL 过程的 GPU 上已经可用的数据直接提供给 Tensorflow 或 PyTorch 等框架。如果是这种情况,我如何从这些框架中的任何一个中访问数据?如果我在这里误解了某些内容,引用的确切含义是什么?

解决方法

您引用的链接实际上只允许您访问仍位于 GPU 上的数据,但在另一个框架(如 Tensorflow 或 PyTorch)中使用该数据并不那么简单。

TL;博士;除非您明确设置了一个库来使用 RAPIDS 加速器,否则您可能希望使用 RAPIDS 运行您的 ETL,然后保存它,并启动一个新作业来使用该数据训练您的模型。

您仍然需要解决许多问题。我们已经在 XGBoost 的情况下处理过这些问题,但我们还没有尝试为 Tensorflow 或 PyTorch 解决这些问题。

最大的问题是

  1. 使数据进入正确的流程。即使数据在 GPU 上,出于安全考虑,它也与给定的用户进程相关联。 PyTorch 和 Tensorflow 通常作为 python 进程运行,而不是在运行 Spark 的同一个 JVM 中运行。这意味着数据必须发送到另一个进程。有多种方法可以做到这一点,但尝试将其作为零复制操作进行操作并非易事。
  2. 数据的格式不是 Tensorflow 或 PyTorch 想要的。 RAPID 的数据采用箭头兼容格式。 Tensorflow 和 PyTorch 具有用于从 CPU 以标准格式导入数据的 API,但可能需要做一些工作才能将数据转换为框架所需的格式,并找到一个 API 以让您直接从 GPU 中提取数据。
  3. 共享 GPU 资源。 Spark 最近才添加以支持调度 GPU。在此之前,人们只会为每个执行程序启动一个 spark 任务和一个 python 进程,以便 python 进程在进行训练或推理时将拥有整个 GPU。使用 RAPIDS 加速器,GPU 不再免费,您需要一种共享资源的方法。如果两个库都更新以使用它并且它们处于同一进程中,则 RMM 会提供其中的一些功能,但在 Pytorch 和 Tensoflow 的情况下,它们通常在 Python 进程中,因此很难弄清楚如何共享 GPU。