为大量数据集加快Gensim的Word2vec的速度

问题描述 投票:0回答:1

我正在尝试使用Gensim在庞大的数据集上构建一个Word2vec(或FastText)模型,该数据集由1000个文件组成,每个文件包含〜210,000个句子,每个句子包含〜1000个单词。培训是在185gb RAM,36核计算机上进行的。我验证过

gensim.models.word2vec.FAST_VERSION == 1

首先,我尝试了以下方法:

files = gensim.models.word2vec.PathLineSentences('path/to/files')
model = gensim.models.word2vec.Word2Vec(files, workers=-1)

但是经过13个小时,我认为它已运行太长时间并停止了它。

然后,我尝试根据单个文件构建词汇表,并根据所有1000个文件进行训练,如下所示:

files = os.listdir['path/to/files']
model = gensim.models.word2vec.Word2Vec(min_count=1, workers=-1)
model.build_vocab(corpus_file=files[0])
for file in files:
    model.train(corpus_file=file, total_words=model.corpus_total_words, epochs=1)

但是我在训练前后检查了单词向量的样本,并且没有变化,这意味着没有进行实际的训练。

我可以就如何快速成功地运行它提供一些建议。谢谢!

更新#1:

这里是检查向量更新的代码:

file = 'path/to/single/gziped/file'
total_words = 197264406 # number of words in 'file'
total_examples = 209718 # number of records in 'file'
model = gensim.models.word2vec.Word2Vec(iter=5, workers=12)
model.build_vocab(corpus_file=file)
wv_before = model.wv['9995']
model.train(corpus_file=file, total_words=total_words, total_examples=total_examples, epochs=5)
wv_after = model.wv['9995']

所以向量:wv_beforewv_after完全相同

gensim word2vec fasttext
1个回答
0
投票
负值。 (您从哪里得到有意义的想法?)

因此,很有可能破坏某些东西,也许甚至阻止尝试任何训练。

[是否有合理的日志记录输出(级别INFO)表明培训在针对PathLineSentences还是您的第二次尝试正在进行中?诸如top之类的实用程序是否显示繁忙的线程?输出是否暗示了特定的进度,并让您预测了可能的完成时间?

我建议使用正的workers值并观察INFO级别的日志记录,以更好地了解发生了什么。

[不幸的是,即使使用36个内核,使用语料库可迭代序列(如PathLineSentences)也会将gensim Word2Vec放入模型中,如果使用workers值在8-16范围内,您可能会获得最大吞吐量,远远少于所有线程。但是,即使它是通过可迭代的序列即时组合而成的,它也可以对任何大小的语料库进行正确的处理。

使用corpus_file模式可以使更多的内核饱和,但是您仍应指定要使用的实际工作线程数-在您的情况下为workers=36-并且它旨在从包含所有数据的单个文件上进行工作。 。

您尝试用train()多次执行corpus_file的代码有很多问题,我想不出一种使corpus_file模式适应于许多文件的方法。一些问题包括:

    您仅从第一个文件构建词汇表,这意味着仅出现在其他文件中的任何单词都将被未知和忽略,并且Word2Vec算法的任何单词频率驱动部分都可以正常工作代表]]
  • 模型从model.corpus_total_words步骤建立其预期语料库大小(例如:build_vocab())的估计,因此在其进度报告中,每个train()都会表现得好像该大小是总语料库大小一样和内部alpha学习率衰减的管理。因此,这些日志将是错误的,alpha将在每个train()中以新的衰减进行错误地管理,从而导致所有文件的alpha上下乱七八糟的拼图。

  • 您只需要遍历每个文件的内容一次,这是不典型的。 (不过,如果每个文件的文本均等且随机地代表域,那么对于一个2,100亿个巨大的语料库来说,这可能是合理的。在这种情况下,完整的语料库一次可能和遍历1/5的语料库一样好。大小的5倍。但是,如果某些单词/使用模式全部集中在某些文件中,这将是一个问题-最好的训练会在每个时期和所有时期插入对比示例。)

  • min_count=1对于这种算法几乎总是不明智的,尤其是在典型自然语言词频的大型语料库中。稀有单词,尤其是那些仅出现一次或几次的单词,会使模型变得巨大,但这些单词将无法获得良好的单词向量,并使它们保持类似噪音的状态,从而干扰了其他更常见单词的改进。

  • 我推荐:

尝试使用语料库可重复序列模式,并进行记录和合理的workers值,以至少准确地了解它可能需要花费多长时间。 (最长的步骤将是初始词汇扫描,该扫描实质上是单线程的,并且必须访问所有数据。但是您可以在该步骤之后将模型.save()删除,然后再重新进行.load()修改设置,然后尝试不同的train()方法,而无需重复慢速词汇调查。)

尝试使用更高的min_count值(对于更小的模型和更快的训练,请丢弃更多的稀有词)。也许还尝试大胆地降低sample的值(例如1e-051e-06等)以丢弃大部分的最常用单词,以便进行更快的训练,这通常也可以提高整体单词向量的质量(通过花费相对较少的字词需要更多的精力)。

如果速度仍然太慢,请考虑是否可以使用较小的语料库子样本就足够了。

请考虑corpus_file方法,如果您可以将大量或全部数据滚动到所需的单个文件中。

© www.soinside.com 2019 - 2024. All rights reserved.