【问题标题】:Numpy SVD appears to parallelize on Mac OSX, but not on my Ubuntu virtual machineNumpy SVD 似乎在 Mac OSX 上并行化,但在我的 Ubuntu 虚拟机上却没有
【发布时间】:2025-12-17 03:15:03
【问题描述】:

我想运行以下脚本:

#python imports
import time

#3rd party imports
import numpy as np
import pandas as pd

def pd_svd(pd_dataframe):
    np_dataframe = pd_dataframe.values
    return np.linalg.svd(pd_dataframe)

if __name__ == '__main__':
    li_times = []
    for i in range(1, 3):
        start = time.time()
        pd_dataframe = pd.DataFrame(np.random.random((3000, 252 * i)))
        pd_svd(pd_dataframe)
        li_times.append(str(time.time() - start))
    print li_times

我在装有 OSX 10.9.4 的 Macbook Air 2011 和运行 Ubuntu 12.0.4 的 16 核云 VM 上试用它。出于某种原因,这在我的 Macbook Air 上大约需要 4 秒,在我的 VM 上大约需要 15 秒。我使用top 检查了这些进程,似乎在我的 Ubuntu VM 上,它没有使用并行性,而在我的 Macbook Air 上,它是。

以下是我的 MBA 上顶的结果:

在我的 ubuntu 虚拟机上:

知道为什么我的 Macbook Air 的 SVD 速度要快得多吗?特别是,在进行 numpy 比较时,云 VM 速度要快得多,而且似乎使用了并行性(没有做 top,但速度是原来的几倍)。

编辑:

这是np.show_config() 在云虚拟机上的输出:

blas_info:
    libraries = ['blas']
    library_dirs = ['/usr/lib']
    language = f77
lapack_info:
    libraries = ['lapack']
    library_dirs = ['/usr/lib']
    language = f77
atlas_threads_info:
  NOT AVAILABLE
blas_opt_info:
    libraries = ['blas']
    library_dirs = ['/usr/lib']
    language = f77
    define_macros = [('NO_ATLAS_INFO', 1)]
atlas_blas_threads_info:
  NOT AVAILABLE
lapack_opt_info:
    libraries = ['lapack', 'blas']
    library_dirs = ['/usr/lib']
    language = f77
    define_macros = [('NO_ATLAS_INFO', 1)]
atlas_info:
  NOT AVAILABLE
lapack_mkl_info:
  NOT AVAILABLE
blas_mkl_info:
  NOT AVAILABLE
atlas_blas_info:
  NOT AVAILABLE
mkl_info:
  NOT AVAILABLE

【问题讨论】:

  • 您的云 VM 中的 numpy 版本可能未链接到多线程 BLAS 库。 np.show_config() 的输出是什么?
  • 您好,感谢您的帮助。我更新了。

标签: python numpy virtual-machine linear-algebra blas


【解决方案1】:

我怀疑您的云 VM 上的 numpy 版本仅链接到参考 CBLAS 库 (*/usr/lib/libblas/libblas.so.3.0)。这是单线程的,并且比其他优化的 BLAS 实现(例如 OpenBLAS 和 ATLAS)慢得多。

您可以通过使用ldd 检查哪些库在运行时被 numpy 动态链接来确认这一点:

~$ ldd /usr/lib/python2.7/dist-packages/numpy/core/_dotblas.so

你可能会看到这样的一行:

...
libblas.so.3 => /usr/lib/libblas.so.3 (0x00007f98445e3000)
...

/usr/lib/libblas.so.3 是一个符号链接。如果您使用readlink 跟踪链接链,您可能会看到如下内容:

~$ readlink -f /usr/lib/libblas.so.3
/usr/lib/libblas/libblas.so.3.0

这是缓慢的单线程 CBLAS 库。假设您有 root 访问权限,最简单的解决方案可能是通过 apt-get 安装 OpenBLAS:

~$ sudo apt-get install libopenblas-base libopenblas-dev

当我在我的服务器上安装这个包时,它更新了/usr/lib/libblas.so.3 的符号链接以指向 OpenBLAS 库而不是 CBLAS:

~$ readlink -f /usr/lib/libblas.so.3
/usr/lib/openblas-base/libblas.so.3

希望这足以让您使用更快的 BLAS 库。

如果由于某种原因,您无法使用 apt-get 解决此问题,我之前已经编写了一些说明,用于从源代码 which you can find here 构建 numpy 和 OpenBLAS。我还编写了一些说明 here 用于使用 update-alternatives 手动符号链接到不同的 BLAS 库。


*我在回答中引用的路径是运行 Ubuntu 14.10 的服务器的默认路径,我使用 apt-get 安装了 numpy。它们可能会有所不同,具体取决于您的 Ubuntu 版本和您安装 numpy 的方式。

【讨论】:

  • 当我使用 apt-get 然后尝试导入 numpy(“GotoBLAS:架构初始化失败。未找到初始化函数。”)以及尝试从source via cd OpenBLAS && make FC=gfortran ("getarch_2nd.c:12:35: error: 'SGEMM_DEFAULT_UNROLL_M' undeclared (first use in this function)")
  • 嗯,由于硬件虚拟化,它似乎无法检测 CPU 架构。我从未尝试在 VM 中编译 OpenBLAS,但我认为您应该能够通过在编译时使用 TARGET= 环境变量 (see here) 设置目标架构来使其工作。您应该能够通过查看less /proc/cpuinfo 来确定目标架构。
  • 您的分析完全正确。这在我使用的虚拟机上不起作用,所以我使用了一个不同的虚拟机和一个更新的 ubuntu(14.04)并且它有效。我接受了。
  • @AlexanderMoreno 酷,很高兴你设法修复它。为了未来读者的利益,如果您能提及哪个虚拟机给您带来了麻烦,那就太好了。
最近更新 更多