如何限制 python 脚本 w/o 终端或多处理库使用的 CPU 的数量?
How to limit number of CPU's used by a python script w/o terminal or multiprocessing library?
我的主要问题是发出。由于还没有人给出解决方案,我决定找到一个解决方法。我正在寻找一种方法来限制 python 脚本 CPU 的使用( 不是优先级而是 CPU 核心的数量 ) python 代码。我知道我可以使用多处理库(池等)来做到这一点,但我不是 运行 将其与多处理结合起来的人。所以,我不知道该怎么做。而且我也可以通过终端来做到这一点,但这个脚本是由另一个脚本导入的。不幸的是,我没有通过终端调用它的奢侈。
tl;dr:如何限制 CPU 一个 python 脚本的使用( 核心数 ),该脚本正在被另一个脚本导入并且我什至不知道为什么它 运行 是并行的,而不是通过终端 运行 连接它。请检查下面的代码片段。
导致问题的代码段:
from sklearn.datasets import load_digits
from sklearn.decomposition import IncrementalPCA
import numpy as np
X, _ = load_digits(return_X_y=True)
#Copy-paste and increase the size of the dataset to see the behavior at htop.
for _ in range(8):
X = np.vstack((X, X))
print(X.shape)
transformer = IncrementalPCA(n_components=7, batch_size=200)
#PARTIAL FIT RUNS IN PARALLEL! GOD WHY?
---------------------------------------
transformer.partial_fit(X[:100, :])
---------------------------------------
X_transformed = transformer.fit_transform(X)
print(X_transformed.shape)
版本:
- Python 3.6
- 作业库 0.13.2
- scikit-learn 0.20.2
- numpy 1.16.2
更新:不起作用。感谢您对@Darkonaut 的澄清。可悲的是,我已经知道这是行不通的,而且我已经在问题标题上明确说明了,但我猜人们不会看。
我想我做错了。我已经根据@Ben Chaliah Ayoub answer 更新了代码片段。似乎没有任何改变。而且我还想指出一些事情:我并不是要 运行 多核上的这段代码。此行 transformer.partial_fit(X[:100, :])
运行 宁多核(出于某种原因),它没有 n_jobs
或任何东西。另请注意,我的第一个示例和我的原始代码未使用池或类似的东西进行初始化。我一开始就无法设置核心数(因为没有那个地方)。但是现在有了它的位置,但它仍然 运行ning 在多个内核上。随意测试它自己。 (下面的代码)这就是我寻找解决方法的原因。
from sklearn.datasets import load_digits
from sklearn.decomposition import IncrementalPCA
import numpy as np
from multiprocessing import Pool, cpu_count
def run_this():
X, _ = load_digits(return_X_y=True)
#Copy-paste and increase the size of the dataset to see the behavior at htop.
for _ in range(8):
X = np.vstack((X, X))
print(X.shape)
#This is the exact same example taken from sckitlearn's IncrementalPCA website.
transformer = IncrementalPCA(n_components=7, batch_size=200)
transformer.partial_fit(X[:100, :])
X_transformed = transformer.fit_transform(X)
print(X_transformed.shape)
pool= Pool(processes=1)
pool.apply(run_this)
更新: 因此,在导入 numpy 之前,我尝试在我的代码中使用 设置 blas 线程,但它(再次)不起作用。还有其他建议吗?最新阶段的代码可以在下面找到。
致谢: @Amir
from sklearn.datasets import load_digits
from sklearn.decomposition import IncrementalPCA
import os
os.environ["OMP_NUM_THREADS"] = "1" # export OMP_NUM_THREADS=1
os.environ["OPENBLAS_NUM_THREADS"] = "1" # export OPENBLAS_NUM_THREADS=1
os.environ["MKL_NUM_THREADS"] = "1" # export MKL_NUM_THREADS=1
os.environ["VECLIB_MAXIMUM_THREADS"] = "1" # export VECLIB_MAXIMUM_THREADS=1
os.environ["NUMEXPR_NUM_THREADS"] = "1" # export NUMEXPR_NUM_THREADS=1
import numpy as np
X, _ = load_digits(return_X_y=True)
#Copy-paste and increase the size of the dataset to see the behavior at htop.
for _ in range(8):
X = np.vstack((X, X))
print(X.shape)
transformer = IncrementalPCA(n_components=7, batch_size=200)
transformer.partial_fit(X[:100, :])
X_transformed = transformer.fit_transform(X)
print(X_transformed.shape)
I am looking for a way to limit a python scripts CPU usage (not priority but the number of CPU cores) with python code.
例如,要使您的应用程序仅利用前 4 CPUs,请执行以下操作:
taskset --cpu-list 0-3 <app>
但是,这些工具限制进程使用特定的 CPUs,而不是使用的 CPUs 的总数。为了获得最佳结果,他们要求将那些 CPU 与 OS 进程调度程序隔离开来,以便调度程序不会 运行 那些 CPU 上的任何其他进程。否则,如果指定的 CPU 当前正在 运行 其他线程,而其他 CPU 空闲,您的线程将无法 运行 在其他空闲 CPUs 并且必须为这些特定的 CPUs 排队,这并不理想。
使用 cgroups
,您可以限制 processes/threads 使用可用 CPU 资源的特定部分,而不限于特定的 CPU,但是 cgroups
设置不那么琐碎。
我通过设置BLAS环境变量(来自 link)解决了原题给出的示例代码中的问题。 但这不是我实际问题的答案。我的第一次尝试(第二次更新)是错误的。我需要设置线程数 不是在导入 numpy 库之前而是在库 (IncrementalPCA) 导入 numpy.
之前
那么,示例代码中的问题是什么?这不是一个实际问题,而是 numpy 库使用的 BLAS 库的一个特性。尝试使用多处理库限制它没有用,因为默认情况下 OpenBLAS 设置为使用所有可用线程。
致谢:@Amir 和@Darkonaut
来源:OpenBLAS 1, OpenBLAS 2,
import os
os.environ["OMP_NUM_THREADS"] = "1" # export OMP_NUM_THREADS=1
os.environ["OPENBLAS_NUM_THREADS"] = "1" # export OPENBLAS_NUM_THREADS=1
os.environ["MKL_NUM_THREADS"] = "1" # export MKL_NUM_THREADS=1
os.environ["VECLIB_MAXIMUM_THREADS"] = "1" # export VECLIB_MAXIMUM_THREADS=1
os.environ["NUMEXPR_NUM_THREADS"] = "1" # export NUMEXPR_NUM_THREADS=1
from sklearn.datasets import load_digits
from sklearn.decomposition import IncrementalPCA
import numpy as np
X, _ = load_digits(return_X_y=True)
#Copy-paste and increase the size of the dataset to see the behavior at htop.
for _ in range(8):
X = np.vstack((X, X))
print(X.shape)
transformer = IncrementalPCA(n_components=7, batch_size=200)
transformer.partial_fit(X[:100, :])
X_transformed = transformer.fit_transform(X)
print(X_transformed.shape)
但是您可以通过检查哪一个来明确设置正确的 BLAS 环境
由您的 numpy 构建使用,如下所示:
>>>import numpy as np
>>>np.__config__.show()
给出了这些结果...
blas_mkl_info:
NOT AVAILABLE
blis_info:
NOT AVAILABLE
openblas_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/lib']
language = c
define_macros = [('HAVE_CBLAS', None)]
blas_opt_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/lib']
language = c
define_macros = [('HAVE_CBLAS', None)]
lapack_mkl_info:
NOT AVAILABLE
openblas_lapack_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/lib']
language = c
define_macros = [('HAVE_CBLAS', None)]
lapack_opt_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/lib']
language = c
define_macros = [('HAVE_CBLAS', None)]
...意味着我的 numpy 构建使用了 OpenBLAS。我需要写的只是 os.environ["OPENBLAS_NUM_THREADS"] = "2"
以限制 numpy 库的线程使用。
我的主要问题是发出
tl;dr:如何限制 CPU 一个 python 脚本的使用( 核心数 ),该脚本正在被另一个脚本导入并且我什至不知道为什么它 运行 是并行的,而不是通过终端 运行 连接它。请检查下面的代码片段。
导致问题的代码段:
from sklearn.datasets import load_digits
from sklearn.decomposition import IncrementalPCA
import numpy as np
X, _ = load_digits(return_X_y=True)
#Copy-paste and increase the size of the dataset to see the behavior at htop.
for _ in range(8):
X = np.vstack((X, X))
print(X.shape)
transformer = IncrementalPCA(n_components=7, batch_size=200)
#PARTIAL FIT RUNS IN PARALLEL! GOD WHY?
---------------------------------------
transformer.partial_fit(X[:100, :])
---------------------------------------
X_transformed = transformer.fit_transform(X)
print(X_transformed.shape)
版本:
- Python 3.6
- 作业库 0.13.2
- scikit-learn 0.20.2
- numpy 1.16.2
更新:不起作用。感谢您对@Darkonaut 的澄清。可悲的是,我已经知道这是行不通的,而且我已经在问题标题上明确说明了,但我猜人们不会看。
我想我做错了。我已经根据@Ben Chaliah Ayoub answer 更新了代码片段。似乎没有任何改变。而且我还想指出一些事情:我并不是要 运行 多核上的这段代码。此行 transformer.partial_fit(X[:100, :])
运行 宁多核(出于某种原因),它没有 n_jobs
或任何东西。另请注意,我的第一个示例和我的原始代码未使用池或类似的东西进行初始化。我一开始就无法设置核心数(因为没有那个地方)。但是现在有了它的位置,但它仍然 运行ning 在多个内核上。随意测试它自己。 (下面的代码)这就是我寻找解决方法的原因。
from sklearn.datasets import load_digits
from sklearn.decomposition import IncrementalPCA
import numpy as np
from multiprocessing import Pool, cpu_count
def run_this():
X, _ = load_digits(return_X_y=True)
#Copy-paste and increase the size of the dataset to see the behavior at htop.
for _ in range(8):
X = np.vstack((X, X))
print(X.shape)
#This is the exact same example taken from sckitlearn's IncrementalPCA website.
transformer = IncrementalPCA(n_components=7, batch_size=200)
transformer.partial_fit(X[:100, :])
X_transformed = transformer.fit_transform(X)
print(X_transformed.shape)
pool= Pool(processes=1)
pool.apply(run_this)
更新: 因此,在导入 numpy 之前,我尝试在我的代码中使用
致谢: @Amir
from sklearn.datasets import load_digits
from sklearn.decomposition import IncrementalPCA
import os
os.environ["OMP_NUM_THREADS"] = "1" # export OMP_NUM_THREADS=1
os.environ["OPENBLAS_NUM_THREADS"] = "1" # export OPENBLAS_NUM_THREADS=1
os.environ["MKL_NUM_THREADS"] = "1" # export MKL_NUM_THREADS=1
os.environ["VECLIB_MAXIMUM_THREADS"] = "1" # export VECLIB_MAXIMUM_THREADS=1
os.environ["NUMEXPR_NUM_THREADS"] = "1" # export NUMEXPR_NUM_THREADS=1
import numpy as np
X, _ = load_digits(return_X_y=True)
#Copy-paste and increase the size of the dataset to see the behavior at htop.
for _ in range(8):
X = np.vstack((X, X))
print(X.shape)
transformer = IncrementalPCA(n_components=7, batch_size=200)
transformer.partial_fit(X[:100, :])
X_transformed = transformer.fit_transform(X)
print(X_transformed.shape)
I am looking for a way to limit a python scripts CPU usage (not priority but the number of CPU cores) with python code.
例如,要使您的应用程序仅利用前 4 CPUs,请执行以下操作:
taskset --cpu-list 0-3 <app>
但是,这些工具限制进程使用特定的 CPUs,而不是使用的 CPUs 的总数。为了获得最佳结果,他们要求将那些 CPU 与 OS 进程调度程序隔离开来,以便调度程序不会 运行 那些 CPU 上的任何其他进程。否则,如果指定的 CPU 当前正在 运行 其他线程,而其他 CPU 空闲,您的线程将无法 运行 在其他空闲 CPUs 并且必须为这些特定的 CPUs 排队,这并不理想。
使用 cgroups
,您可以限制 processes/threads 使用可用 CPU 资源的特定部分,而不限于特定的 CPU,但是 cgroups
设置不那么琐碎。
我通过设置BLAS环境变量(来自
之前
那么,示例代码中的问题是什么?这不是一个实际问题,而是 numpy 库使用的 BLAS 库的一个特性。尝试使用多处理库限制它没有用,因为默认情况下 OpenBLAS 设置为使用所有可用线程。
致谢:@Amir 和@Darkonaut
来源:OpenBLAS 1, OpenBLAS 2,
import os
os.environ["OMP_NUM_THREADS"] = "1" # export OMP_NUM_THREADS=1
os.environ["OPENBLAS_NUM_THREADS"] = "1" # export OPENBLAS_NUM_THREADS=1
os.environ["MKL_NUM_THREADS"] = "1" # export MKL_NUM_THREADS=1
os.environ["VECLIB_MAXIMUM_THREADS"] = "1" # export VECLIB_MAXIMUM_THREADS=1
os.environ["NUMEXPR_NUM_THREADS"] = "1" # export NUMEXPR_NUM_THREADS=1
from sklearn.datasets import load_digits
from sklearn.decomposition import IncrementalPCA
import numpy as np
X, _ = load_digits(return_X_y=True)
#Copy-paste and increase the size of the dataset to see the behavior at htop.
for _ in range(8):
X = np.vstack((X, X))
print(X.shape)
transformer = IncrementalPCA(n_components=7, batch_size=200)
transformer.partial_fit(X[:100, :])
X_transformed = transformer.fit_transform(X)
print(X_transformed.shape)
但是您可以通过检查哪一个来明确设置正确的 BLAS 环境 由您的 numpy 构建使用,如下所示:
>>>import numpy as np
>>>np.__config__.show()
给出了这些结果...
blas_mkl_info:
NOT AVAILABLE
blis_info:
NOT AVAILABLE
openblas_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/lib']
language = c
define_macros = [('HAVE_CBLAS', None)]
blas_opt_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/lib']
language = c
define_macros = [('HAVE_CBLAS', None)]
lapack_mkl_info:
NOT AVAILABLE
openblas_lapack_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/lib']
language = c
define_macros = [('HAVE_CBLAS', None)]
lapack_opt_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/lib']
language = c
define_macros = [('HAVE_CBLAS', None)]
...意味着我的 numpy 构建使用了 OpenBLAS。我需要写的只是 os.environ["OPENBLAS_NUM_THREADS"] = "2"
以限制 numpy 库的线程使用。