【问题标题】:Multiple instances of Python running simultaneously limited to 35同时运行的多个 Python 实例限制为 35 个
【发布时间】:2018-07-10 03:15:33
【问题描述】:

我在并行计算集群的不同处理器上将 Python 3.6 脚本作为多个单独的进程运行。 最多 35 个进程同时运行没有问题,但第 36 个(以及更多)进程在第二行出现分段错误import pandas as pd 时崩溃。有趣的是,第一行 import os 不会引起问题。 完整的错误信息是:

OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max
Traceback (most recent call last):
  File "/home/.../myscript.py", line 32, in <module>
    import pandas as pd
  File "/home/.../python_venv2/lib/python3.6/site-packages/pandas/__init__.py", line 13, in <module>
    __import__(dependency)
  File "/home/.../python_venv2/lib/python3.6/site-packages/numpy/__init__.py", line 142, in <module>
    from . import add_newdocs
  File "/home/.../python_venv2/lib/python3.6/site-packages/numpy/add_newdocs.py", line 13, in <module>
    from numpy.lib import add_newdoc
  File "/home/.../python_venv2/lib/python3.6/site-packages/numpy/lib/__init__.py", line 8, in <module>
    from .type_check import *
  File "/home/.../python_venv2/lib/python3.6/site-packages/numpy/lib/type_check.py", line 11, in <module>
    import numpy.core.numeric as _nx
  File "/home/.../python_venv2/lib/python3.6/site-packages/numpy/core/__init__.py", line 16, in <module>
    from . import multiarray
SystemError: initialization of multiarray raised unreported exception
/var/spool/slurmd/job04590/slurm_script: line 11: 26963 Segmentation fault      python /home/.../myscript.py -x 38

Pandas 和其他一些软件包安装在虚拟环境中。我已经复制了虚拟环境,因此每个 venv 中运行的进程不超过 24 个。例如,上面的错误脚本来自一个在虚拟环境中运行的名为python_venv2的脚本。

无论有多少进程从特定的 Pandas 实例导入,每次都会在第 36 个进程上出现问题。 (我什至没有降低并行计算集群的容量。)

那么,如果不是限制访问 Pandas 的进程数,是不是限制了运行 Python 的进程数?为什么限制为 35?

是否可以在机器上安装多个 Python 副本(在不同的虚拟环境中?)以便我可以运行 35 个以上的进程?

【问题讨论】:

  • 您的用户在被命中的集群上似乎存在线程限制。无论如何,这与 Python 无关,而是与操作系统相关。
  • 这个问题类似于this onethis one。他们没有得到很好的答案,而且年龄在 2-3 岁,所以我认为这个问题应该保持开放。
  • 尝试从命令行运行export OPENBLAS_NUM_THREADS=1
  • 您使用的是哪个操作系统?
  • export OPENBLAS_NUM_THREADS=1 似乎已经解决了这个问题非常感谢@Richard - 你能告诉我我在那里做了什么吗?

标签: python linux parallel-processing multiprocessing openblas


【解决方案1】:

分解错误信息

您的错误消息包含以下提示:

OpenBLAS blas_thread_init: pthread_create: Resource temporarily unavailable
OpenBLAS blas_thread_init: RLIMIT_NPROC 1024 current, 2067021 max

RLIMIT_NPROC 变量控制用户可以拥有的进程总数。更具体地说,由于它是每个进程的设置,当进程调用 fork()clone()vfork() 和 c 时,该进程的 RLIMIT_NPROC 值将与该进程的父进程的总进程计数进行比较用户。如果超过了该值,就会关闭,正如您所经历的那样。

错误消息表明 OpenBLAS 无法创建其他线程,因为您的用户已经使用了 RLIMIT_NPROC 提供的所有线程。

由于您在集群上运行,因此您的用户不太可能运行许多线程(例如,如果您在个人计算机上浏览网页、播放音乐等),因此有理由得出以下结论: OpenBLAS 正在尝试启动多个线程。

OpenBLAS 如何使用线程

OpenBLAS 可以使用多个线程来加速线性代数。您可能需要多个线程来快速解决一个更大的问题。您可能需要更少的线程来同时解决许多较小的问题。

OpenBLAS 有several ways 来限制它使用的线程数。这些是通过以下方式控制的:

export OPENBLAS_NUM_THREADS=4
export GOTO_NUM_THREADS=4
export OMP_NUM_THREADS=4

优先级为 OPENBLAS_NUM_THREADS > GOTO_NUM_THREADS > OMP_NUM_THREADS。 (我认为这意味着OPENBLAS_NUM_THREADS 会覆盖OMP_NUM_THREADS;但是,OpenBLAS 在使用USE_OPENMP=1 编译时会忽略OPENBLAS_NUM_THREADSGOTO_NUM_THREADS。)

如果上述变量均未设置,OpenBLAS 将使用与您机器上的内核数相等的线程数运行(您机器上的 32 个)

您的情况

您的集群有 32 核 CPU。您正在尝试运行 36 个 Python 实例。每个实例需要 1 个 Python 线程 + 32 个 OpenBLAS 线程。您还需要 1 个线程用于 SSH 连接,1 个线程用于 shell。这意味着您需要 36*(32+1)+2=1190 个线程。

解决问题的核选项是使用:

export OPENBLAS_NUM_THREADS=1

这将使您减少到 36*(1+1)+2=74 个线程。

由于您有备用容量,您可以将OPENBLAS_NUM_THREADS 调整为更高的值,但是您的单独 Python 进程拥有的 OpenBLAS 实例会相互干扰。因此,在获得一种解决方案的速度与获得多种解决方案的速度之间需要权衡取舍。理想情况下,您可以通过每个节点运行更少的 Python 并使用更多节点来解决这种权衡问题。

【讨论】:

  • 谢谢理查德,这是一个非常全面的答案。事实上,操作系统已经在 4 个不同的节点之间分配了作业。 OPENBLAS_NUM_THREADS 的试验和时间范围是否在 1 到 32 之间?
  • @doctorer:是的,我建议这样做。您可以尝试 1、4、8、16、31、32、60-64。根据您的 CPU 架构,您可能会发现其中之一提供了最佳速度。 60-64 值“超额订阅”您的 CPU,如果 CPU 可以隐藏内存延迟,有时会提供更好的结果。使用 31 和 60-63 为管理计算的 Python 和 OpenBLAS 线程释放不同数量的资源。
  • @doctorer:您的 CPU 内部可能看起来像 this,因此使用线程数隐含地控制缓存的争用。
  • Richard 的这个解决方案在集群中也适用于我。非常感谢。
猜你喜欢
  • 2021-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
  • 2018-02-11
  • 2023-04-11
相关资源
最近更新 更多