我们使用 Dask 在 HPC 系统上分析大型数据集。Dask 是一个并行计算库,它能很好地与现有的 Python 软件生态系统集成,并能轻松地与原生 HPC 硬件配合使用。

本文解释了为什么这种方法对我们来说是合理的。我们的动机是与同事分享经验,并强调未来工作的机会。

我们首先介绍我们使用 Dask 的六个理由,然后讨论当前影响我们的七个问题。

我们使用 Dask 的理由

1. 易用性

Dask 扩展了 Numpy、Pandas 和 Scikit-learn 等库,这些库对于科学家和工程师来说是熟知的 API。它还为多节点多进程处理提供了更简单的 API。这使得我们现有的用户群能够轻松上手。

通过将并行性从用户/开发者中抽象出来,我们的分析工具可以由非计算机科学专家编写,例如科学家自己,这意味着我们的软件工程师可以更多地扮演支持角色而非领导角色。经验表明,借助 Dask 和 Jupyter 等工具,科学家将更少的时间花在编码上,更多的时间花在思考科学问题上,这才是他们应该做的。

2. 平滑的 HPC 集成

借助 Dask JobqueueDask MPI 等工具,无需像常见的作业排队系统那样编写任何样板式的 shell 脚本代码。

Dask 可以原生地与我们现有的作业调度器(SLURM/SGE/LSF/PBS/…)交互,因此在用户和 IT 之间无需设置和管理额外的系统。我们所需的所有基础设施都已到位。

大规模交互式分析功能强大,使我们能够以新的方式利用现有基础设施。自动扩展提高了我们的占用率,并有助于获得 HPC 运营者/所有者的认可。Dask 对部分或全部工作节点失效的弹性,为将经典 HPC 工作负载与分析作业共存时利用作业抢占提供了新途径。

3. 面向科学计算

除了与 Scipy 和 PyData 软件生态系统集成外,Dask 还兼容 HDF5、NetCDF、Parquet 等科学数据格式。这是因为 Dask 与 Python 生态系统中的其他库(如 Xarray)协同工作,这些库已经对科学数据格式和处理提供了强大的支持,并且还支持 C/C++/Fortran 代码,这在 Python 库中很常见。

这种原生支持是我们认为 Dask 相较于 Apache Spark 的主要优势之一。

4. API 的多功能性

然而,Dask 并未针对任何特定工作流而设计,而是可以提供基础设施来涵盖机构内的各种不同问题。许多不同类型的工作负载都是可能的

  • 您可以轻松处理大规模的 Numpy 数组或 Pandas Dataframe,进行数值计算或数据分析/清洗,
  • 您可以处理任何对象集合,例如 JSON 文件、文本文件或日志文件,
  • 您可以使用 Dask Delayed 来表达更随意的任务或作业调度工作负载,或者使用 Dask Futures 进行实时和反应式处理。

Dask 涵盖并简化了我们多年来遇到的广泛的 HPC 工作流。许多以前使用作业数组、简化版 MPI(例如 mpi4py)或纯 bash 脚本实现的工作流,对于使用 Dask 的用户来说似乎更容易了。

5. 基础设施的多功能性

Dask 兼容笔记本电脑、服务器、HPC 系统和云计算。环境变化时只需进行少量代码调整,这减少了我们在不同系统(例如从笔记本电脑到超级计算机,或从超级计算机到云)之间迁移分析代码时重写代码的负担。

# Local machines
from dask.distributed import LocalCluster
cluster = LocalCluster()

# HPC Job Schedulers
from dask_jobqueue import SLURMCluster, PBSCluster, SGECluster, ...
cluster = SLURMCluster(queue='default', project='ABCD1234')

# Hadoop/Spark clusters
from dask_yarn import YARNCluster
cluster = YarnCluster(environment='environment.tar.gz', worker_vcores=2)

# Cloud/Kubernetes clusters
from dask_kubernetes import KubeCluster
cluster = KubeCluster(pod_spec={...})

Dask 对我们来说不仅仅是一个工具;它是一个思考如何以完全不同的方式为用户提供计算基础设施的门户。Dask 为云计算技术(如弹性扩展和对象存储)打开了大门,并促使我们重新思考 HPC 中心到底应该是什么样子。

6. 成本与协作

Dask 是免费且开源的,这意味着我们无需重新分配预算和人员来应对数据分析工具的新即时需求。我们无需支付许可费用,并且在必要时能够修改代码。HPC 社区在 Dask 开发者中拥有良好的代表性。我们很容易参与其中,我们的顾虑也得到了很好的理解。

需要改进的方面

1. 异构资源处理

通常我们希望在同一部署中包含不同类型的 HPC 节点。这包括以下情况:

  • 内存低或高的工作节点,
  • 带有 GPU 的工作节点,
  • 来自不同节点池的工作节点。

Dask 已为此类异构性提供了一些支持,但还不够。我们看到两个主要的改进机会。

  • Dask-Jobqueue 等工具应该使其更容易在同一集群中管理多个工作节点池。当前的部署解决方案假设同构性。
  • 用户应该更容易指定计算的哪些部分需要不同的硬件。目前的解决方案可行,但需要用户提供比理想情况更多的细节。

2. 粗粒度诊断和历史记录

Dask 提供了一些分析工具,可以提供任务级别的实时诊断,但目前尚无法在粗粒度级别分析或分析您的 Dask 应用程序,也没有内置方法来长时间跟踪性能。

拥有更多分析整体性能的工具,对于做出设计决策和未来的架构选择将有所帮助。

能够持久化或存储计算(compute() 调用)和调度器上执行的任务的历史记录,对于跟踪问题和潜在的性能改进非常有帮助。

3. 使用 MPI 启动批处理作业

在我们准备这篇博文时,此问题已得到解决。

HPC 用户希望在由数千个大型节点组成的集群上分析 PB 级数据集。

虽然 Dask 理论上可以处理这种规模,但它确实会有点变慢,降低了交互式大规模计算的乐趣。处理数百万个任务可能会导致计算实际开始前出现数十秒的延迟。这对于我们的 Dask 批处理作业来说完全没问题,但往往会让交互式 Jupyter 用户感到沮丧。

这种减速很大程度上是由于任务图构建时间和集中式调度造成的,这都可以通过多种方式加速。我们预计,通过一些巧妙的方法,我们可以将 Dask 持续平稳运行的规模再提高一个数量级。

在我们准备这篇博文时,这个问题已解决。

目前大多数 Dask 工作流都是交互式的。人们登录 Jupyter notebook,导入 Dask,然后 Dask 会动态地向作业调度器(如 SLURM、PBS 等)请求资源。这非常好,因为 Dask 能够利用调度中的小间隙,在不再需要工作节点时释放它们,为用户提供愉快的交互体验,同时减轻集群的负载。

然而,并非所有作业都是交互式的。科学家们通常希望提交一个大型作业,就像他们提交 MPI 作业一样。他们提交一个包含所需资源的单一作业脚本,然后离开,资源管理器会在这些资源可用时运行该作业(这可能需要几个小时)。虽然这些工作负载不如交互式工作负载新颖,但它们对于常见流程至关重要,并且是重要的支持内容。

Kevin Paul 在 NCAR 讨论这篇博文时提出了这一点。从我们开始计划到发布这篇博文期间,Kevin 已经通过提供 dask-mpi 解决了这个问题。dask-mpi 是一个项目,它可以轻松使用普通的 mpirunmpiexec 命令启动 Dask,从而使 Dask 易于部署到任何可以部署 MPI 的地方。

5. 更多数据格式支持

目前,Dask 对常用的科学数据格式(如 HDF5、Grib 和 NetCDF)以及常见的数据科学格式(如 CSV、JSON、Parquet、ORC 等)支持良好。

然而,数据格式的范围非常广泛,Dask 用户发现自己有些困难,甚至需要手动解决许多不同领域常见格式的数据摄取问题,例如:

  • 遥感数据集:GeoTIFF, Jpeg2000,
  • 天文数据:FITS, VOTable,
  • …等等

支持这些格式并不难(事实上,我们许多人已经在 Dask 中构建了自己的支持),但拥有一个高质量的集中式解决方案会非常方便。

我们许多机构都很兴奋能够利用深度学习的最新进展,并将 Keras、TensorFlow 和 PyTorch 等强大工具以及 GPU 等强大硬件集成到我们的工作流程中。

然而,我们经常发现我们的数据和架构与标准深度学习教程中的略有不同。我们喜欢使用 Dask 进行数据摄取、清洗和预处理,但希望建立更好的实践和流畅的工具,以便尽可能高效地从使用 Dask 在 HPC 上进行的科学工作流程过渡到深度学习。

更多信息,请参阅此 github issue 获取示例主题。

7. 更多计算指南

虽然有方法可以交互式地分析和诊断计算,并且有一套相当不错的 Dask 常见计算示例,但在优化大型 HPC 计算工作流之前,尝试和错误似乎是常态。

我们应该制定更多关于如何进行大规模计算的指南和策略,并且需要培养围绕 Dask 的社区,Pangeo 等项目已经在做这方面的工作。请注意,这些指南可能取决于基础设施。


博文评论由 Disqus 提供