我需要在一个大于内存的Tensor上进行一些计算,但首先我需要从 NumPy
适合内存的阵列(部件)。
我在计算这些 NumPy
数组,然后将它们转换为 Dask
数组,并将它们放在 list
. 我的最后一个Tensor是这些数组的特殊连接。问题是,根据部分的数量,我甚至无法到达发生串联的代码行。
例如,使用形状的零件 (30, 40, 40, 40, 40)
,那么 614 MB
具有 16 GB
ram(通常为 10
免费),只是尝试计算 20
部件足够耗尽内存。
我可以看到每个新Tensor的计算是如何变慢的,以及可用ram是如何变得越来越低,直到进程被终止。如果我计算 10
零件,我可以看到我的可用零件 RAM
从 10 GB
到 5.2
. 如果我试着计算 20
部分,进程被终止。
import numpy as np
import dask.array as da
def compute_part():
array = np.random.random((30, 40, 40, 40, 40)) # 614 MB
return da.from_array(array)
def construct_tensor(nparts):
list_of_parts = []
for part in range(nparts):
part_as_da_array = compute_part()
list_of_parts.append(part_as_da_array)
# Below, the concatenation should happen
construct_tensor(20) # This is enough for the process to not finish
有没有更好地利用可用内存的方法?dask自动创建 chunks
大小 (15, 20, 20, 20, 20)
,我还尝试重新调整阵列,使每一块都更小,但我没有看到任何改进。当我使用时,我现在看到的差别很小 Dask
数组而不是 NumPy
在内存使用方面。
1条答案
按热度按时间erhoui1w1#
dask无法“减少”内存中已存在的阵列的大小。没有分块会对你有帮助。如果您的数据适合内存,那么您可能根本不需要dask。
相反,您需要在每个块中根据需要加载/创建数据。对于您的简单示例,您可以通过替换
compute_part
具有da.random.random
,它正是以这种方式懒惰的(在实际使用每个块之前不使用任何内存)。我理解随机数可能不是您的实际用例。如果这些片段确实需要先存储在内存中,那么最终可能会使用
da.from_delayed
,或者首先为每个块运行块创建步骤,写入数据存储,如支持块写入的zarr。