配置 Dask-Jobqueue

要在 HPC 系统上正确使用 Dask 和 Dask-Jobqueue,您需要提供一些关于该系统以及您计划如何使用它的信息。

您可以通过构造函数的关键字参数提供此信息

cluster = PBSCluster(cores=36, memory='100GB', queue='regular', ...)

或者作为配置文件的一部分

jobqueue:
  pbs:
    cores: 36
    memory: 100GB
    queue: regular
    ...
cluster = PBSCluster()

有关处理配置文件的更多信息,请参阅 Dask 配置文档

本页解释了这些参数的含义以及如何查找关于它们的信息。

核心数和内存

这些数字对应于单个作业的大小,通常是您集群中单个节点的大小。它不代表您希望用于整个部署的核心数或内存总量。请记住,dask-jobqueue 在正常操作中会启动多个作业。

核心数应提供为整数,而内存通常提供为字符串,例如“100 GB”。

cores: 36
memory: 100GB

千兆字节 vs 二进位千兆字节

Dask 区分 GB(千兆字节)和 GiB(二进位千兆字节)

  • 1GB = \(10^9\) 字节

  • 1GiB = \(2^{30} = 1024^{3}\) 字节 \(\approx 1.074\) GB

memory 配置由 Dask 内存解析器解释,并且对于大多数 JobQueueCluster 实现,它会被翻译为作业提交的资源需求。但大多数作业调度程序(至少 PBS 和 Slurm 是这种情况)使用 KB 或 GB,但实际表示 KiB 或 GiB。Dask jobqueue 考虑到了这一点,因此在查询作业排队系统时,您可能找不到您预期的内存量。举个例子,对于 PBSCluster,如果您指定 memory='20GB',最终在 PBS 端会请求 19GB。这是因为 20GB \(\approx\) 18.6GiB,并向上取整。

通过在 dask-jobqueue 配置中始终使用“GiB”可以避免这种情况。

进程数

默认情况下,Dask 会根据 cores 的值尝试将一个作业划分为多个进程。如果 cores 小于或等于 4,则进程数将等于 cores 值。否则,进程数将至少为 sqrt(cores),其余为线程,以保持 cores = processes * threads。您可以使用 processes 配置值控制进程数。如果您的计算受 GIL 限制,使用进程可能有利,但如果您计划在进程之间进行大量通信,则不利。通常我们发现,对于纯粹的 Numpy 工作负载,少量进程(例如一个)是最好的,而对于纯粹的 Python 工作负载,大量进程(例如每两个核心一个进程)是最好的。如果您不确定,不妨稍作实验,或者选择一个适中的数量,例如每四个核心一个进程。

cores: 36
memory: 100GB
processes: 9

队列

许多 HPC 系统有各种不同的队列,您可以向其提交作业。这些队列通常有诸如“regular”(常规)、“debug”(调试)和“priority”(优先级)等名称。这些是由您的集群管理员设置的,用于根据作业的大小和紧急程度来引导某些作业。

queue: regular

如果您不熟悉在系统上使用队列,则应将其留空,或咨询您的 IT 管理员。

项目或账户

您在 HPC 系统上可能有一个分配,通过*项目*或*账户*来引用。这通常是一小段文本,引用您的组或特定项目。通常是您的 IT 管理员在分配您在 HPC 系统上的小时数时提供给您的。

project: XYZW-1234
#account: XYZW-1234

如果这听起来对您陌生,或者您不使用项目或账户代码,则应将其留空,或咨询您的 IT 管理员。

本地存储

当 Dask worker 内存不足时,通常会开始将数据写入磁盘。这在个人计算机或分析集群上通常是一个明智的选择,但在缺乏本地存储的 HPC 系统上可能不明智。当 Dask worker 尝试在缺乏本地存储的系统上将多余数据写入磁盘时,可能导致 Dask 进程以意想不到的方式终止。

如果您的节点在某处挂载了快速的本地连接存储,则应指示 dask-jobqueue 使用该位置。

local-directory: /scratch

有时,您的作业调度程序会以环境变量的形式提供此位置。如果是这样,您应该包含该环境变量,并在其前面加上 $ 符号,作业启动后它将得到适当的展开。

local-directory: $LOCAL_STORAGE

无本地存储

如果您的节点没有本地连接存储,我们建议您关闭 Dask 将多余数据写入磁盘的策略。这必须在配置文件中完成,并且必须与 jobqueue 配置部分分开(尽管将其包含在同一文件中也可以)。

jobqueue:
  pbs:
    cores: 36
    memory: 100GB
    ...

distributed:
  worker:
    memory:
      target: False    # Avoid spilling to disk
      spill: False     # Avoid spilling to disk
      pause: .80       # Pause worker threads at 80% use
      terminate: 0.95  # Restart workers at 95% use

网络接口

HPC 系统通常拥有先进的网络硬件,如 Infiniband。Dask worker 可以利用基于 Infiniband 的 TCP 网络,这可以在数据传输期间提高带宽。要获得更高的速度,通常需要指定加速硬件的网络接口。如果您有足够的权限,可以使用 ifconfig UNIX 命令查找所有网络接口的列表。

$ ifconfig
lo          Link encap:Local Loopback                       # Localhost
            inet addr:127.0.0.1  Mask:255.0.0.0
            inet6 addr: ::1/128 Scope:Host
eth0        Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:XX   # Ethernet
            inet addr:192.168.0.101
            ...
ib0         Link encap:Infiniband                           # Fast InfiniBand
            inet addr:172.42.0.101

注意:在某些集群上,ifconfig 可能需要 root 权限。您可以改用这段 python 代码来列出所有网络接口:

import psutil
psutil.net_if_addrs()

或者,您的 IT 管理员会拥有这些信息。

管理配置文件

默认情况下,当 dask-jobqueue 首次被导入时,会在 ~/.config/dask/jobqueue.yaml 放置一个文件,其中包含许多不同作业调度程序的注释掉的版本。您可能需要做几件事来清理它:

  1. 移除所有不适用于您的注释掉的部分。例如,如果您只使用 PBS,则考虑删除 SGE、SLURM 等下面的条目。

  2. 您可以随意重命名文件,或在文件中包含 Dask 其他部分的配置选项。jobqueue.yaml 文件名并非特殊,Dask 的每个组件有自己的配置文件也不是特殊之处。您可以根据您的团队需求合并或拆分配置文件。

  3. 请您的 IT 管理员在 /etc/dask 中放置一个通用文件供全局使用。Dask 将首先在 /etc/dask 中查找 .yaml 文件,然后在其查找,优先使用用户主目录中的文件而不是 /etc/dask 中的文件。通过提供一个全局文件,IT 应该能够为同一系统上的每个人提供合理的设置。