tensorflow 为什么M1 Max上的Python原生速度比旧英特尔i5上的Python慢得多?

bksxznpy  于 2022-11-16  发布在  Python
关注(0)|答案(4)|浏览(190)

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

  • 为什么python在M1 Max上运行比在我的旧MacBook Pro 2016上运行要慢很多(~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)。
    2. Numpy安装者
  • conda install numpy:numpy来自原始的康达-福格频道,或者预装了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

3.从运行

  • 终点站
  • PyCharm(物理魔法)。

下面是测试代码:

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芯片?由于我的工作严重依赖于本地运行,本地速度对我来说非常重要。如果您对可能的解决方案有任何建议,或者您自己设备上的任何数据点,我将不胜感激:)

nwnhqdif

nwnhqdif1#

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_openblas:x1米15英寸
  • 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上不受支持。

  • D. np_openblas_source:首先通过brew install openblas安装openblas。然后将[openblas]路径/opt/homebrew/opt/openblas添加到site.cfg并从源代码构建Numpy。
  • 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    |
+-------+-----------+------------+-------------+-----------+--------------------+----+----------+----------+
7xzttuei

7xzttuei2#

可能原因:不同的BLAS库

由于性能指标评测运行的是线性代数例程,因此此处测试的可能是BLAS实现。osx-64平台的默认Anaconda发行版将随英特尔的MKL实现一起提供;osx-arm 64平台仅具有通用Netlib BLAS和OpenBLAS实现选项。
对于我(MacOS w/ Intel i9),我得到了以下基准测试结果:
| BLAS实施|平均时间(s)|
| - -|- -|
| mkl|0.95932单位|
| blis| 1.72059年|
| 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.
enxuqcxy

enxuqcxy3#

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

  • 带libblas加速的M1 Max:1.024
  • 不带libblas加速的M1最大值:2.672
bmp9r5qi

bmp9r5qi4#

谢谢你的提示。我在我刚买的新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中运行
  2. 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

相关问题