内存错误:使用Python的word2vec时无法分配形状和数据类型为float32的数组。

4
我正在尝试使用维基百科文本数据训练word2vec模型,下面是我使用的代码。
import logging
import os.path
import sys
import multiprocessing

from gensim.corpora import  WikiCorpus
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence


if __name__ == '__main__':
    program = os.path.basename(sys.argv[0])
    logger = logging.getLogger(program)

    logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s')
    logging.root.setLevel(level=logging.INFO)
    logger.info("running %s" % ' '.join(sys.argv))

    # check and process input arguments

    if len(sys.argv) < 3:
        print (globals()['__doc__'])
        sys.exit(1)
    inp, outp = sys.argv[1:3]

    model = Word2Vec(LineSentence(inp), size=400, window=5, min_count=5, workers=multiprocessing.cpu_count())

    # trim unneeded model memory = use (much) less RAM
    model.init_sims(replace=True)

    model.save(outp)

但是在程序运行20分钟后,我遇到了以下错误:错误信息

1
所以,你遇到了内存错误。你尝试在的机器上运行Word2Vec,但是它没有足够的内存来处理整个输入。考虑缩小输入或者阅读分布式框架的相关资料。 - Oliver W.
@ Oliver W. 您能告诉我如何使用分布式框架来完成这个任务吗?因为我在这个领域还很新。我正在使用 Windows 机器。 - suraj
这是一个非常广泛的问题,Suraj,我认为你最好先阅读一些资料。看看现代框架,比如Apache Spark。但是你要问自己是否需要它?也许你只需要减少问题的规模? - Oliver W.
4个回答

6
理想情况下,您应该将错误的文本粘贴到问题中,而不是截图。但是,我看到了两个关键行:
<TIMESTAMP> : INFO : estimated required memory for 2372206 words and 400 dimensions: 8777162200 bytes
...
MemoryError: unable to allocate array with shape (2372206, 400) and data type float32

在对语料库进行一次扫描后,模型已经学会了有多少个唯一单词将被保留,并报告需要分配多大的模型:大约需要 8777162200 字节(约8.8GB)的模型。但是,在尝试分配所需的向量数组时,出现了 MemoryError,这表明计算机可寻址内存(RAM)不足。
您可以选择以下两种方案之一:
  1. 在具有更多内存的地方运行,例如通过为现有系统添加RAM;或
  2. 减少所需内存的数量,主要方法是减少要训练的唯一单词向量的数量或其维数大小。
您可以通过增加默认的 min_count=5 参数来减少单词数量,例如将其设为 min_count=10min_count=20min_count=50。(您可能不需要超过200万个单词向量,只使用几万个单词的词汇表就可以得到许多有趣的结果。)
您还可以设置一个 max_final_vocab 值,以指定要保留的唯一单词的确切数量。例如,max_final_vocab=500000 将仅保留最常见的 500,000 个单词,忽略其余的单词。
减小 size 值也可以节省内存。对于单词向量,size=300 设置很受欢迎,并且可以将内存要求减少四分之一。
综上所述,使用 size=300, max_final_vocab=500000 可以将所需的内存缩减到 2GB 以下。

1
从现在开始,我将粘贴错误文本。感谢您提供的精彩描述和解决方案。 - suraj
在向量化器中,“size”实际上测量的是什么? - user3710004
在这些word2vec实现中,“size”通常指训练的单词向量中的维数。(在Gensim的最新版本中,此参数的名称已更改为“vector_size”。) - gojomo

1
我在处理pandas dataframe时遇到了同样的问题,通过将float64类型转换为uint8解决了这个问题(当然对于不一定需要float64的情况,您可以尝试使用float32代替64)。
data['label'] = data['label'].astype(np.uint8)
如果遇到转换错误
data['label'] = data['label'].astype(np.uint8, errors='ignore')

0

我不确定在这种情况下是否有效,但您可以通过使用SSD中的空间来增加系统的虚拟内存量。

当运行算法所需的RAM过高时,我在不同的项目中都尝试过这种方法,效果很好。

-转到“开始”菜单并单击“设置”。 -输入“性能”。 -选择“调整Windows外观和性能”。 -在新窗口中,转到“高级”选项卡,在虚拟内存部分下,单击“更改”。 -在新窗口底部,检查推荐值与当前分配值的比较。 您可以超过推荐值。


-1
尝试了许多方法例如修改虚拟内存和重新安装Python之后,对我有效的做法是将numpy的dtype从默认的float64修改为float32。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接