我正在多个图像上运行管道。管道包括从文件系统读取图像,对每个图像进行处理,然后将图像保存到文件系统。但是,由于MemoryError导致达不到工作的工作程序失败。 有没有办法确保敏捷工作者不会在内存中加载太多图像?即,等到工作人员上有足够的空间后,再开始对新映像进行处理。
我有一个调度程序和40个具有4个内核,15GB内存并运行Centos7的工人。我正在尝试批量处理125张图像;每个图像都很大,但足够小以适合工人。整个过程大约需要3GB。
我尝试处理少量图像,效果很好。
已编辑
from dask.distributed import Client, LocalCluster
# LocalCluster is used to show the config of the workers on the actual cluster
client = Client(LocalCluster(n_workers=2, resources={'process': 1}))
paths = ['list', 'of', 'paths']
# Read the file data from each path
data = client.map(read, path, resources={'process': 1)
# Apply foo to the data n times
for _ in range(n):
data = client.map(foo, x, resources={'process': 1)
# Save the processed data
data.map(save, x, resources={'process': 1)
# Retrieve results
client.gather(data)
我希望图像可以在工作人员可用的空间中进行处理,但似乎图像都同时加载到不同的工作人员上。
编辑: 我的问题是所有任务都分配给工作人员,他们没有足够的内存。我发现了如何限制工作人员在单个时刻处理的任务数[此处为{https://distributed.readthedocs.io/en/latest/resources.html#resources-are-applied-separately-to-each-worker-process](see)。 但是,由于这个限制,当我执行任务时,它们都完成了读取步骤,然后是处理步骤,最后是保存步骤。这是一个问题,因为映像已溢出到磁盘上。
是否有一种方法可以使每个任务在开始新任务之前完成? 例如在Worker-1上:read(img1)-> process(img1)-> save(img1)-> read(img2)-> ...
答案 0 :(得分:0)
Dask通常不知道任务需要多少内存,它只能知道输出的大小,并且只有完成后才知道。这是因为Dask只需执行pthon函数,然后等待它完成即可。但是所有事情都会在python函数中发生。通常,您应该期望在拥有可用的工作程序核心后就开始执行尽可能多的任务。
如果您想要较小的总内存负载,那么您的解决方案应该很简单:拥有足够少的工作程序,因此,如果所有工作程序都在使用您可以期望的最大内存,那么您仍然有一些空闲空间。系统来应对。
要编辑:您可能希望在提交之前尝试在图形上运行优化(尽管我认为这应该会发生),因为听起来您的线性任务链应该“融合”。 http://docs.dask.org/en/latest/optimize.html