【问题标题】:Doc2vec MemoryErrorDoc2vec 内存错误
【发布时间】:2015-08-09 21:45:52
【问题描述】:

我正在使用来自 teh gensim 框架的 doc2vec 模型来表示一个包含 1550 万个短文档(最多 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 swap 的 Ubuntu 机器。我检查了内存分配(在 htop 中),我观察到内存从未被完全使用过。我还将python中可能锁定在内存中的最大地址空间设置为无限制:

resource.getrlimit(resource.RLIMIT_MEMLOCK)

有人能解释一下这个 MemoryError 的原因吗?在我看来,可用内存应该足以进行此计算。可能是 python 或 OS 中的一些内存限制?

提前致谢!

【问题讨论】:

    标签: python memory gensim word2vec


    【解决方案1】:

    18M 向量 * 400 维 * 4 字节/浮点数 = 28.8GB 用于模型的 syn0 数组(经过训练的向量)

    syn1 数组(隐藏的权重)也将是 28.8GB——尽管 syn1 并不真正需要 doc-vectors 条目,这些条目在训练期间绝不是目标预测。

    词汇结构(vocab dict 和 index2word 表)可能会增加另一个 GB 或更多。这就是你所有的 60GB RAM。

    用于相似度计算的 syn0norm 数组将需要另外 28.8GB,总使用量约为 90GB。这是您遇到错误的 syn0norm 创建。但即使 syn0norm 创建成功,那么深入虚拟内存也可能会破坏性能。

    一些可能有帮助的步骤:

    • 使用至少 2 的 min_count:出现一次的单词不太可能贡献太多,但可能会占用大量内存。 (但由于单词只是 syn0 的一小部分,因此只会节省一点。)

    • 在训练之后但在触发 init_sims() 之前,丢弃 syn1 数组。您将无法进行更多训练,但您现有的 word/doc 向量仍然可以访问。

    • 在训练之后调用 most_similar() 之前,使用 replace=True 参数自己调用 init_sims(),以丢弃未归一化的 syn0 并用 syn0norm 替换它。同样,您将无法进行更多训练,但您将节省 syn0 内存。

    正在进行的分离文档和词向量的工作,将出现在 gensim 0.11.1 之前的版本中,最终也应该会提供一些缓解。 (它会将 syn1 缩小为仅包含单词条目,并允许 doc-vectors 来自文件支持的(memmap'd)数组。)

    【讨论】:

    • 我按照你的建议做了,我设置了 min_count = 2 并消除了 syn1 数组,它工作了:)。但是,您能解释一下为什么,如果我有 60Gb RAM 和 70Gb Swap(总共 130Gb 内存),当系统需要大约 90Gb 的内存时系统无法工作? gensim word2vec 实现是否需要适应 RAM 中的所有信息?谢谢你!
    • Gensim 的 word2vec 需要可寻址空间中的结构,但不一定需要 RAM。尽管如此,您永远不想依赖交换来获取主动、随机访问的大数据。 60GB RAM 用于 syn0 和 syn1; 30GB 用于 syn0norm(但请参阅上面新的第三个项目符号以获得另一个建议)——然后 most_similar() 对每个向量执行一个数组距离,暂时使用另外 30GB(但我认为一些即将到来的修复将允许这样做是小批量)。在考虑任何其他内存使用/碎片/低效率之前,这是 120GB。即使它有效,交换也可能会使性能变得糟糕。
    • 如何消除 syn1 数组?
    • 与任何其他 Python 对象属性一样,您可以使用 del 将其删除,例如 del model.syn1。 (或者在更常见的情况下,使用负采样,因此只有syn1neg 存在,del model.syn1neg。)但如前所述,这会破坏模型的一个重要部分,并且只有在你只一直在查找单词/文档向量(从不重新训练或推断)。在这种情况下,最新版本的 gensim 让您只保存/加载/操作向量集。 (上面的答案是3岁以上。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    • 2011-09-27
    • 2011-04-08
    相关资源
    最近更新 更多