如何为 n_jobs 产生的 scikit-learn 并行进程设置较低的优先级?

问题描述 投票:0回答:1

当使用 n_jobs 参数并行化 scikit-learn 例程(如 GridSeachCV)时,有没有办法将并行进程设置为低于正常优先级?

我通常希望最大限度地利用并行化,同时仍然允许并行使用我的机器执行常规计算任务。我使用的是 Windows;打开任务管理器手动将 n_jobs=-1 的每个生成进程的优先级设置为低于正常水平,效果很好,但非常乏味。

将 n_jobs 设置为小于可用的 CPU 线程或内核并不是一个令人满意的解决方案,因为我的机器对常规任务的响应速度很慢,除非我保留至少两个物理 CPU 内核(例如,在 8 核 16 核上,n_jobs=6线程 CPU),这使得许多线程未得到充分利用,我希望当我不同时使用我的机器时使用所有线程。

我找到了这个答案关于使用 psutil.Process() 类降低子进程的进程优先级的问题。

以下代码大部分有效:

import psutil

# parallel processing for GridSearchCV.fit()
current_process = psutil.Process()
original_priority = current_process.nice()
current_process.nice(psutil.BELOW_NORMAL_PRIORITY_CLASS)  # set parent priority
grid_search.fit(X, y)
current_process.nice(original_priority)  # reset parent priority

这是运行上述代码的示例数据集和模型:

from sklearn.datasets import load_digits
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV

# sample dataset
dataset = load_digits()
X, y = dataset.data, dataset.target

# sample model
rf_model = RandomForestClassifier(n_jobs=-1)
param_grid = {'max_depth': [x for x in range(5, 20)], 
              'min_samples_split': [x for x in range(2, 10)]}
grid_search = GridSearchCV(rf_model, param_grid, n_jobs=-1)

此代码通常允许 grid_search.fit() 以低于正常优先级成功生成其并行进程,但并非总是如此。有时,只有某些进程的优先级低于正常优先级,而大多数进程都是正常的,并且无论出于何种原因,我都无法始终如一地重现该行为。另外,我不确定将父进程设置为低于正常优先级(例如与 Jupyter Lab 会话交互或停止内核)会产生什么后果。

这是为 n_jobs 产生的 scikit-learn 并行进程设置较低优先级的正确方法吗?关于并行性的 scikit-learn 文档 表明 n_jobs 参数使用 joblib 作为其底层实现,但我在这组文档中没有看到任何有关进程优先级的内容。

scikit-learn parallel-processing joblib psutil
1个回答
0
投票

我能做的最好的事情就是将 psutil 代码放入上下文管理器中:

import psutil
from contextlib import contextmanager
@contextmanager
def lower_process_priority():
    current_process = psutil.Process()
    original_priority = current_process.nice()
    try:
        current_process.nice(psutil.BELOW_NORMAL_PRIORITY_CLASS)
        yield
    finally:
        current_process.nice(original_priority)

用途:

with lower_process_priority():
   grid_search.fit(X, y)

这非常有效,可以让我在 scikit-learn 在后台运行时执行常规计算任务。有些应用程序的响应比其他应用程序更好(奇怪的是,Notepad++ 几乎无法使用),但它已经足够好了。

我发现的一个怪癖是,在 Firefox 中通过 Jupyter Lab 运行此代码时,Jupyter Lab 选项卡/进程本身通常被分配低优先级,这使得 Jupyer Lab 选项卡无响应。使用任务管理器手动将适当的 Firefox 进程设置为“正常”效果很好(在 Firefox 中调用 about:processes 并在括号中找到进程 ID)。

© www.soinside.com 2019 - 2024. All rights reserved.