gensim word2vec的训练时间
Training time of gensim word2vec
我正在 34 GB 预处理 MS_MARCO 语料库(22 GB)上从头开始训练 word2vec。 (预处理语料库是 sentnecepiece 标记化的,因此它的大小更大)我正在使用以下代码训练我的 word2vec 模型:
from gensim.test.utils import common_texts, get_tmpfile
from gensim.models import Word2Vec
class Corpus():
"""Iterate over sentences from the corpus."""
def __init__(self):
self.files = [
"sp_cor1.txt",
"sp_cor2.txt",
"sp_cor3.txt",
"sp_cor4.txt",
"sp_cor5.txt",
"sp_cor6.txt",
"sp_cor7.txt",
"sp_cor8.txt"
]
def __iter__(self):
for fname in self.files:
for line in open(fname):
words = line.split()
yield words
sentences = Corpus()
model = Word2Vec(sentences, size=300, window=5, min_count=1, workers=8, sg=1, hs=1, negative=10)
model.save("word2vec.model")
我的模型现在 运行 现在大约有 30 多个小时了。这是值得怀疑的,因为在我的 8 核 i5 笔记本电脑上,我每时每刻都在 100% 使用所有 8 核。另外,我的程序现在似乎已经从磁盘读取了超过 100 GB 的数据。我不知道这里有没有问题,但我对训练产生怀疑后的主要原因是因为这 100 GB 从磁盘读取。整个语料库是34GB,那为什么我的代码从磁盘读取了100GB的数据?有谁知道在 34 GB 的文本上训练 word2vec 需要多少时间,8 核 i5 CPU 运行 全部并行?谢谢你。有关更多信息,我还附上了系统监视器中我的过程照片。
我想知道为什么我的模型从内存中读取了 112 GB,即使我的语料库总共是 34 GB?我的训练会结束吗?此外,我有点担心笔记本电脑的健康状况,因为它 运行 自过去 30 小时以来一直处于峰值容量。现在真的很热。
我是否应该在 Word2Vec
中添加任何其他参数以在不损失太多性能的情况下进行更快的训练?
完成模型需要遍历所有数据以发现词汇表,然后进行多次遍历(默认为 5 次)以执行向量训练。因此,仅从模型训练中,您应该期望在磁盘读取中看到大约 6 倍的数据大小。
(如果您的机器最终需要在此过程中使用虚拟内存交换,则可能会有更多磁盘 activity – 但您绝对不希望这种情况发生,因为随机访问模式word2vec 训练几乎是虚拟内存使用的最坏情况,这将极大地减慢训练速度。)
如果您想了解代码的进度,并能够估计其完成时间,您应该至少启用 Python 日志记录到 INFO
级别。该过程的各个步骤将报告中期结果(例如发现的和幸存的词汇量)和估计的进度。您通常可以通过研究合理值的日志输出来判断 运行 结束之前是否出现问题,一旦 'training' 阶段开始,完成时间将是训练的简单预测到目前为止完成。
我相信大多数笔记本电脑应该节流自己的 CPU 如果它变得太热以至于变得不安全或有可能在 CPU/components 上极度磨损,但我不能说你的是否这样做,并绝对确保其风扇正常工作且通风口畅通无阻。
我建议您选择数据的一些随机小子集 – 也许 1GB? – 能够 运行 完成所有步骤,熟悉 Word2Vec
日志输出、资源使用和结果,并在尝试 运行 之前修改设置以观察变化在你的完整数据集上,这可能需要几天的训练时间。
您显示的某些参数不是快速训练的最佳选择。特别是:
min_count=1
保留在语料库调查中看到的每个单词,包括那些只出现一次的单词。这会导致模型大得多——可能会冒模型不适合 RAM 的风险,从而导致灾难性的交换。而且,只有几个用法示例的词不可能获得好的词向量,因为这个过程需要看到许多微妙变化的替代用法。尽管如此,通过典型的 'Zipfian' 词频,仅使用几次的此类词的总数可能非常大,因此保留所有这些词需要大量训练 time/effort,甚至可以提供有点像 'noise' 使其他单词的训练(有大量用法示例)效果不佳。因此,对于模型大小、训练速度、剩余向量的 和 质量,较大的 min_count
是可取的。对于更多的项目,默认的 min_count=5
比 min_count=1
更好——这是一个只有在您确定知道效果的情况下才应该真正更改的参数。而且,当您拥有大量数据时(例如 34GB),min_count
可以更高以保持模型大小易于管理。
hs=1
只有在您想使用 'hierarchical-softmax' 训练模式而不是 'negative-sampling' 时才应启用 – 在这种情况下,negative=0
还应设置为禁用 'negative-sampling'。您可能不想使用 hierarchical-softmax:它不是默认值是有原因的,而且它不能很好地扩展到更大的数据集。但是在这里,除了负采样之外,您还启用了 in,可能会使所需的训练时间增加一倍以上。
您选择 negative=10
是因为默认 negative=5
有问题吗?因为这种非默认选择会再次显着减慢训练速度。 (但同样,这里的非默认选择在较小的数据集上更常见,而像您这样的较大的数据集更有可能尝试较小的 negative
值。)
以上观察的主题是:"only change the defaults if you've already got something working, and you have a good theory (or way of testing) how that change might help"。
对于足够大的数据集,还有另一个默认参数需要考虑更改以加快训练速度(并且通常还会提高词向量质量):sample
,它控制如何积极地高频单词(具有许多冗余用法示例)可能会被下采样(随机跳过)。
默认值 sample=0.001
(又名 1e-03
)非常保守。较小的值,例如 sample=1e-05
,将丢弃更多最常用词的冗余用法示例,从而显着加快整体训练速度。 (而且,对于您这种规模的语料库,您最终可以尝试使用更小、更具攻击性的值。)
最后,如果您的所有数据(对于完整 运行 或子集 运行)都可以在一个已经用 space 分隔的文本文件中,您可以使用 corpus_file
指定语料库的替代方法。然后,Word2Vec
class 将使用优化的多线程 IO 方法将文件的各个部分分配给备用工作线程——如果您之前没有看到所有 threads/CPU-cores 的完全饱和,可以增加我们的吞吐量。 (我会把它推迟到尝试其他事情之后,然后检查你的最佳设置是否仍然让你的 8 个线程中的一些线程经常空闲。)
我正在 34 GB 预处理 MS_MARCO 语料库(22 GB)上从头开始训练 word2vec。 (预处理语料库是 sentnecepiece 标记化的,因此它的大小更大)我正在使用以下代码训练我的 word2vec 模型:
from gensim.test.utils import common_texts, get_tmpfile
from gensim.models import Word2Vec
class Corpus():
"""Iterate over sentences from the corpus."""
def __init__(self):
self.files = [
"sp_cor1.txt",
"sp_cor2.txt",
"sp_cor3.txt",
"sp_cor4.txt",
"sp_cor5.txt",
"sp_cor6.txt",
"sp_cor7.txt",
"sp_cor8.txt"
]
def __iter__(self):
for fname in self.files:
for line in open(fname):
words = line.split()
yield words
sentences = Corpus()
model = Word2Vec(sentences, size=300, window=5, min_count=1, workers=8, sg=1, hs=1, negative=10)
model.save("word2vec.model")
我的模型现在 运行 现在大约有 30 多个小时了。这是值得怀疑的,因为在我的 8 核 i5 笔记本电脑上,我每时每刻都在 100% 使用所有 8 核。另外,我的程序现在似乎已经从磁盘读取了超过 100 GB 的数据。我不知道这里有没有问题,但我对训练产生怀疑后的主要原因是因为这 100 GB 从磁盘读取。整个语料库是34GB,那为什么我的代码从磁盘读取了100GB的数据?有谁知道在 34 GB 的文本上训练 word2vec 需要多少时间,8 核 i5 CPU 运行 全部并行?谢谢你。有关更多信息,我还附上了系统监视器中我的过程照片。
我想知道为什么我的模型从内存中读取了 112 GB,即使我的语料库总共是 34 GB?我的训练会结束吗?此外,我有点担心笔记本电脑的健康状况,因为它 运行 自过去 30 小时以来一直处于峰值容量。现在真的很热。
我是否应该在 Word2Vec
中添加任何其他参数以在不损失太多性能的情况下进行更快的训练?
完成模型需要遍历所有数据以发现词汇表,然后进行多次遍历(默认为 5 次)以执行向量训练。因此,仅从模型训练中,您应该期望在磁盘读取中看到大约 6 倍的数据大小。
(如果您的机器最终需要在此过程中使用虚拟内存交换,则可能会有更多磁盘 activity – 但您绝对不希望这种情况发生,因为随机访问模式word2vec 训练几乎是虚拟内存使用的最坏情况,这将极大地减慢训练速度。)
如果您想了解代码的进度,并能够估计其完成时间,您应该至少启用 Python 日志记录到 INFO
级别。该过程的各个步骤将报告中期结果(例如发现的和幸存的词汇量)和估计的进度。您通常可以通过研究合理值的日志输出来判断 运行 结束之前是否出现问题,一旦 'training' 阶段开始,完成时间将是训练的简单预测到目前为止完成。
我相信大多数笔记本电脑应该节流自己的 CPU 如果它变得太热以至于变得不安全或有可能在 CPU/components 上极度磨损,但我不能说你的是否这样做,并绝对确保其风扇正常工作且通风口畅通无阻。
我建议您选择数据的一些随机小子集 – 也许 1GB? – 能够 运行 完成所有步骤,熟悉 Word2Vec
日志输出、资源使用和结果,并在尝试 运行 之前修改设置以观察变化在你的完整数据集上,这可能需要几天的训练时间。
您显示的某些参数不是快速训练的最佳选择。特别是:
min_count=1
保留在语料库调查中看到的每个单词,包括那些只出现一次的单词。这会导致模型大得多——可能会冒模型不适合 RAM 的风险,从而导致灾难性的交换。而且,只有几个用法示例的词不可能获得好的词向量,因为这个过程需要看到许多微妙变化的替代用法。尽管如此,通过典型的 'Zipfian' 词频,仅使用几次的此类词的总数可能非常大,因此保留所有这些词需要大量训练 time/effort,甚至可以提供有点像 'noise' 使其他单词的训练(有大量用法示例)效果不佳。因此,对于模型大小、训练速度、剩余向量的 和 质量,较大的min_count
是可取的。对于更多的项目,默认的min_count=5
比min_count=1
更好——这是一个只有在您确定知道效果的情况下才应该真正更改的参数。而且,当您拥有大量数据时(例如 34GB),min_count
可以更高以保持模型大小易于管理。hs=1
只有在您想使用 'hierarchical-softmax' 训练模式而不是 'negative-sampling' 时才应启用 – 在这种情况下,negative=0
还应设置为禁用 'negative-sampling'。您可能不想使用 hierarchical-softmax:它不是默认值是有原因的,而且它不能很好地扩展到更大的数据集。但是在这里,除了负采样之外,您还启用了 in,可能会使所需的训练时间增加一倍以上。您选择
negative=10
是因为默认negative=5
有问题吗?因为这种非默认选择会再次显着减慢训练速度。 (但同样,这里的非默认选择在较小的数据集上更常见,而像您这样的较大的数据集更有可能尝试较小的negative
值。)
以上观察的主题是:"only change the defaults if you've already got something working, and you have a good theory (or way of testing) how that change might help"。
对于足够大的数据集,还有另一个默认参数需要考虑更改以加快训练速度(并且通常还会提高词向量质量):sample
,它控制如何积极地高频单词(具有许多冗余用法示例)可能会被下采样(随机跳过)。
默认值 sample=0.001
(又名 1e-03
)非常保守。较小的值,例如 sample=1e-05
,将丢弃更多最常用词的冗余用法示例,从而显着加快整体训练速度。 (而且,对于您这种规模的语料库,您最终可以尝试使用更小、更具攻击性的值。)
最后,如果您的所有数据(对于完整 运行 或子集 运行)都可以在一个已经用 space 分隔的文本文件中,您可以使用 corpus_file
指定语料库的替代方法。然后,Word2Vec
class 将使用优化的多线程 IO 方法将文件的各个部分分配给备用工作线程——如果您之前没有看到所有 threads/CPU-cores 的完全饱和,可以增加我们的吞吐量。 (我会把它推迟到尝试其他事情之后,然后检查你的最佳设置是否仍然让你的 8 个线程中的一些线程经常空闲。)