當我使用 sklearn 擬合模型時,我試圖限制 CPU 的使用數量RandomizedSearchCV,但不知何故我一直在使用所有 CPU。在Python scikit learn n_jobs的回答之后,我看到在 scikit-learn 中,我們可以使用它n_jobs來控制使用的 CPU 內核的數量。
n_jobs是一個整數,指定同時運行的作業人員的最大數量。如果給定 1,則根本不joblib使用并行性,這對除錯很有用。如果設定為 -1,則使用所有 CPU。
對于n_jobs低于 -1,(n_cpus 1 n_jobs)使用。例如n_jobs=-2,使用除一個以外的所有 CPU。
但是當設定n_jobs為 -5 時,所有 CPU 仍會繼續以 100% 運行。我查看了要使用的joblib庫Parallel和delayed. 但我所有的 CPU 仍然在繼續使用。這是我嘗試過的:
from sklearn.model_selection import RandomizedSearchCV
from joblib import Parallel,delayed
def rscv_l(model, param_grid, X_train, y_train):
rs_model = RandomizedSearchCV(model, param_grid, n_iter=10,
n_jobs=-5, verbose=2, cv=5,
scoring='r2')
rs_model.fit(X_train, y_train) # the cpu usage problem comes here
return rs_model
# Here my attempt to parallelize and set my function as iterable
results = Parallel( n_jobs = -5 )( delayed( rscv_l )( model,
param_grid,
X, y )
for X, y
in zip( [X_train],
[y_train] ) )
出了什么問題?
更新: 查看如何阻止 numpy 進行多執行緒處理?,我想我可能有一個多執行緒問題。當我檢查 numpy 配置時,我發現:
blas_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['user/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['user/include']
blas_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['user/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['user/include']
lapack_mkl_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['user/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['user/include']
lapack_opt_info:
libraries = ['mkl_rt', 'pthread']
library_dirs = ['user/lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['user/include']
但仍然提出的解決方案對我不起作用:
import os
os.environ["OMP_NUM_THREADS"] = "4" # export OMP_NUM_THREADS=4
os.environ["OPENBLAS_NUM_THREADS"] = "4" # export OPENBLAS_NUM_THREADS=4
os.environ["MKL_NUM_THREADS"] = "6" # export MKL_NUM_THREADS=6
os.environ["VECLIB_MAXIMUM_THREADS"] = "4" # export VECLIB_MAXIMUM_THREADS=4
os.environ["NUMEXPR_NUM_THREADS"] = "6" # export NUMEXPR_NUM_THREADS=6
import numpy
from sklearn.model_selection import RandomizedSearchCV
這解決了我的問題: 感謝@user3666197 的回答,我決定限制整個腳本的 cpu 數量,并簡單地使用 n_jobs 和一個正整數。這解決了我的 CPU 使用問題:
import os
n_jobs = 2 # The number of tasks to run in parallel
n_cpus = 2 # Number of CPUs assigned to this process
pid = os.getpid()
print("PID: %i" % pid)
# Control which CPUs are made available for this script
cpu_arg = ''.join([str(ci) ',' for ci in list(range(n_cpus))])[:-1]
cmd = 'taskset -cp %s %i' % (cpu_arg, pid)
print("executing command '%s' ..." % cmd)
os.system(cmd)
# hyperparameter tunning
rs_model = RandomizedSearchCV(xgb, param_grid, n_iter=10,
n_jobs=n_jobs, verbose=2, cv= n_folds,
scoring='r2')
#model fitting
rs_model.fit(X_train,y_train)
uj5u.com熱心網友回復:
問: “怎么了? ”
A :
沒有一件事我們可以說它“出錯”,代碼執行生態系統是如此的多層次,它并不像我們希望的那樣微不足道,而且有幾個(不同的,一些隱藏的)地方,配置決定有多少 CPU 核心將實際承擔整體處理負載。
情況也取決于版本和特定于配置(Scikit、Numpy、Scipy 都對所使用的數字包的各自編譯選項具有相互依賴關系和底層依賴關系)
實驗
證明 - 或 - 反駁剛剛假設的語法 (d) 效果:
給定方法中頂級n_jobs引數中負數解釋的記錄特征RandomizedSearchCV(...),提交相同的任務,但配置為明確允許(頂級)數量,n_jobs = CPU_cores_allowed_to_load并觀察實際獲得的核心數量和時間在整個處理流程中加載。
結果:
當且僅當加載了該數量的“允許” CPU 內核時,頂級呼叫確實將引數設定正確“傳播”到與處理流程一起使用的每個方法或程序
如果你的觀察證明設定沒有“遵守”,我們只能審查所有源代碼垂直的整個范圍來決定,誰應該為這種不遵守頂層的不服從負責為n_jobs. 雖然用于 CPU 內核關聯映射的 O/S 工具可能會給我們一些機會“從外部”限制使用的此類內核的數量,但也會出現一些其他不利影響(附加管理成本是對性能影響最小的) -熱管理引入的 CPU 核心“跳躍”,被關聯圖所禁止,將在當代處理器上導致越來越低的時鐘頻率(因為核心在數值密集型處理中確實很熱),從而延長了整體任務處理時間,因為系統中有“更冷”(因此更快)的 CPU 核心(那些被關聯映射阻止使用的 CPU 核心),但這些 CPU 核心與關聯映射不允許使用的 CPU 核心完全相同用于臨時放置我們的任務處理(而熱門的,
頂級呼叫可能已經設定了一個n_jobs-parameter,但是任何較低級別的組件可能已經“服從”了那個值(不知道有多少其他同時作業的對等點做了同樣的事情——就像在joblib.Parallel()和類似的建構式中所做的那樣,更不用說其他固有部署的、規避 GIL 的多執行緒庫 - 因為它們恰好缺乏任何相互協調以保持頂級集合n_jobs-ceiling )
def rscv_l( model, param_grid, X_train, y_train ):
rs_model = RandomizedSearchCV( model,
param_grid,
n_iter = 10,
n_jobs = 1, # DO NOT CANNIBALISE MORE
verbose = 2, # AS BEING RUN
cv = 5, # IN CONFLICT
scoring = 'r2'# WITH OUTER-SETTINGS
) # ----vvv----------
rs_model.fit( X_train, y_train ) # the cpu usage problem comes here
return rs_model
################################################################
#
# Here my attempt to parallelize and set my function as iterable
#
results = Parallel( n_jobs = -5 # <------------- joblib spawns that many workers
)( delayed( rscv_l ) # <---# HERE, avoid
( model, # UNCOORDINATED
param_grid, # CPU-CANNIBALISM
X, y ) # ref. above
for X, y in zip( [X_train],
[y_train] )
)
如果對更多細節感興趣
您可能還喜歡這個
“如何在 GridSearchCV(..., n_jobs = ...) 中找到最佳行程數?”
這個
“scikit-learn 如何處理......”
和
“如何找到理想數量的并行行程......”
來自
其他來源,涵蓋了這個問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/430563.html
