如何加快Word2Vec对海量数据的初始词汇扫描?



我现在有一个海量的数据语料库数据集,它大约有110亿个句子,每个句子大约有10个单词,分成12000多个以。txt.gz结尾的文件。我希望用Gensim的Word2Vec跳过它。我使用Gensim的多文件流方法PathLineSentences来读取数据。

sentences=PathLineSentences('path')
w2vModel=Word2Vec(sentences,
vector_size=128, 
window=5, 
min_count=2,
workers=24,
epochs=200,
sg=1,
hs=1,
batch_words=100000,
compute_loss=True)

但是我发现了一个问题,训练前的词汇表扫描阶段很慢(因为它只能在单线程中运行?),以下是TOP命令信息的截图:在这里输入图像描述它已经像上面那样运行了将近12个小时。这个阶段的词汇表扫描是否可以是多线程的,或者是否有其他方法可以加快速度?谢谢大家。下面是我的回调函数:

class callback(CallbackAny2Vec):
def __init__(self,path_prefix):
self.epoch = 0
self.path_prefix = path_prefix
self.loss_to_be_subed = 0
self.start_time = datetime.now()
self.end_time = datetime.now()
def on_epoch_begin(self,model):
self.start_time = datetime.now()
print('Epoch {} start'.format(self.epoch))
def on_epoch_end(self, model):
self.end_time = datetime.now()
loss = model.get_latest_training_loss()/100000
loss_now = loss - self.loss_to_be_subed
self.loss_to_be_subed = loss
print('Loss after epoch {}: {}'.format(self.epoch, loss_now))
print("Epoch {} end".format(self.epoch))
output_path = '{}_epoch_{}.model'.format(self.path_prefix, self.epoch)
model.save(output_path)
print('duration of epoch {} is {}n'.format(self.epoch,self.end_time-self.start_time))
self.epoch += 1

最初的词汇表扫描不幸是单线程的:它必须一次读取所有数据,计算所有单词,以确定哪些罕见的单词将被忽略,并按频率顺序对所有其他单词进行排序。

如果您避免将sentences语料库传递给初始构造函数,则可以对该过程进行更多的控制。相反,将其关闭,然后调用后面的步骤.build_vocab()&.train()自己。(.build_vocab()步骤将是长单线程步骤。)然后,您可以选择在.build_vocab()完成后保存模型。(可能,然后,你可以重新加载它,修补一些设置,并运行其他训练课程,而不需要完全重复扫描。)

另外,如果你刚刚开始,我建议你用一个较小的数据集进行初始试验——也许只是整个语料库的1/10或1/20的抽样——这样你就可以让你的过程工作,&在尝试完整的训练之前,稍微优化了一下。

单独,关于您的隐含设置:

  • 使用低至min_count=2的值对于Word2Vec通常是一个坏主意&相关的算法。该模型只能为具有多种用法的单词实现有用的向量-因此类的默认值min_count=5是一个很好的最小值,当使用较大的语料库(如您的语料库)时,增加这个下限比降低它更有意义。(虽然增加min_count不会加快词汇调查的速度,但它会加快培训的速度。通常可以提高剩余单词向量的质量,因为没有罕见单词的"噪声",其他单词的训练效果会更好。
  • 即使你的机器有24个CPU内核,在传统的(语料库-迭代器)模式下,Word2Vec训练吞吐量通常在6-12个工人的范围内达到最大值(主要是由于Python GIL瓶颈)。较高的值会减慢速度。(不幸的是,只有通过试验才能找到最佳价值& &;错误-开始训练&在几分钟内观察记录的速率-以及最佳的工作人员数量将随着其他设置(如windownegative)而改变。
  • 对于如此大的数据集,epochs=200是过度的(并且可能需要很长时间)。对于大型数据集,您更有可能使用少于默认的epochs=5,而不是需要使用更多。
  • 通过设置hs=1而不设置negative=0,您已经启用了分层softmax训练,同时保留默认的负采样活动。这可能会使你的训练时间至少增加一倍。让你的模型更大,没有任何好处。对于一个大型数据集,考虑hs=0模式是很奇怪的——它在更大的模型中变得不那么高效。(你应该避免触摸hs的值,除非你确定你需要。)
  • 同样,不清楚为什么要更改batch_words&compute_loss。(损失计数会减慢速度,但也不是很好用——所以很少需要。)一般来说,你的设置改变了很多东西最好保持不变,除非/直到你确定你可以测量变化的净效果。

最新更新