gensim LdaMulticore and OpenMP BLAS

watbbzwu  于 4个月前  发布在  其他
关注(0)|答案(3)|浏览(136)

许多Python安装程序如今使用与高度优化的BLAS链接的numpy版本,默认情况下,它会使用尽可能多的核心。这意味着在一台六核机器上运行LdaMulticoreworkers=5时,最终尝试使用30个核心,性能受到严重影响。
以这个测试程序为例:

from gensim.corpora import Dictionary
from gensim.models import LdaModel, LdaMulticore
from nltk.corpus import brown
from time import perf_counter

vocab = Dictionary(brown.words(f) for f in brown.fileids())
vocab.filter_extremes(no_below=50, no_above=0.5)
corpus = [vocab.doc2bow(brown.words(f)) for f in brown.fileids()]

start = perf_counter()
lda = LdaModel(corpus=corpus, id2word=vocab, num_topics=100, chunksize=50, passes=5)
print('%15s %5.2f'%('LdaModel', perf_counter()-start))

start = perf_counter()
lda = LdaMulticore(corpus=corpus, id2word=vocab, num_topics=100, chunksize=50, passes=5,
                                     workers=5)
print('%15s %5.2f'%('LdaMulticore', perf_counter()-start))

在一台六核CPU上使用Intel Python发行版运行,我得到:

LdaModel 10.38
   LdaMulticore 14.24

但是,当将MKL_NUM_THREADS设置为1以禁用numpy内部的并行性时,我得到:

LdaModel 20.46
   LdaMulticore  4.85

使用Intel的并行MKL BLAS,LdaModel实际上比LdaMulticore更快,尽管单线程BLAS的LdaMulticore是目前最快的。
据我所知,没有一种可移植且可靠的方法来控制numpy数值核心可能使用的线程数,所以目前也许最好的办法是在文档中添加关于这个问题的警告。

brqmpdu1

brqmpdu11#

你好,@rmalouf,谢谢你的报告。我知道这个问题(这个变体稍微宽一点,因为有很多可能的"后端"),据我所知,最宽的变体是

export MKL_NUM_THREADS=1
export NUMEXPR_NUM_THREADS=1
export OMP_NUM_THREADS=1

是的,我们确实需要在文档中添加一些关于它的警告+有一个小型的"上下文管理器"或者类似的东西会很好,它可以设置这些变量(并在退出后恢复旧值)。
此外,在有/没有这些变量的情况下进行一些基准测试也是一个好主意。
@piskvorky wdyt?

ee7vknir

ee7vknir2#

是的,好主意。

这个主题对大多数人来说太晦涩了,所以一个很大的警告“你正在运行并行化的LDA,但你的BLAS已经并行化了——你应该做X”会有所帮助。

甚至更好,自动透明地选择这两个参数(#workers / BLAS线程),在一定程度上可以自动设置。但是我们应该为高级用户留下一个覆盖这些自动设置的选择。

fkvaft9z

fkvaft9z3#

嗯,这确实是一个非常微妙的问题,如何选择最优的变体。当我遇到这个问题时,我有一个简单的“视觉”标准:如果我在htop输出中看到很多“红色”(这只是个可视化示例,与LDA没有直接关系),

这意味着我需要导出这些变量和 =1 。当然,需要使用不同的标志进行适当的基准测试(并与 LdaModel 进行比较)

相关问题