blis-blas类线性代数库,作为一个独立的c-扩展。
blis的Python项目详细描述
cython blis:来自python和cython的快速blas类操作,没有撕裂
此存储库提供blis线性代数 作为独立的python c扩展的例程。
目前,我们只支持单线程执行,因为这实际上最适合我们的工作负载(ml推断)。
安装
您可以通过pip:
pip install blis
轮子应该是可用的,所以安装应该很快。如果您想从源安装,并且您在Windows上,则需要安装LLVM。
为替代架构构建blis
提供的控制盘应在x86_86体系结构上工作。不幸的是,我们目前还不知道如何为其他体系结构提供不同的轮子,而且我们不能提供一个在任何地方都能工作的二进制文件。因此,如果控制盘不适合您的CPU,您需要指定源代码分布,并使用blis arch
环境变量告诉blis您的CPU体系结构。
a)使用通用拱支架安装
BLIS_ARCH="generic" pip install spacy --no-binary blis
b)建筑专用支架
为了编译blis,cython blis
bundles为特定的体系结构编写makefile脚本,这些脚本是通过运行blis构建系统并记录命令来编译的。我们还没有每个架构的日志,因为有些架构我们还没有访问。
有关
建筑。例如,下面介绍如何为ARM体系结构构建支持Cortexa57
:
git clone https://github.com/explosion/cython-blis &&cd cython-blis git pull && git submodule init && git submodule update && git submodule status python3 -m venv env3.6 source env3.6/bin/activate pip install -r requirements.txt ./bin/generate-make-jsonl linux cortexa57 BLIS_ARCH="coretexa57" python setup.py build_ext --inplace BLIS_ARCH="cortexa57" python setup.py bdist_wheel
祈祷吧,这将为你打造一个支撑平台的轮子。你
然后可以使用
blis/\u src/make/linux-cortexa57.jsonl
和
blis/\u src/include/linux-cortexa57/blis.h
文件以便运行:
BLIS_ARCH=cortexa57 pip install spacy --no-binary=blis
运行基准
安装后,运行一个小型矩阵乘法基准:
$ exportOMP_NUM_THREADS=1# Tell Numpy to only use one thread. $ python -m blis.benchmark Setting up data nO=384nI=384batch_size=2000. Running 1000 iterations Blis... Total: 11032014.6484 7.35 seconds Numpy (Openblas)... Total: 11032016.6016 16.81 seconds Blis einsum ab,cb->ca 8.10 seconds Numpy einsum ab,cb->ca Total: 5510596.19141 83.18 seconds
低性能是
是预期的,但是低的numpy.dot
性能令人惊讶。链接numpy
与MKL相比,性能更佳:
Numpy (mkl_rt) gemm... Total: 11032011.71875 5.21 seconds
这些数字是指在Dell XPS 13 i7-7500u上的性能。运行 2015年MacBook Air的相同基准:
Blis... Total: 11032014.6484 8.89 seconds Numpy (Accelerate)... Total: 11032012.6953 6.68 seconds
显然,戴尔的numpy+openblas性能是个例外,因此很可能 编译和体系结构检测出现问题。
用法
提供了两个api:一个高级pythonapi和direct cython访问。python api最好的部分是 einsum函数, 它的工作原理和numpy的一样,但是有一些限制 直接映射到blis例程。示例用法:
fromblis.pyimporteinsumfromnumpyimportndarray,zerosdim_a=500dim_b=128dim_c=300arr1=ndarray((dim_a,dim_b))arr2=ndarray((dim_b,dim_c))out=zeros((dim_a,dim_c))einsum('ab,bc->ac',arr1,arr2,out=out)# Change dimension order of outputout=einsum('ab,bc->ca',arr1,arr2)assertout.shape==(dim_a,dim_c)# Matrix vector product, with transposed outputarr2=ndarray((dim_b,))out=einsum('ab,b->ba',arr1,arr2)assertout.shape==(dim_b,dim_a)
爱因斯坦的求和格式非常棒,所以
令人失望的是,它比调用tensordot
麻木的函数放弃了numpy版本的通用性,
这样就可以很容易地将调用映射到blis:
- 只有两个输入张量
- 最大二维
- 尺寸必须标有
A
,B
和C
- 第一个参数的尺寸必须是
'a'
(对于1D输入)或'ab'
(对于2d输入)。
有了这些限制,只有15种有效的组合
对应于您使用gemm
,gemv
执行的所有操作,
ger
和axpy
函数。因此你可以忘记所有其他的
函数,只需使用einsum
。以下是有效的einsum字符串
它们对应的调用和numpy等价物:
'a,a->;a'
axpy(a,b)
A+B
'a,b->;ab'
ger(a,b)
外部(A,B)
'a,b->;ba'
ger(b,a)
外部(B,A)
'ab,a->;ab'
批处理axpy(a,b)
a*b
'ab,a->;ba'
批处理axpy(a,b,trans1=true)
(a*b).t
'a b,b->;a'
gemv(a,b)
a*b
'a b,a->;b'
gemv(a,b,trans1=true)
a.t*b
'AB,AC->;CB'
gemm(b,a,trans1=true,trans2=true)
点(B.T,A)
'AB,AC->;BC'
gemm(a,b,trans1=true,trans2=false)
点(A.T,B)
'AB,BC->;AC'
gemm(a,b,trans1=false,trans2=false)
点(A,B)
'ab,bc->;ca'
gemm(b,a,trans1=false,trans2=true)
点(B.T,A.T)
'ab,ca->;bc'
gemm(a,b,trans1=true,trans2=true)
点(B,A.T)
'ab,ca->;cb'
gemm(b,a,trans1=false,trans2=false)
点(b,a)
'AB、CB->;AC'
gemm(a,b,trans1=false,trans2=true)
点(A.T,B.T)
'ab,cb->;ca'
gemm(b,a,trans1=false,trans2=true)
点(B,A.T)
我们还提供与底层的融合型Nogil cython绑定 blis线性代数库。融合类型是一种简单的模板机制, 只允许少量编译时通用编程:
cimportblis.cyA=<float*>calloc(nN*nI,sizeof(float))B=<float*>calloc(nO*nI,sizeof(float))C=<float*>calloc(nr_b0*nr_b1,sizeof(float))blis.cy.gemm(blis.cy.NO_TRANSPOSE,blis.cy.NO_TRANSPOSE,nO,nI,nN,1.0,A,nI,1,B,nO,1,1.0,C,nO,1)
我们需要时,已经添加了绑定。请提交拉取请求,如果 库缺少一些您需要的功能。
开发
要构建源程序包,应运行以下命令:
pip install blis0
这将使用
flame blis
子模块。
更新生成文件
为了编译blis源代码,我们使用jsonl文件来提供 显式编译器标志。我们通过运行blis的构建来构建这些jsonl文件 系统,然后转换日志。这避免了我们必须复制 在python中构建系统:我们只是使用jsonl来生成一堆子流程 电话。为了支持新的操作系统/架构组合,我们必须提供 jsonl文件和头。
Linux
Linux构建文件需要在manylinux1 docker中生成 容器,以便与车轮制造过程兼容。
首先,安装Docker。然后按以下步骤启动容器:
pip install blis1
在容器中,以下命令应该检查repo和 为通用架构构建jsonl文件:
pip install blis2
然后从新的终端中,从容器中检索我们需要的两个文件:
pip install blis3