我正在使用teh gensim框架中的doc2vec模型来表示15 500 000个短文档(最多300个单词)的语料库:
gensim.models.Doc2Vec(sentences, size=400, window=10, min_count=1, workers=8 )
创建向量后,有超过18 000 000个向量代表单词和文档。
我想找到给定项目最相似的项目(单词或文档):
similarities = model.most_similar(‘uid_10693076’)
但是在计算相似度时我得到了一个MemoryError:
Traceback (most recent call last):
File "article/test_vectors.py", line 31, in <module>
similarities = model.most_similar(item)
File "/usr/local/lib/python2.7/dist-packages/gensim/models/word2vec.py", line 639, in most_similar
self.init_sims()
File "/usr/local/lib/python2.7/dist-packages/gensim/models/word2vec.py", line 827, in init_sims
self.syn0norm = (self.syn0 / sqrt((self.syn0 ** 2).sum(-1))[..., newaxis]).astype(REAL)
我有一台配备60GB Ram和70GB交换机的Ubuntu机器。我检查了内存分配(在htop中),我发现永远不会完全使用内存。我还设置了无限制的最大地址空间,可以在python中锁定在内存中:
resource.getrlimit(resource.RLIMIT_MEMLOCK)
有人可以解释这个MemoryError的原因吗?在我看来,可用的内存应该足以进行这种计算。可能是python或OS中的一些内存限制?
提前致谢!
答案 0 :(得分:13)
18M向量* 400维* 4字节/浮点数= 28.8GB,用于模型的syn0数组(训练向量)
syn1数组(隐藏权重)也将是28.8GB - 尽管syn1并不真正需要doc-vectors的条目,这些条目在训练期间绝不是目标预测。
词汇结构(词汇dict和index2word表)可能会增加另一个GB或更多。这就是你所有的60GB内存。
用于相似度计算的syn0norm数组需要另外28.8GB,总使用量约为90GB。这是syn0norm创建,你得到错误。但即使syn0norm创建成功,深入虚拟内存也可能会破坏性能。
可能会有所帮助的一些步骤:
使用至少为2的min_count:出现一次的单词不太可能贡献太多,但可能会占用大量内存。 (但由于单词是你的syn0的一小部分,这只会节省一点。)
训练之后但在触发init_sims()之前,丢弃syn1数组。您将无法训练更多,但您现有的word / doc向量仍可访问。
在训练之后但在调用most_similar()之前,请使用replace = True参数自行调用init_sims(),以丢弃非规范化的syn0并将其替换为syn0norm。再次,你将无法训练更多,但你将保存syn0内存。
分离出文档和单词向量的正在进行的工作,这将出现在过去0.11.1的gensim中,最终也应该提供一些缓解。 (它会将syn1缩小为仅包含单词条目,并允许doc-vectors来自文件支持(memmap'd)数组。)