gpt4 book ai didi

python - 当有更多任务时,许多分布式任务 worker 在一次评估后闲置,或者从未收到任何工作

转载 作者:行者123 更新时间:2023-11-28 18:01:20 25 4
gpt4 key购买 nike

我们正在使用 dask 来优化深度学习器 (DL) 架构,方法是生成设计,然后将它们发送给 dask worker,而 dask worker 又使用 pytorch 进行训练。我们观察到一些工作人员似乎没有开始,而那些完成评估 DL 的工作人员不会立即开始评估下一个等待的 DL。

我们已经在橡树岭国家实验室的 Summit super 计算机上实现了这一点。对于我们的原型(prototype),我们提交了一个分配 92 个节点的批处理作业,启动了一个 dask 调度程序和 92 个 dask worker,每个节点都有一个 worker。每个节点有 6 个 Nvidia Volta V100、两个 IBM Power9 和 512 GB DDR4 + 96GB HMB@ 内存。然后,每个工作人员使用 pytorch 来训练深度学习,并将其验证准确性作为“适应度”返回。但是,如果提出的 DL 架构不可行,则会抛出异常,并且相关的适应度变为 -MAXINT。

在只有两名工作人员的初始试运行中,我们注意到,如果一名工作人员评估了一个格式错误的 DL 设计,它将立即被分配一个新的 DL 进行评估。直到运行结束,这两个 worker 中的任何一个都没有闲着。

这是实际代码的精简版。

from dask.distributed import Client, as_completed

client = Client(scheduler_file=’scheduler.json’)

# posed_dl_designs is a list of random DL architectures,
# eval_dl is the entry point for the pytorch training
worker_futures = client.map(eval_dl, posed_dl_designs)

for res in as_completed(worker_futures):
evaluated_dl = res.result()

# pool is Queue of evaluated DLs sorted by validation
# accuracy; so update_pool() replaces the least accurate DL
# with the newly evaluated DL
update_pool(evaluated_dl, pool)

# Let the workers drain down if we meet some kind of budget
# for generated DL designs; otherwise generate a new DL and
# give it to a worker for training/evaluation
if not stop():

# create_new_dl() selects one of the better DLs from
# the pool, clones it, and alters it slightly, thereby
# creating a new DL design
new_dl = create_new_dl(pool)

# Now evaluate/train the new DL
new_future = client.submit(eval_dl, new_dl)
iterator.add(new_future)

这就是我们调用调度程序和工作程序的方式:

# The scheduler doesn't need GPUs. It just needs one lonely core to run on.
jsrun --gpu_per_rs 0 --nrs 1 --tasks_per_rs 1 --cpu_per_rs 1 --rs_per_host 1 dask-scheduler --interface ib0 --no-bokeh --no-show --scheduler-file $SCHEDULER_FILE &

# Spin up an individual task for each worker. Since dask does not use MPI, specify smpiargs none.
for i in {0..91}; do

jsrun --smpiargs="none" --nrs 1 -e individual --stdio_stdout ${RUN_DIR}/worker_out.%h.%j.%t.%p --stdio_stderr ${RUN_DIR}/worker_error.%h.%j.%t.%p --tasks_per_rs 1 --cpu_per_rs 14 --gpu_per_rs 6 --rs_per_host 1 dask-worker --nthreads 1 --nprocs 1 --memory-limit 512e9 --interface ib0 --no-bokeh --reconnect --scheduler-file $SCHEDULER_FILE --resources "MEM=512e9" &

done

# Invocation for the controller process elided

当我们将运行规模扩大到雇用 92 名 worker 时,我们发现几分钟后只有 5 或 6 名 worker 在运行——这些 worker 对应于拥有可行的 DL 作为他们的第一个 DL 设计候选人进行培训的 worker 。

闲置 worker 分为两类。大多数闲置 worker 显然已经评估了一个损坏的 DL 设计,并忠实地返回了适当的特殊值,表明;但随后从未将新的 DL 重新分配给那个现在自由的 worker 。另一类 worker 从未评估过任何 DL,以下代表他们的输出:

distributed.nanny - INFO -         Start Nanny at: 'tcp://10.41.18.55:45941'
distributed.diskutils - INFO - Found stale lock file and directory '/gpfs/alpine/csc342/proj-shared/may/delemera_first_trial_run/worker-c4o0rsb3', purging
distributed.worker - INFO - Start worker at: tcp://10.41.18.55:44107
distributed.worker - INFO - Listening to: tcp://10.41.18.55:44107
distributed.worker - INFO - nanny at: 10.41.18.55:45941
distributed.worker - INFO - Waiting to connect to: tcp://10.41.18.54:8786
distributed.worker - INFO - -------------------------------------------------
distributed.worker - INFO - Threads: 1
distributed.worker - INFO - Memory: 512.00 GB
distributed.worker - INFO - Local Directory: /gpfs/alpine/csc342/proj-shared/may/delemera_first_trial_run/worker-kqf62513
distributed.worker - INFO - -------------------------------------------------
distributed.worker - INFO - Registered to: tcp://10.41.18.54:8786
distributed.worker - INFO - -------------------------------------------------
distributed.core - INFO - Starting established connection

因此,对于那些闲置的工作人员,在与调度程序建立通信时存在问题。我们没有注意到任何其他可能相关的消息。

最佳答案

事实证明,问题不在于 dask,而在于我们调用代码的方式。

也就是说,我们的顶级脚本中有一个运行时参数,它规定了发送给工作人员的初始人口规模。如果未指定,我们的原始实现将使用默认值,并且在我们的作业提交脚本中,我们省略了相应的命令行参数,这意味着默认值 5 用于初始人口的大小。

如上面的代码片段所述,我们配置设置的方式是,无论分配的工作人员数量或更新个体池的大小如何,初始人口规模都会决定向前移动数量实际忙碌的 worker 。也就是说,由于我们使用了默认值 5,因此这些是调度程序首先处理的任务。然后,当每个工作人员评估一个 DL 时,它将被添加到池中,另一个工作人员将被分配一个新的 DL 进行评估。 (并且不一定是刚刚完成评估最新 DL 的同一个工作人员,这是最初造成混淆的根源。)永远不可能将更多工作分配给剩余的闲置工作人员。

我们现在删除了此参数的默认值,以强制用户为每次运行指定此关键信息。

一些类(class)包括:

  • 为命令行参数提供默认值可能会变得无声且难以找到错误源
  • 花时间为运行时参数添加完整性检查(例如,如果初始种群大小小于池大小,代码现在会报错并失败)
  • 不要假设这是依赖包的错误;错误可能出在你自己的代码中
  • 磁盘空间很便宜,因此真正打开日志记录以获得适当且有用的诊断信息
  • 进行多次、部分运行以观察病态行为模式(例如,我们注意到,无论工作人员的数量和评估的 DL 池的大小如何,只有五个工作人员曾经忙碌过)

关于python - 当有更多任务时,许多分布式任务 worker 在一次评估后闲置,或者从未收到任何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55545196/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com