gensim - Doc2Vec:在英语维基百科上训练时的MemoryError

时间:2018-05-17 11:35:16

标签: python out-of-memory gensim doc2vec

我从英语维基百科转储中提取了145,185,965个句子(14GB),我想根据这些句子训练一个Doc2Vec模型。不幸的是,我只有'32GB的RAM,并且在尝试训练时得到 MemoryError 。即使我将min_count设置为50,gensim告诉我它需要超过150GB的RAM。我不认为进一步增加min_count是个好主意,因为结果模型不是很好(只是一个猜测)。但无论如何,我会用500来试试看内存是否足够。

有没有可能用有限的RAM训练这么大的模型?

这是我目前的代码:

corpus = TaggedLineDocument(preprocessed_text_file)
model = Doc2Vec(vector_size=300, 
                window=15, 
                min_count=50,  #1
                workers=16, 
                dm=0, 
                alpha=0.75, 
                min_alpha=0.001, 
                sample=0.00001,
                negative=5)
model.build_vocab(corpus)
model.train(corpus, 
            epochs=400, 
            total_examples=model.corpus_count, 
            start_alpha=0.025, 
            end_alpha=0.0001)

我可能会犯一些明显的错误吗?使用它完全错了吗?

我也可以尝试减少矢量大小,但我认为这会导致更糟糕的结果,因为大多数论文都使用300D矢量。

1 个答案:

答案 0 :(得分:3)

可寻址存储器中所需的模型大小很大程度上取决于所需的权重数量,唯一字数和唯一doc标签的数量。

拥有145,000,000个独特的doc-tags,无论你限制自己有多少单词,只需要训练中的原始doc-vectors就可以了:

145,000,000 * 300 dimensions * 4 bytes/dimension = 174GB

您可以尝试较小的数据集。您可以减小矢量大小。你可以获得更多的记忆。

我会首先尝试其中的一个或多个,只是为了验证你能够让事情有效并取得一些初步结果。

有一个技巧,最好被认为是实验性的,可以用来培训更大的doc-vector集合,但代价是额外的复杂性和较低的性能:docvecs_mapfile的{​​{1}}参数。 / p>

通常,您不希望Doc2Vec / Word2Vec式训练会话使用任何虚拟内存,因为任何使用较慢磁盘IO的方法都会导致训练速度极慢。但是,对于只在一个顺序中迭代的大型doc-set,在使doc-vectors数组由内存映射文件支持之后,性能命中可能是可存活的。基本上,每个训练传递从字体到后面扫描文件,一次读取每个部分并将其分页一次。

如果提供Doc2Vec参数,docvecs_mapfile将分配doc-vectors数组以供该磁盘文件支持。因此,您将在磁盘上拥有数百GB的文件(理想情况下为SSD),其范围根据需要在RAM中进行分页。

如果您尝试这样做,请务必首先在小型运行中试验此选项,以熟悉其操作,尤其是在保存/加载模型时。

另请注意,如果您在doc-vectors上执行默认Doc2Vec,则必须从原始数组创建另一个174GB的单位规范化向量数组。 (您可以强制执行此操作,通过在调用需要单元规范向量的任何其他方法之前显式调用most_similar()调用来破坏现有原始值。)