2016-11-07 60 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)仍然不知道爲什麼我的稀疏矩陣實現比密集矩陣慢。我很可能犯了錯誤。