我正在尝试使用dask.delayed
计算一个较大的矩阵,以便在以后的计算中使用。我只在单个本地计算机上运行代码。当我使用dask
单机调度程序时,它可以正常工作,但速度有些慢。要访问更多选项和性能监视器以改善代码,我想在一台计算机上使用dask.distributed
。但是,使用dask.distributed
客户端运行相同的代码会慢慢耗尽所有可用内存,并且崩溃而无法实现任何目标。
是否存在另一种解决问题的方法,该问题将使dask.distributed
客户端以更好的内存效率完成工作?
stack.rechunk
优化块大小,包括按行和列自动分块(在dask
调度程序中,行的块似乎运行得更快)。compute()
和persist()
(结果相同)。dask.distributed
客户端,并调整工作程序的数量。 threads
在死亡之前会更快地使用更多RAM。dask.distributed
的内存限制为cluster = distributed.LocalCluster(memory_limit = 8e9)
,但是忽略了内存限制。nX
和nY
),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