tensorflow 为什么M1 Max上的numpy本机比旧的英特尔i5慢得多?

k5ifujac  于 2023-02-24  发布在  其他
关注(0)|答案(4)|浏览(152)

我刚刚得到了我的新MacBook Pro与M1最大芯片和设置Python。我已经尝试了几个组合设置来测试速度-现在我很困惑。首先把我的问题在这里:

  • 为什么Python在M1 Max上原生运行比在我的旧MacBook Pro 2016上运行英特尔i5要慢得多(~100%)?
  • 在M1 Max上,为什么本机运行(由miniforge)和通过Rosetta运行(由anaconda)之间没有显著的速度差异--后者应该慢20%左右?
  • 在M1 Max和本机运行中,为什么安装了Numpy的conda和安装了Numpy的TensorFlow之间没有显著的速度差异?
  • 在M1 Max上,为什么在PyCharm IDE中运行总是比从终端运行慢20%,这在我的旧Intel Mac上不会发生。

支持我的问题的证据如下:
以下是我尝试过的设置:

      1. Python安装者**
  • Miniforge-arm64,以便python在M1 Max芯片上本机运行。(从活动监视器检查,python进程的KindApple)。
  • Anaconda。然后通过Rosseta运行python。(从活动监视器检查,python进程的KindIntel)。
      1. Numpy由**安装
  • conda install numpy:numpy来自原始的conda-forge频道,或者预装了anaconda。
  • 苹果-tensorflow :我用miniforge安装的python直接安装tensorflow,numpy也会安装,据说这样安装的numpy是针对苹果M1优化的,速度会更快,安装命令如下:
conda install -c apple tensorflow-deps
python -m pip install tensorflow-macos
python -m pip install tensorflow-metal

下面是测试代码:

import time
import numpy as np
np.random.seed(42)
a = np.random.uniform(size=(300, 300))
runtimes = 10

timecosts = []
for _ in range(runtimes):
    s_time = time.time()
    for i in range(100):
        a += 1
        np.linalg.svd(a)
    timecosts.append(time.time() - s_time)

print(f'mean of {runtimes} runs: {np.mean(timecosts):.5f}s')

结果如下:

+-----------------------------------+-----------------------+--------------------+
|   Python installed by (run on)→   | Miniforge (native M1) | Anaconda (Rosseta) |
+----------------------+------------+------------+----------+----------+---------+
| Numpy installed by ↓ | Run from → |  Terminal  |  PyCharm | Terminal | PyCharm |
+----------------------+------------+------------+----------+----------+---------+
|          Apple Tensorflow         |   4.19151  |  4.86248 |     /    |    /    |
+-----------------------------------+------------+----------+----------+---------+
|        conda install numpy        |   4.29386  |  4.98370 |  4.10029 | 4.99271 |
+-----------------------------------+------------+----------+----------+---------+

这是相当慢的。为了比较,

  • 在我的旧MacBook Pro 2016上运行相同的代码与i5芯片-它的成本**2.39917s**。
  • 另一个post (but not in English)报告使用M1芯片(非Pro或Max)运行,miniforge + conda_installed_numpy为**2.53214s,miniforge + apple_tensorflow_numpy为1.00613s**。
  • 你也可以自己试一下。

以下是CPU信息的详细信息:

  • 我的旧i5:
$ sysctl -a | grep -e brand_string -e cpu.core_count
machdep.cpu.brand_string: Intel(R) Core(TM) i5-6360U CPU @ 2.00GHz
machdep.cpu.core_count: 2
  • 我的新M1 Max:
% sysctl -a | grep -e brand_string -e cpu.core_count
machdep.cpu.brand_string: Apple M1 Max
machdep.cpu.core_count: 10

我严格按照教程中的说明操作-但为什么会发生这些情况?是因为我的安装缺陷,还是因为M1 Max芯片?由于我的工作严重依赖于本地运行,本地速度对我来说非常重要。任何可能的解决方案建议,或您自己设备上的任何数据点将不胜感激:)

ryevplcw

ryevplcw1#

2022年3月28日更新:请看下面@AndrejHribernik的评论。
如何在M1 Max上安装numpy,性能加速最快(苹果vecLib),以下是截至2021年12月6日的答案。
步骤

I.安装小型锻造机

这样Python就可以在arm 64上本地运行,而不是通过Rosseta翻译。
1.下载Miniforge3-MacOSX-arm64.sh,然后
1.运行脚本,然后打开另一个shell

$ bash Miniforge3-MacOSX-arm64.sh

1.创建一个环境(这里我使用名称np_veclib

$ conda create -n np_veclib python=3.9
$ conda activate np_veclib

II.使用指定为vecLib的BLAS接口安装Numpy

1.要编译numpy,首先需要安装cythonpybind11

$ conda install cython pybind11

1.编译numpy(谢谢@Marijn的answer)-不要使用conda install

$ pip install --no-binary :all: --no-use-pep517 numpy
  1. 2.的另一种方法是从源代码构建
$ git clone https://github.com/numpy/numpy
$ cd numpy
$ cp site.cfg.example site.cfg
$ nano site.cfg

编辑复制的site.cfg:添加以下行:

[accelerate]
libraries = Accelerate, vecLib

然后构建并安装:

$ NPY_LAPACK_ORDER=accelerate python setup.py build
$ python setup.py install

1.在2或3之后,现在测试numpy是否正在使用vecLib:

>>> import numpy
>>> numpy.show_config()

然后,应打印/System/Library/Frameworks/vecLib.framework/Headers等信息。

III.使用conda进一步安装其他软件包

让conda识别pip安装的软件包

conda config --set pip_interop_enabled true

必须这样做,否则,例如conda install pandas,则numpy将在The following packages will be installed列表中重新安装。但新安装的是来自conda-forge通道的,速度很慢。

与其他安装的比较:

1.竞争对手:

除了上面最优的一个,我还尝试了其他几个安装

  • 答:np_defaultconda create -n np_default python=3.9 numpy
  • B. np_openblasconda create -n np_openblas python=3.9 numpy blas=*=*openblas*
  • C. np_netlibconda create -n np_netlib python=3.9 numpy blas=*=*netlib*

上述ABC选项直接从conda-forge通道安装。numpy.show_config()将显示相同的结果。要查看差异,请按conda list检查-例如,openblas包安装在B中。请注意,mklblis在arm 64上不受支持。

  • 直径np_openblas_source:首先通过brew install openblas安装openblas,然后将[openblas]路径/opt/homebrew/opt/openblas添加到site.cfg,并从源代码构建Numpy。
  • 在此post中的M1i9–9880H
  • 我的旧i5-6360U 2核心的MacBook Pro 2016 13英寸.

2.基准测试:

这里我使用两个基准:

  1. mysvd.py:我的SVD分解
import time
import numpy as np
np.random.seed(42)
a = np.random.uniform(size=(300, 300))
runtimes = 10

timecosts = []
for _ in range(runtimes):
    s_time = time.time()
    for i in range(100):
        a += 1
        np.linalg.svd(a)
    timecosts.append(time.time() - s_time)

print(f'mean of {runtimes} runs: {np.mean(timecosts):.5f}s')
  1. dario.py:一个基准脚本由Dario Radečić在上述职位.

3.结果:

+-------+-----------+------------+-------------+-----------+--------------------+----+----------+----------+
|  sec  | np_veclib | np_default | np_openblas | np_netlib | np_openblas_source | M1 | i9–9880H | i5-6360U |
+-------+-----------+------------+-------------+-----------+--------------------+----+----------+----------+
| mysvd |  1.02300  |   4.29386  |   4.13854   |  4.75812  |      12.57879      |  / |     /    |  2.39917 |
+-------+-----------+------------+-------------+-----------+--------------------+----+----------+----------+
| dario |     21    |     41     |      39     |    323    |         40         | 33 |    23    |    78    |
+-------+-----------+------------+-------------+-----------+--------------------+----+----------+----------+
tct7dpnv

tct7dpnv2#

可能原因:不同的BLAS库

由于基准测试运行的是线性代数例程,因此这里测试的可能是BLAS实现。osx-64平台的默认Anaconda发行版将随英特尔的MKL实现一起提供;* * osx-arm64**平台只有通用Netlib BLAS和OpenBLAS实现选项。
对于我(MacOS w/Intel i9),我得到了以下基准测试结果:
| BLAS实施|平均时间(s)|
| - ------|- ------|
| mkl|0.95932|
| blis|一点七二零五九|
| openblas|二一七七零二三|
| netlib|五点七二七八二|
所以,我怀疑旧的MBP安装了MKL,而M1系统正在安装Netlib或OpenBLAS。也许可以试着弄清楚Netlib或OpenBLAS在M1上是更快,并保留更快的一个。

指定BLAS实现

以下是我测试的具体不同环境:

# MKL
conda create -n np_mkl python=3.9 numpy blas=*=*mkl*

# BLIS
conda create -n np_blis python=3.9 numpy blas=*=*blis*

# OpenBLAS
conda create -n np_openblas python=3.9 numpy blas=*=*openblas*

# Netlib
conda create -n np_netlib python=3.9 numpy blas=*=*netlib*

并使用以下命令运行基准脚本(so-np-bench.py

conda run -n np_mkl python so-np-bench.py

# etc.
q3aa0525

q3aa05253#

有了Miniforge3-MacOSX-arm64conda install -c conda-forge numpy "libblas=*=*accelerate",它在我的MacBook M1 Max上运行得非常完美。

  • 带libblas加速的M1最大值:1.024
  • M1最大值(无libblas加速):2.672
sg24os4d

sg24os4d4#

谢谢你的提示。我在我刚买的新Mac M1 MAX中遵循了以下步骤:
1.我安装了Minoforge3(bash Miniforge3-MacOSX-arm64.sh
1.使用Python 3.10初始化了一个基于conda的环境(conda init

  1. numpy安装为:conda install numpy "libblas=*=*accelerate"
    然后是链接中建议的基准:
    1.上面提到的脚本mysvd.pymean of 10 runs: 1.08088s中运行
    1.来自https://gist.githubusercontent.com/daradecic/a2ac0a75d7e5f22c9aa07174dcbbe061/raw/a56ee217e6d3f949b1d1f719a7a134cef130cd9f/macs.py的脚本dario.py给出:
Dotted two 4096x4096 matrices in 0.28 s.
Dotted two vectors of length 524288 in 0.11 ms.
SVD of a 2048x1024 matrix in 0.44 s.
Cholesky decomposition of a 2048x2048 matrix in 0.07 s.
Eigendecomposition of a 2048x2048 matrix in 3.83 s.

TOTAL TIME = 19 seconds

相关问题