dask和dask.distributed

时间:2019-06-26 18:43:54

标签: python dask dask-distributed dask-delayed

我正在尝试使用dask.delayed计算一个较大的矩阵,以便在以后的计算中使用。我只在单个本地计算机上运行代码。当我使用dask单机调度程序时,它可以正常工作,但速度有些慢。要访问更多选项和性能监视器以改善代码,我想在一台计算机上使用dask.distributed。但是,使用dask.distributed客户端运行相同的代码会慢慢耗尽所有可用内存,并且崩溃而无法实现任何目标。

是否存在另一种解决问题的方法,该问题将使dask.distributed客户端以更好的内存效率完成工作?

  • 我仔细阅读了dask.delayed Best Practices guide,并认为我们使用的是正确的。
  • 我已经在本地Win 10 PC(64 GB RAM)和Azure Win Server 2012 VM(256 GB)上运行了它,
  • 我尝试过手动设置块。
  • 我尝试使用stack.rechunk优化块大小,包括按行和列自动分块(在dask调度程序中,行的块似乎运行得更快)。
  • 我尝试使用compute()persist()(结果相同)。
  • 我尝试使用线程和进程调度程序来启动dask.distributed客户端,并调整工作程序的数量。 threads在死亡之前会更快地使用更多RAM。
  • 我已尝试根据此answer设置dask.distributed的内存限制为cluster = distributed.LocalCluster(memory_limit = 8e9),但是忽略了内存限制。
  • 如果我减小问题的大小(下面的nXnY),dask.distributed客户端会完成任务,但是与{{ 1}}调度程序。

此示例重现了问题:

dask

实际上,我的问题要大得多,import dask import distributed import numpy as np import dask.array as da def calcRow(X,Y): Tx = np.transpose(X * (X + Y)) # Simplified work return (Tx) # Specify size of (nY x nX) matrix nX = 1000000 # Distributed fails with nX >= 1000000 and nY >= 5000 nY = 5000 # Fill with random data x = np.random.rand(nX,1) y = np.random.rand(nY,1) # Setup dask.distributed client. # Comment out these two lines to use the standard dask scheduler, # which does work client = distributed.Client() client # Build the matrix row = dask.delayed(calcRow, pure=True) # Build 1 row makeRows = [row(x, y[ii]) for ii in range(nY)] # Loop for all nY rows buildMat = [da.from_delayed(makeRow, dtype=float, shape=(10,nX)) for makeRow in makeRows] # Build matrix stack = da.vstack(buildMat) my_matrix = stack.compute() # Calculate the matrix entries 本身是一个大型,缓慢,复杂的计算,但是形状和矩阵构建步骤是相同的​​。

我了解最佳实践是在调用calcRow之前将数据scatter存入内存,但是我没有分散功能,只是一个compute数组。

如果我注释掉2条delayed客户端行,则上面的示例在60秒内使用最大0.25 GB的RAM运行。但是插入这些行之后,代码将在3-4分钟内达到完全使用内存(64GB)的水平,并且一​​直持续到系统变得不稳定为止。

如果我在dask.distributed中构建矩阵,则可以启动dask客户端,并在以后的dask.distributed计算中使用该矩阵没有问题。它只是建立引起问题的矩阵。

我几乎觉得这是一个错误,但是不能确定我的代码不应该受到指责。我真的很重视可以使代码运行或证明错误的建议。

编辑1: 我还尝试将装饰器应用于dask.distributed

calcRow

并使用:

@dask.delayed
def calcRow(X,Y):

但这似乎是相同的吗?

编辑2: 如果我以makeRows = [calcRow(x, y[ii]) for ii in range(nY)] 开始distributed.client,它将更快地消耗所有系统内存,但实际上会提供以下警告,这可能是诊断性的:

  

distributed.worker-警告-内存使用率很高,但是worker没有数据   存储到磁盘。也许其他进程正在泄漏内存?处理   内存:40.27 GB-工作者内存限制:8.00 GB

0 个答案:

没有答案