并行代码如果先运行则会挂起,但如果在运行非并行代码后运行则会起作用

时间:2014-05-29 22:19:51

标签: python parallel-processing scikit-learn

所以这听起来有点复杂,但我最近遇到了joblib的问题,它会创建一堆进程然后挂起来(也就是说,每个进程占用内存,但不占用CPU时间)

以下是我能够重现问题的最简单的代码:

from sklearn import linear_model
import numpy as np
from sklearn import cross_validation as cval
from joblib import Parallel, delayed

def fit_hanging_model(n=10000, nx=10, ny=32, ndelay=10,
                       n_cvs=5, n_jobs=None):
    # Create data
    X = np.random.randn(n, ny*ndelay)
    y = np.random.randn(n, nx)

    # Create model + CV
    model = linear_model.Ridge(alpha=1000.)
    cvest = cval.KFold(n, n_folds=n_cvs, shuffle=True)

    # Fit model
    par = Parallel(n_jobs=n_jobs, verbose=10)
    parfunc = delayed(_fit_model_cvs)
    par(parfunc(X, y, train, test, model)
                      for i, (train, test) in enumerate(cvest))

def _fit_model_cvs(X, Y, train, test, model):
    model.fit(X, Y)  

n = 10
a = np.random.randn(n, 32) 
b = np.random.randn(32, 10)

##########
c = np.dot(a, b)
##########

fit_hanging_model(n_jobs=3)

以下是发生的事情:

  • 如果我运行上面的所有代码,那么它会产生三个进程并挂起
  • 如果我运行上面的所有代码,但使用n_jobs = 1,那么它可以正常工作
  • 如果我再次运行上面的所有代码,在使用n_jobs = 1运行一次后,无论我使用多少个工作,它都能正常工作。
  • 如果我为######之间的代码运行EXCEPT以上的所有代码,那么它运行正常。
  • 但是,如果我然后在######之间运行代码,并尝试使用n_jobs>运行fit_hanging_model; 1,然后它挂起

这是使用joblib = 0.8.0,并且sklearn 0.15-git。

注意,这个bug是在Linux上的CentOS上。我无法在另一台机器上重现此错误,因此可能很难重现。

有没有人知道为什么会这样?看起来这个点产品做的很奇怪,但我不知道它可能是什么......我在绳子的尽头......

2 个答案:

答案 0 :(得分:4)

想出来。显然,这是Joblib创建多个python进程的问题,而MKL同时尝试进行线程处理。请在此处查看问题和解决方案(涉及设置环境变量):

https://github.com/joblib/joblib/issues/138

答案 1 :(得分:0)

根据我的经验,joblib在它调用的函数进行另一级并行化时挂起。

在@choldgraf的答案中使用解决方案,您需要通过MKL禁用内部并行化级别:

import os
os.environ['MKL_NUM_THREADS'] = '1'
os.environ['OMP_NUM_THREADS'] = '1'
os.environ['MKL_DYNAMIC'] = 'FALSE'

这适用于其他并行计算库,例如OpenMP