pypy 是一个支持 JIT 技术的 python 解释器实现,在某些任务上可以期待有比 cpython 更好的性能。但由于很多 python 包使用了特殊的 cpython 扩展接口,难以被 cpython 支持。特别是机器学习、科学计算流行的软件包,现在通常通过 anaconda 直接安装预编译包,难以支持 pypy. 一直好奇 pypy 在科学计算任务上会不会比 cpython 有优势,折腾了一晚上在 macOS 上安装了 pypy3 + numpy + scipy + matplotlib + scikit-learn + matplotlib, 在这里记录一下。
首先需要安装 pypy3 本身和编译器。可以通过 homebrew 安装:
brew install pypy3 gcc g++ gfortran
此时 pypy3 & pip 已经可以使用。可以使用 pypy3 命令替代 python3 命令运行一些脚本:
pip_pypy3 install package_name
pypy3 # start pypy3
注意,如果当前有 conda env, virtualenv 处于激活状态,先将其 deactivate. 有时候 pypy3 没有正确设置环境变量,会有一些警告,但在我的测试过程中只有警告,没有出现错误。以及,pypy3 默认安装带的包比较少,可能会出现各种 ImportError, 一般可以使用 pip_pypy3 安装对应的包解决。
「纯 python 软件包」的安装一般可以成功,只有 numpy 这种带有 C 扩展、还需要链接其他库的包安装比较麻烦。为了安装 numpy, 首先需要安装某个数学加速库。这里建议安装 OpenBLAS. 直接安装预编译的 OpenBLAS 似乎是不行的,可能是由于预编译的编译器版本与本地不一致。因此直接从 github 拉取最新版并编译安装:
git clone https://github.com/xianyi/OpenBLAS.git
cd OpenBLAS
make
# default install into /opt/OpenBLAS
sudo make install
注意,anaconda 里的 numpy 链接的是 intel mkl. 可以尝试搜索从 intel 官网安装这个软件包,作为 root 安装时,这个软件包会被安装在 opt/intel/mkl
. 我没有尝试链接 intel mkl, 不知道能否成功。
之后编译安装 numpy & scipy. 这两个软件包从 pip 安装会失败,因此仍然从 github 拉取源码。这里以 numpy 为例,scipy 是同一个组织的软件包,安装步骤完全相同。
# install wheel at first
pip_pypy3 install wheel
git clone https://github.com/numpy/numpy.git
从 pip 安装失败是因为链接不到 OpenBLAS. 从一篇博客了解到,需要在 numpy 源代码根目录下添加一个文件 site.cfg
, 指定 OpenBLAS 位置:
[DEFAULT]
library_dirs = /opt/OpenBLAS/lib
include_dirs = /opt/OpenBLAS/include
[atlas]
atlas_libs = openblas
libraries = openblas
[openblas]
libraries = openblas
library_dirs = /opt/OpenBLAS/lib
include_dirs = /opt/OpenBLAS/include
scipy 编译时也需要在其根目录下创建一个同样的文件,可以直接把 numpy 目录下的该文件复制过去。然后可以编译、安装。
cd numpy # or scipy
pypy3 setup.py build
pypy3 setup.py install
这些编译过程可能需要花几分钟时间。numpy & scipy 安装成功后,其他的常见软件包 matplotlib, jupyter, scikit-learn 等的安装可以直接通过 pip_pypy3.
之后,如果想启动 ipython, 由于环境变量可能不正确,可能要通过以下命令:
pypy3 -m IPython
至此,基于 pypy3 的科学计算 & 机器学习环境安装成功 ~
pypy3 在某些情景下比 cpython 要快,但在我的项目上,它不仅没有变快,反而变慢了。。对于类似于脚本的短时运行的科学计算项目,pypy3 优势可能不明显,也有可能是我的打开方式有什么问题。。