陌路茶色/

Scaling Word2Vec on Big Corpus

最近想把phrase的Embedding加入到phrase extraction中,查看到这样一篇关于如何在大量语料上训练Word2Vec的方法,正好阅读以下。

该论文的工作两点:1.将输入语料转换为word-context矩阵,2.解决更新冲突

Abstract

由于word-context对的强依赖关系,word2vec的训练在cpu上是连续的,本篇论文的目标是扩展word2vec到GPU集群上,因此,一个主要的挑战是减少在training batch之间的依赖,我们设计了Word2vec的变种,这样确保每一个word-context对包含一个non-dependent word和统一采样的上下文。在每一个批次的训练中,我们冻结上下文部分,仅更新non-dependent部分以减少冲突。这种变化还通过固定样本数来直接控制训练迭代,并平等对待高频和低频词。结果展示在16块GPU上实现了7.5倍的速度且不带来正确率的衰减。

Introduction

Word2vec在GPU上要比CPU上快,但是在GPU上的扩展经常会遭遇低质量的Embedding学习或者次优化的GPU利用率,这其中主要的挑战是batch size,当batch size比较大时,Embedding的质量就会急剧下降,而减少batch size就会使训练速度变慢。
Word2vec有两个主要的问题,第一个是online learning scheme,原始的w2v不能控制迭代的数量,因为它要扫描整个语料并优化word-context对之间的余弦相似度,其训练时间(迭代次数)正比于语料的大小,因此使得算法很难在大语料下训练。第二个是对low-frequency words的不敏感,对于一个word,其更新次数等于word的频次,这个问题是有些word的频率太大了,这会对低频词造成高的损失和方差,这同样也会限制大的batch size的使用和GPU利用率低的问题。
我们提出了一个可选的训练机制叫做W2V-CL,W2V-CL从语料中均匀的采样word和contextual words,每一个word被分配相同的上下文样本(context size),这样训练时间依赖于词表大小和上下文的大小,解决了online learning scheme问题。我们设计了两步更新trick来避免在一个batch中的更新冲突。

实验表明单GPU上,我们的模型比baseline快两倍,且正确率不下降,同时也实现了2个节点上共16块GPU的加速。W2C-CL模型需要前置word-context矩阵,可以直接放入到任何的深度学习框架中,同时我们使用Chainer deep learning 框架作为一个例子来论证W2C-CL的灵活性。

Word2Vec

开始讲Word2vec的原理以及W2V-Vanilla model在GPU上的实现,原文非常清楚了,没啥可写的,可以参考word2vec_pytorch使用pytorch对word2vec的实现【代码需要修改几处便能跑了,已测试】。

online learning scheme中corpus出现在前面的会被先优化,反之亦然,我们认为重排序后可能会训练相同质量的embedding而更高的训练速度【意思是说重排序后数据更加混乱,那么训练效果更好,少的训练集就能达到更好的效果】。
对待高频词更加的小心也是合理的,因为它们在下游任务中出现更加的平凡,但是上百万次的更新可能更加的平凡对于学习一个词的embedding,而低频词被更新次数太少可能不能更好的学习其向量表示,如下图所示,左边是最高频率top10的词,右边是最低频率top10的词,“bored” 和“ridiculous”仅仅出现了50次,而 “the” 出现了1061396次,即the相对于bored会被更新很多次,显然更高频的词可能不需要那么多次更新。
屏幕快照 2019-11-30 下午9.34.34.png
在GPU中训练时最大的问题是batch size,也是本论文的主要挑战,首先如果batch size设置过大,在神经网络中为了反向传播,每一个神经元的梯度都会被存储,其在内存上的消耗和batch size的大小如下图所示:
屏幕快照 2019-11-30 下午9.45.56.png
其次过大的batch size导致模型学习质量下降(在CV中),为什么会下降呢,文中给出了一张图如下所示,说参数越多,损失函数的轨迹就越陡,而训练集的损失函数和测试集的损失函数受数据分布不一定重合,这样导致在训练集上达到最小的损失函数点在测试集上就会出现偏差,而函数越陡峭,偏差越大,batch size越大即参数越多。【个人理解,因为下面这个图横轴有点问题】
屏幕快照 2019-11-30 下午9.58.25.png

直观上,在W2V-Vanilla模型中更新冲突导致学习embedding的质量比较差应该被消除,理论上很难证明 sharp minimum问题和conflict行为。但是经验上使用大的batch size训练embedding会导致一系列任务差的表现,我们选择batch size的大小为1024来保证embedding的质量,因此扩展word2vec最主要的挑战是增加batch size且保持embedding质量不下降。

Word2Vec with Controllable Number of Iterations and Large Batch Size

我们提出了W2V-Vanilla 模型的一个代替W2V-CL模型,下图所示为W2V-CL模型的整个结构:
屏幕快照 2019-11-30 下午10.12.26.png
训练语料C和词表V,W2V-CL模型第一步是均匀的从语料C中采样word-context对,词表中的每一个词都被分配l个上下文。预处理步骤创建了大小为$|V|*l$的word-context矩阵,对于高频词,其上下文超过$l$,随机移除掉多余的词,对于低频词,其上下文少于$l$,重采样。矩阵创建完成后,对行进行shuffle,实验表明shuffle导致训练更加稳定,预处理过程在单CPU上完成,经验上,100M只需要400s。

对于每一次迭代,batch size被设置为$|V|$,如下图所示,每一个batch包含2个单词列表,左边单词列表中的单词仅且出现一次,右边的上下文单词列表要么是word-matrix矩阵中的列,要么是负采样的结果,而高频词可能会出现多次,这样就会带来冲突。【冲突的意思就是说当在一个batch中,反向传播时,一个上下文向量同时被两个单词向量指向,更新的时候应该如何处理的问题。如下图W2V-CL中所示,红色的contextual words被多个words指向,反向传播同时被更新,出现冲突】
【再说一下这个冲突到底是什么:以下图为例,words 向量$u_1$和向量$u_2$同时指向contextual words向量$v_1$,如果串行更新,向量$v_1$会更新两次,即出现了三个状态:$v_{10},v_{11},v_{12}$,其中$v_{10}$为起始状态,$$v_{11}=v_{10}-g(v_1,u_1)$$ $$v_{12}=v_{11}-g(v_1,u_2)$$ 而如果并行更新就是$v_1=v_{10}-g'(v_1,u_1,u_2)$,也就是说并行更新时状态过期了,我的理解是如果冲突少没啥问题,但是冲突过多可能效果就会下降,因为更新点一直都是在很早的状态下,而串行就会不停的变化状态点】
屏幕快照 2019-11-30 下午10.25.57.png
在前面的讨论中也表明,冲突会导致低质量的embedding学习,为了避免更新冲突,我们使用两步更新方法,第一步:左边单词列表查找word向量表,右边单词列表查找context向量表,更新单词向量,第二步:交换word和context的角色,左边单词列表查找context向量,右边单词列表查找word向量,更新上下文向量。【这个就是本论文的核心思想,解决了所谓的冲突问题】

Advantages of W2V‑CL over W2V‑Vanilla

W2V‑CL的batch size设置为词表的大小$|V|$,而W2V‑Vanilla使用的是1024,online learning scheme问题,W2V‑CL使用word–context矩阵,保证低频和高频有同样的跟新次数。

Theoretical Computational Complexity

W2V‑CL的时间复杂度为$l⋅ |V| ⋅ o$, W2V-Vanilla的时间复杂度为$ |C| ⋅ 2 ⋅ win ⋅ o$,o为两个向量乘积操作的时间复杂度。然后讲了Heaps’ law。

Scaling W2V‑CL Model Using Multiple GPUs and Compute Nodes

假设有N块GPU,每块GPU分配$|B|/N$个word-context pair,$|B|$是batch size。。。。
这里前面有提到batch size设置为vocab的大小,因此每一块GPU上训练一个batch的时候是训练了整个词表一次。
如下图所示:
屏幕快照 2019-12-01 下午10.17.07.png

后面没啥可讲的了。。。

补充
Skip-gram:在小数据集上表现好,即便是rare words or phrase也表现的很好
CBOW:比skip-gram训练要快,在frequent words上的正确率要更好点

实践

此部分我会将该方法应用在spark上,目前已写好代码。。。

参考

1.An implementation guide to Word2Vec using NumPy and Google Sheets
2.The Illustrated Word2vec
3.word2vec多线程优化时不加锁的做法合理么?

留下一条评论

暂无评论