【发布时间】:2022-07-08 15:18:26
【问题描述】:
对于上下文,我正在尝试在频谱图列表上使用动态时间扭曲计算成对距离矩阵。所有声音文件都有不同的长度(时间步长),但在开始之前我知道它们的大小。该脚本按顺序运行良好,但计算时间太长,因此我尝试将其与 joblib 并行化。
假设我用 np.float32 类型的数组列表来表示它们(我将把所有代码放在下面的最小示例中)。 作为替代,我将定义 dtw 函数来创建一个随机矩阵并返回最后一个单元格(行和列)中的值。我使用 numba 对其进行了优化,因此它运行得相当快。
import numpy as np
from joblib import Parallel, delayed
# Number of samples
n = 20000
# Generate
x = [np.random.uniform(size=(n, 40)) for n in np.random.randint(low=50, high=500, size=n)]
# Placeholder function
def fake_dtw(a, b):
mat = np.random.uniform(size=(len(a), len(b)))
return mat[-1, -1]
# Code to compute pairwise distance
batch_size = 1000
pre_dispatch = 2 * batch_size
with Parallel(n_jobs=-1, batch_size=batch_size, pre_dispatch=pre_dispatch) as p:
results = p(
delayed(
lambda i, j, a, b: (i, j, fake_dtw(a, b))
)(i, j, x[i], x[j])
for i in range(1, len(x))
for j in range(i)
)
dtw_matrix = np.zeros(shape=(len(x), len(x)))
for i, j, res in results:
dtw_matrix[i, j] = res
dtw_matrix[j, i] = res
我已经阅读了documentation 以及这个问题What batch_size and pre_dispatch in joblib exactly mean。所以我知道 batch_size 和 pre_dispatch 是如何工作的,但我想不出一种方法来计算适当的值以获得最佳性能。
我的问题如下:给定
- 列表中所有项目的大小(我可以在启动前计算)
- 操作数(在本例中为 4 亿,因为它是 20000 个样本中的所有对)
- CPU 数量(我一次最多可以启动 48 个工作器)
- 我电脑的 RAM (64 GB)
有没有办法让我选择
batch_size和pre_dispatch以便尽可能快地计算运算?
在一个大约是我当前数据集大小 1/4 的数据集上,我能够使用 pre_dispatch='all' 和 batch_size=(number of operations)/os.cpu_count() 侥幸逃脱,因此所有数据在运行前会立即分发,但如果我尝试使用它会崩溃当前数据集(我认为这是由于内存使用造成的)。我尝试了更多值,但我想知道是否有更原则性的方法来执行此操作,而不是暴力破解并查看有效的方法。
提前谢谢你!
【问题讨论】:
标签: python parallel-processing joblib