Icy translate 英中翻译系统上线
Wed, Aug 16, 2017 in Interesting Python
Icytranslate 是一个完全开源的英文-中文的神经机器翻译系统(NMT),现在这个系统仍有缺陷,为了把一个翻译系统部署到我内存和cpu都不是很好的服务器上我也是在模型上花了点功夫,做了一些妥协,现在这个翻译系统大概可以把高中英语作文水平的句子翻译得比较能看,在更高难度的文章上表现就开始不太好。这篇文章会描述翻译模型的构建和训练过程,并且公布icytranslate的github地址,一方面希望能给对这方面感兴趣的人一个完整的参考,另一方面希望有更厉害的人能够参与进来,提一些pull request,一起改进这个系统。
首先是Icytranslate的github项目:
- 模型训练部分: https://github.com/bupticybee/icytranslate_offline
- restful api: https://github.com/bupticybee/icytranslate_api 将模型的产出封装成web api
- icytranslate的网站: https://github.com/bupticybee/icytranslate_website 和icytranslate_api一起部署,构成icytranslate
icytralslate的模型只有不到200MB,绝大多数的服务器应该都可以毫无压力的运行起来。
接下来的章节我们会将注意力集中在如何构建一个机器翻译系统上:
概述
关于icytranslate
icytranslate 现在的英语水平也就相当于初中或者高中生的水平吧,大家可以搜一些高中生作文测试,更复杂的环境就不保证是使用效果了,平台使用目前也是有限制的,icytranslate不接受4句以上的翻译,并且每一句超过40个词的部分会被截断,这是为了节省服务器资源。
关于机器翻译
- 规则法(rule based machine translation, RBMT),顾名思义,就是根据语言语法规则直接设计程序来完成翻译的工作。
- 统计法 (statistical machine translation, SMT) ,通过对大量的平行语料进行统计分析,构建统计翻译模型(词汇、比对或是语言模式)。
- 神经网络(Neural machine translation, NMT),目前最先进的方法,运用sequence to sequence learning来解决机器翻译的问题,谷歌用它改变了世界。
由于我看的几篇论文都是有关NMT系统的,其他两种系统只有很粗略的了解,所以这篇文章不会提及,我们的重点集中在NMT。
一些NMT的方法
首先我并不认以我的表述能力可以将任何一种nmt的模型在一篇blog的篇幅里完完全全说清楚,所以这里只是贴出论文链接 + 简单介绍一下,如果真的对机器翻译感兴趣建议可以都读一下,只有好处没有坏处,因为如果对这些理论没有了解的话可能会看不太懂接下去的内容。
Sequence to Sequence Learning with Neural Networks
这篇文章提出了最简单的sequence to sequence 模型
图上的ABC是源语言的句子中的经过embedding的词向量,XYZ是目标语言的,整个sequence to sequence 模型做的事情首先是利用一个单向LSTM网络将源语言的句子映射成一个句子向量,然后再在另一侧利用另一个LSTM网络将这个句子向量翻译成为目标语言,作者在论文中表示就是一个这么简单的模型就可以在英文-法文的翻译任务上取得非常好的成绩。
Effective Approaches to Attention-based Neural Machine Translation
这篇文章将attention用在多层单向LSTM上,取得了很好的结果,以至于tensorflow 官方出品的 nmt项目 https://github.com/tensorflow/nmt 默认用的就是这个结构。
Neural Machine Translation by Jointly Learning to Align and Translate
icytranslate 的模型基本就是这篇论文的超级低配版加上一些奇怪的想法。
这篇论文使用双向RNN来给源语言编码,然后使用attention机制直接把输入语言的信息提供给输出端,亮点是输入网络和输出网络不再直接相连,而是通过attention来交换信息。
* Convolutional Sequence to Sequence Learning
这篇论文之所以打星星是因为我自己都还没看完,暂时没法给出一个中规中矩的介绍,但是这篇论文非常有名,利用卷积在sequence to sequence 的模型上取得了很好的效果。
* Attention Is All You Need
这篇论文我也是没有看过的,同样非常有名,将attention机制发挥到了极致。
Google’s Neural Machine Translation System
这篇论文是google出品的,描述了google translate 运用的一些技术,其中一些trick很有启发性。比如提出将词表外的词汇分成subwords加入词表。
数据集
中英翻译的平行语料确实不是特别好找,这里推荐我发现的两个还可以的语料:
- UM corpus: 官网链接 , 语料需要申请,一般一周以内会给回复邮件,然后就可以下载了。这份语料包含了超过200万个中英 中英对照句子,规模不是特别大,但是根据《UM-Corpus: A Large English-Chinese Parallel Corpus forStatistical Machine Translation》 这篇描述性论文,这份语料是完全可以训练出一个中英翻译模型的。
这份语料涉及的面很广,我粗略看了一些例子,还是一部分语料是很明显的bad case的,但不妨碍这仍然是一份很优秀的语料集。
- UN corpus:官网链接 这份语料最明显的优点就是多,1500万条 中-英对照句子,而且大部分都翻译得非常准确,毕竟这份语料是联合国官方文件的翻译(1500万个句子,可以看出联合国的文件有多么冗长),缺点也是非常明显的,就是语料大部分都是在说官话,没有UM crops 的那种多样性,不适合生活中的场景,训练出来可能只能翻译一些政府文件。
所以我最后选择在UM crop 上训练icytranslate, 其他语料上的效果有待进一步实验。
预处理
这部分往下的所有代码都可以在项目的github上找到
分词
英文语料用jieba分词分好,然后转小写
中文语料按字分开,之所以不按词来分是因为按照字来分可以节省很多embedding的空间,减小模型体积,我也训练过按照词来分的模型,但是模型太大了,部署的时候发现我的服务器并没有像训练的机器那么好的配置,载进内存以后很影响其他服务,毕竟同机还部署了我自己的博客和icysearch,出事了就不太好了,我们可以计算一下至少省了多少空间:
中文的词汇实在是非常多,想要大致覆盖所有语料到能看的地步至少需要6万个词汇,而如果使用字来分开的话语料中不同的汉字加起来只有8000多个,达到的语料覆盖率就可以到100%,如果选用6万个词汇的话,embedding 使用的存储空间至少(embedding 到 512维向量):
60000 * 512 * 4(float32 占4个字节) = 122,880,000 字节 ~= 117MB
如果按字分开:
7000 * 512 * 4(float32 占4个字节) = 16,384,000 字节, ~= 15.62MB
这里的差距接近100MB,我们不要忘了这只是编码的embedding,输出还有一层反向embedding,所以一共就差了至少200MB的模型体积,而且根据实际的实验,在我的模型设置下,两种词汇切分方式的效果差别没有那么大,而且不要忘了,我们最后产出的模型的体积就只有不到200MB,也就是说光这一步就节省了一半多的模型体积。
词语-index映射
取英文语料中使用频率最大的5万个单词,中文语料中的所有汉字(8823个),加上<go> <unk> <eos>
这三个特殊标记,其中<go>
表示的是一个句子的起始符号 <unk>
表示的是词表之外的所有单词, <eos>
是句子的终结符号,最后英文单词映射成的index共有50003个,中文汉字映射成8826个index。
筛除语料
为了加速训练,我在预处理时筛掉了所有长度大于40个单词的中-英句子,最后剩下1.9 million 的中英句子
模型
模型如上文所说,基本是一个超级低配版的《NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE 》
模型差不多就是上图的那个样子,只不过hidden size缩水到512,embedding size也是512,而且只用了一层的双向LSTM作为输入编码器,两层的单向LSTM作为输出的解码器,使用了参数为1.0的gradient normal,具体的描述参考论文,具体的实现见github源码。
训练
使用learning rate 为1.0的SGD作为优化器,训练10个epoch以后每半轮将learning rate减半,再训练3轮, 然后停止训练,模型应该从第二轮开始就能输出一些稍微有意义的结果。
整个过程在装配有1080ti和32GB内存的机器上需要大概1.5天的时间,在训练NMT模型中已经算是很短的了。
the end
代码在github上可以找到, 有问题联系 icybee@yeah.net