如何避免任务图中的大对象

2024-04-24 04:39:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用达斯克。分布式. 我的模型是在一个延迟函数中定义的,我堆叠了几个实现。 下面的代码片段给出了我所做工作的简化版本:

import numpy as np
import xarray as xr
import dask.array as da
import dask
from dask.distributed import Client
from itertools import repeat 

@dask.delayed
def run_model(n_time,a,b):
    result = np.array([a*np.random.randn(n_time)+b])
    return result

client = Client()

# Parameters
n_sims = 10000
n_time = 100
a_vals = np.random.randn(n_sims)
b_vals = np.random.randn(n_sims)
output_file = 'out.nc'

# Run simulations
out = da.stack([da.from_delayed(run_model(n_time,a,b),(1,n_time,),np.float64) for a,b in zip(a_vals, b_vals)])

# Store output in a dataframe
ds = xr.Dataset({'var1': (['realization', 'time'], out[:,0,:])},
             coords={'realization': np.arange(n_sims),
                     'time': np.arange(n_time)*.1})

# Save to a netcdf file -> at this point, computations will be carried out
ds.to_netcdf(output_file)

如果我想运行大量模拟,我会收到以下警告:

^{pr2}$

据我所知(根据thisthis问题),警告提出的方法有助于将大数据放入函数中。但是,我的输入都是标量值,所以它们不应该占用近3MB的内存。即使函数run_model()根本不接受任何参数(因此没有传递任何参数),我也会收到相同的警告。在

我还查看了任务图,以确定是否存在需要加载大量数据的步骤。对于三个实现,它看起来是这样的: Task graph of the code

所以在我看来,每一个实现都是分开处理的,这样就可以减少要处理的数据量。在

我想了解产生一个大物体的步骤是什么,以及我需要做些什么来将它分解成更小的部分。在


Tags: 函数runfromimportmodeltimeasnp
1条回答
网友
1楼 · 发布于 2024-04-24 04:39:27

在这种情况下,这个信息有点误导。具体表现为:

> len(out[:, 0, :].dask)
40000
> out[:, 0, :].npartitions
10000

该图的pickle大小(其头部是消息中的getitem键)是~3MB。通过为计算的每个元素创建一个dask数组,最终得到一个与元素一样多的分区的堆栈数组,模型运行操作、项目选择以及存储操作将应用于每个元素并存储在图形中。是的,它们是独立的,整个计算很可能会完成,但这都是非常浪费的,除非模型生成函数在每个输入标量上运行相当长的时间。在

在您的实际情况中,可能是内部数组实际上比您当前的单元素版本大,但是在对数组执行numy操作的一般情况下,在worker上创建数组(使用随机或一些加载函数)并在大小大于100MB的分区上操作是正常的。在

相关问题 更多 >