我正在尝试使用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_before
和wv_after
完全相同
因此,很有可能破坏某些东西,也许甚至阻止尝试任何训练。
[是否有合理的日志记录输出(级别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-05
,1e-06
等)以丢弃大部分的最常用单词,以便进行更快的训练,这通常也可以提高整体单词向量的质量(通过花费相对较少的字词需要更多的精力)。
如果速度仍然太慢,请考虑是否可以使用较小的语料库子样本就足够了。
请考虑corpus_file
方法,如果您可以将大量或全部数据滚动到所需的单个文件中。