首页 > 解决方案 > python多处理瓶颈

问题描述

我有一个 python 代码,它最初使用 sklearn lib 来训练一个 KNN 分类器,它产生两个 python 对象:模型和矢量化器。这两个对象接下来将用于对我的数据进行分类(分类)。

接下来,我有一个非常大的数据框,其中包含以下两列(在许多其他列中):

category :此列将包含上述分类器的输出

data_path :此列是包含上述分类器输入的数据文件的路径

首先,我使用下面的 df.apply 方法来处理数据帧:

def get_classifier_result(row, model, vectorizer):
    with open(row['data_path'], "r") as f:
        my_txt = f.readlines()
    ### run the classifier and classify my_txt input here and generate category value
    row['category'] = category

df = pd.read_csv(my_df, sep='\t', header=0)
df.apply(lambda row: get_classifier_result(row, model, vectorizer), axis=1) 

这段代码花了 24 多小时在一个 56 核的强大 Linux 盒式服务器上运行。所以我尝试使用多处理来加快速度:

import multiprocessing

def get_classifier_result(row, model, vectorizer):
    with open(row['data_path'], "r") as f:
        my_txt = f.readlines()
    ### run the classifier and classify my_txt input here and generate category value
    row['category'] = category

df = pd.read_csv(my_df, sep='\t', header=0)
p = multiprocessing.Pool(int(40))
for i, row in df.iterrows():
    p.apply_async(get_classifier_result, [row, model, vectorizer])

这种方法没有任何改进。在 linux 框上显示 htop 表明所有 40 个进程都处于 S(睡眠)模式,除了一个。所以我基本上只运行一个进程,就像我在 df.apply 方法中一样。

该问题似乎与模型和矢量化对象的大小有关。如果我用较小的训练数据集训练分类器,以便模型和矢量化器对象的大小减小(假设是 20 倍),那么 htop 会显示所有 40 个进程处于就绪模式并正在运行,并且事情真的会加速。我尝试使用 Manager() 并将共享列表中的这两个对象传递给进程,但无济于事:

m = Manager()
my_list = [model,vectorizer]
my_shared_list = m.list(my_list)
for i, row in df.iterrows():
    p.apply_async(get_classifier_result, [row, my_shared_list])

我什至尝试在池中只运行 3 个进程,但结果是一样的(只有一个进程处于活动状态,而另外两个处于睡眠模式)。

为什么除了一个之外的所有进程都处于睡眠模式并等待。怎样才能知道他们在等什么?为什么将参数对象的大小减小到生成进程可以避免这个问题?

标签: pythonmultiprocessing

解决方案


推荐阅读