2016-11-07 56 views
1

我目前正在研究一种耦合HMM的Python实现,它涉及维度(50,50,40,40)的元素乘法,点积和ndarrays总和, 40)和维度的ndarrays(40,40,40,40)。这就是说,非常大......第二个ndarray或多或少是稀疏的,有大约70%的零。在Python中实现大型ndarray乘法的最快方法

我一直在使用numpy.einsum,它给了我相当慢的结果(算法需要大约3小时运行)。现在问题是我需要优化HMM的一些参数,这意味着我必须至少进行10000次运行,因此为了保持合理,我需要将速度提高至少1000倍。

我一直在四处寻找找到在Python中执行大型数组操作的最佳方式,现在我完全迷失了所有读过的东西。所以我有几个问题。在问他们之前,我只想指定我在带有OSX,英特尔处理器和nvidia GPU的机器上使用Python 3的最后一个anaconda发行版。另外,我相信我可以将我的ndarrays扁平化,将我的问题简化为一个简单的矩阵矩阵问题。

1)似乎BLAS/MKL库可以提供很好的增加。当在OSX中使用Ananaconda时,似乎MKL本身也与Python链接。因此,我是否直到现在才使用MKL,而不知道它? NP。 配置 .show()给了我这样的东西:

openblas_lapack_info: 
    NOT AVAILABLE 
blas_opt_info: 
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)] 
    include_dirs = ['//anaconda/include'] 
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread'] 
    library_dirs = ['//anaconda/lib'] 
lapack_opt_info: 
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)] 
    include_dirs = ['//anaconda/include'] 
    libraries = ['mkl_lapack95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread'] 
    library_dirs = ['//anaconda/lib'] 
lapack_mkl_info: 
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)] 
    include_dirs = ['//anaconda/include'] 
    libraries = ['mkl_lapack95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread'] 
    library_dirs = ['//anaconda/lib'] 
blas_mkl_info: 
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)] 
    include_dirs = ['//anaconda/include'] 
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread'] 
    library_dirs = ['//anaconda/lib'] 
mkl_info: 
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)] 
    include_dirs = ['//anaconda/include'] 
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread'] 
    library_dirs = ['//anaconda/lib'] 

这是否真的给与einsum功能的速度增加?如果没有,我怎样才能设法访问,例如,来自Python的MKL gemm函数?

2)这些Python库中的任何一个对我的问题是否有用:Theanos,Numba,Cupy?或者只是蟒蛇加速?来自Anaconda Accelerate的cuBlas是否会成为我的最佳选择(也就是说我很想用单精度或半精度)?

3)这会很有用,重新编码我的算法,例如,C或C++?

4)我尝试使用稀疏矩阵(scipy.sparse.csc_matrix)实现我的算法,但它使我的程序慢了很多。那是可以预料的还是我犯了一个错误?

我知道这会让很多问题,但这是我第一次遇到这类问题和互联网是不是真的明确对...

非常感谢!

回答

0

好的,因为我在这些最后的日子里花了很多时间来调查我的问题,所以我可以给与我一样迷路的人们提供一些答案。所以:

1)是的,默认情况下MKL是通过anaconda本地安装的(但这并不总是如此)。但是,np.einsum不能从中获益,因为它不使用BLAS优化的点numpy函数。因此,试图从mkl手动访问gemm函数是没有用的(即使库anaconda加速实际上很容易)。使用np.tensordot,np.multiply和其他方法重写np.einsum的操作会更容易。

2)我没有时间去探索所有我问过的库,但是一个tensordot Theanos操作显然不会比简单的np.tensordot快。同样,几年前情况并非如此,因为np.tensordot操作并未将BLAS用于多维数组。关于所有的cuda库,似乎它们与MKL相比实际上并不出色,除非你有非常强大的CGU(例如参见https://larsjuhljensen.wordpress.com/2011/01/28/commentary-the-gpu-computing-fallacy/

3)将用MKL优化的一些Python代码重写到C++中(见Benchmarking (python vs. c++ using BLAS) and (numpy)

4)仍然不知道为什么我的稀疏矩阵实现比密集矩阵慢。我很可能犯了错误。

相关问题