Gensim Word2Vec使用太多内存

时间:2017-10-23 21:48:12

标签: python-3.x memory word2vec gensim

我想在大小为400MB的标记化文件上训练word2vec模型。我一直在尝试运行这个python代码:

import operator
import gensim, logging, os
from gensim.models import Word2Vec
from gensim.models import *

class Sentences(object):
    def __init__(self, filename):
        self.filename = filename

    def __iter__(self):
        for line in open(self.filename):
            yield line.split()

def runTraining(input_file,output_file):
    logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
    sentences = Sentences(input_file)
    model = gensim.models.Word2Vec(sentences, size=200)
    model.save(output_file)

当我在我的文件上调用此函数时,我得到了这个:

2017-10-23 17:57:00,211 : INFO : collecting all words and their counts
2017-10-23 17:57:04,071 : INFO : PROGRESS: at sentence #0, processed 0 words, keeping 0 word types
2017-10-23 17:57:16,116 : INFO : collected 4735816 word types from a corpus of 47054017 raw words and 1 sentences
2017-10-23 17:57:16,781 : INFO : Loading a fresh vocabulary
2017-10-23 17:57:18,873 : INFO : min_count=5 retains 290537 unique words (6% of original 4735816, drops 4445279)
2017-10-23 17:57:18,873 : INFO : min_count=5 leaves 42158450 word corpus (89% of original 47054017, drops 4895567)
2017-10-23 17:57:19,563 : INFO : deleting the raw counts dictionary of 4735816 items
2017-10-23 17:57:20,217 : INFO : sample=0.001 downsamples 34 most-common words
2017-10-23 17:57:20,217 : INFO : downsampling leaves estimated 35587188 word corpus (84.4% of prior 42158450)
2017-10-23 17:57:20,218 : INFO : estimated required memory for 290537 words and 200 dimensions: 610127700 bytes
2017-10-23 17:57:21,182 : INFO : resetting layer weights
2017-10-23 17:57:24,493 : INFO : training model with 3 workers on 290537 vocabulary and 200 features, using sg=0 hs=0 sample=0.001 negative=5 window=5
2017-10-23 17:57:28,216 : INFO : PROGRESS: at 0.00% examples, 0 words/s, in_qsize 0, out_qsize 0
2017-10-23 17:57:32,107 : INFO : PROGRESS: at 20.00% examples, 1314 words/s, in_qsize 0, out_qsize 0
2017-10-23 17:57:36,071 : INFO : PROGRESS: at 40.00% examples, 1728 words/s, in_qsize 0, out_qsize 0
2017-10-23 17:57:41,059 : INFO : PROGRESS: at 60.00% examples, 1811 words/s, in_qsize 0, out_qsize 0
Killed

我知道word2vec需要很多空间,但我仍然认为这里存在问题。如您所见,此型号的估计内存为600MB,而我的计算机有16GB的RAM。然而,在代码运行时监视进程表明它占用了我所有的内存,然后被杀死。

正如其他帖子所说,我试图增加min_count并减小尺寸。但即使有可笑的值(min_count = 50,size = 10),过程也会停止在60%。

我还试图让python成为OOM的一个例外,这样就不会杀死进程。当我这样做时,我有一个MemoryError而不是杀戮。

发生了什么事?

(我最近使用的是Ubuntu 17.04,16GB内存和Nvidia GTX 960M的笔记本电脑。我从Anaconda和gensim 3.0运行python 3.6,但它对gensim 2.3没有做得更好)

1 个答案:

答案 0 :(得分:0)

您的文件是一行,如日志输出所示:

2017-10-23 17:57:16,116 : INFO : collected 4735816 word types from a corpus of 47054017 raw words and 1 sentences

这是你想要的,这是值得怀疑的;特别是gensim的Word2Vec中优化的cython代码只能在截断它们之前处理10,000个单词的句子(并丢弃其余的单词)。因此,大多数数据在培训期间都没有被考虑(即使它已经完成)。

但更大的问题是,单个4700万字的行将作为一个巨大的字符串进入内存,然后split()成为一个4700万条目的字符串列表。因此,尝试使用内存高效的迭代器并没有任何帮助 - 整个文件被带入内存,两次,一次'迭代'。

我仍然没有看到使用完整的16GB RAM,但也许正在纠正这将解决问题,或使任何剩余的问题更明显。

如果您的标记化数据没有10,000个令牌句长度周围或以下的自然换行符,您可以查看gensim中包含的示例语料库类LineSentence如何能够处理(也是缺少换行符text8text9语料库,将每个产生的句子限制为10,000个令牌:

https://github.com/RaRe-Technologies/gensim/blob/58b30d71358964f1fc887477c5dc1881b634094a/gensim/models/word2vec.py#L1620

(它可能不是一个促成因素,但您可能还想使用with上下文管理器来确保在迭代器用完后立即关闭open() ed文件。)