那个屠榜的T5模型,现在可以在中文上玩玩了
©PaperWeekly 原创 · 作者|苏剑林
单位|追一科技
研究方向|NLP、神经网络
不知道大家对 Google 去年的屠榜之作 T5 还有没有印象?就是那个打着“万事皆可 Seq2Seq”的旗号、最大搞了 110 亿参数、一举刷新了GLUE、SuperGLUE 等多个 NLP 榜单的模型,而且过去一年了,T5 仍然是 SuperGLUE [1] 榜单上的第一,目前还稳妥地拉开着第二名 2% 的差距。
T5
跟 BERT 一样,T5 也是 Google 出品的预训练模型,来自论文为 Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer,代码已开源。T5的理念就是“万事皆可 Seq2Seq”,它使用了标准的 Encoder-Decoder 模型,并且构建了无监督/有监督的文本生成预训练任务,最终将效果推向了一个新高度。
论文标题:
Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer
论文链接:
https://arxiv.org/abs/1910.10683
代码链接:
https://github.com/google-research/text-to-text-transfer-transformer
1.1 训练
输入:明月几时有,[M0] 问青天,不知 [M1],今夕是何年。我欲[M2]归去,唯恐琼楼玉宇,高处 [M3];起舞 [M4] 清影,何似在人间。
输出:[M0] 把酒 [M1] 天上宫阙 [M2] 乘风 [M3] 不胜寒 [M4] 弄
而有监督部分,则是收集了常见的 NLP 监督任务数据,并也统一转化为 SeqSeq 任务来训练。比如情感分类可以这样转化:
输入:识别该句子的情感倾向:这趟北京之旅我感觉很不错。
输出:正面
主题分类可以这样转化:
输入:下面是一则什么新闻?八个月了,终于又能在赛场上看到女排姑娘们了。
输出:体育
阅读理解可以这样转化:
输入:阅读理解:特朗普与拜登共同竞选下一任美国总统。根据上述信息回答问题:特朗普是哪国人?
输出:美国
除了屠了多个榜单之外,T5 还对整个训练流程中很多可调的超参数都调试了一遍,比如模型架构究竟用标准的 Encoder-Decoder 好还是 UniLM 那种结构好,无监督预训练任务究竟是 BERT 的方式好还是其他方式好,随机 Mask 的比例是不是 15% 最好,等等。
mT5
2.1 T5.1.1
总的来说,mT5 跟 T5 一脉相承的,整体基本一样,但在模型结构方面,mT5 用的是 T5.1.1方案,在此对它做个基本的介绍。
很多人都不知道的是,自从在去年 10 月发布后,T5 在今年还经历了一次低调的小升级,具体细节可以查看 Github [2] 链接,官方把升级前的 T5 称为 T5.1.0,而升级后的叫做 T5.1.1。
也就是把 relu 激活的第一个变化层改为了 gelu 激活的门控线性单元,这样 FFN 层增加了 50% 参数,但是从论文效果看效果明显增加。
此外,T5.1.1 还对 Embedding 层做了改动,原来在 T5.1.0 中,Encoder 和 Decoder 的Embedding 层、Decoder 最后预测概率分布的 Softmax 层都是共享同一个 Embedding 矩阵的。
现在 T5.1.1 只让 Encoder 和 Decoder 的 Embedding 层共享,而 Decoder 最后预测概率分布的 Softmax 层则用了一个独立的 Embedding 矩阵,当然这会让参数量大大增加,但 Google 的结论说这样做效果会更好,其结论被总结在最近的论文Rethinking embedding coupling in pre-trained language models [5] 中。还有最后一点改动,T5.1.1 在预训练阶段去掉了 Dropout,而只有在下游微调阶段才使用 Dropout。
2.2 结果
mT5 其实就是重新构建了多国语言版的数据集 mC4,然后使用 T5.1.1 方案训练了一波,技术路线上没有什么明显的创新。关于训练细节,大家观察下原论文就好,论文其实也不长,毕竟 T5 已经把路都给铺好了。
读者可能会有疑问,这种多国语言版的该用什么方式评测?简单的话,我们可以直接在此基础上 finetune 一个跨语种的机器翻译任务,看看效果的提升。
实践
终于到了大家喜闻乐见的实践时间了,这里我们简单介绍一下在 bert4keras 上使用 mT5 模型来做中文文本生成任务的流程和技巧。bert4keras 从 0.9.1 版本开始支持调用 mT5 模型,如果要进行下述实验的读者,请先将 bert4keras 升级到 0.9.1 版或以上。
Github链接:
https://github.com/bojone/t5_in_bert4keras
## 基本
用bert4keras把mT5模型加载到keras中的基本代码为:
# 模型路径
config_path = '/root/kg/bert/mt5/mt5_small/t5_config.json'
checkpoint_path = '/root/kg/bert/mt5/mt5_small/model.ckpt-1000000'
spm_path = '/root/kg/bert/mt5/sentencepiece.model'
# 加载分词器
tokenizer = SpTokenizer(spm_path, token_start=None, token_end='</s>')
# 加载模型
t5 = build_transformer_model(
config_path=config_path,
checkpoint_path=checkpoint_path,
model='t5.1.1',
return_keras_model=False,
name='T5',
)
encoder = t5.encoder
decoder = t5.decoder
model = t5.model
3.1 中文
相信大多数读者多数都只关心中文任务,部分读者可能也会关心英文任务,应该鲜有读者会关心中英文以外的任务了。然而,mT5 涵盖了 101 种语言,总词表有 25 万,而且它采用的 T5.1.1结构的 Softmax 还不共享参数,这就导致了 Embedding 层占用了相当多的参数量。
比如 mT5 small 的参数量为 3 亿,其中 Embedding 相关的就占了 2.5 亿,关键是里边的大部分参数我们都用不上,纯粹是不必要的浪费。因此,对于主要关心中文任务的我们来说,有必要精简一下这个 Embedding 层了。
对模型的精简很简单,只需要在两个 Embedding 矩阵中删除不需要的行就行了,关键在于如何决定要保留的 token,以及如何得到一个精简后的 sentencepiece 模型。
决定要保留的 token,简单来想就是把中文的 token 保留下来,但是也不只是中文,英文的也要保留一部分,看上去似乎只是一个正则表达式的问题,实际上没那么简单,用英文字母的也不一定是英语,用中文字的也不一定是中文,这是个让人纠结的事情。
于是笔者想了另外一个办法:用这个 25 万 token 的 tokenizer 对笔者收集的几十 G 中文语料分词,统计分词结果,然后按照词频选择前面的部分(最后保留了 3 万多个 token)。这样虽然费时一些,但是比较靠谱,能确保把我们比较需要的 token 保留下来。决定词表后,就要修改得到一个新的 sentencepiece 模型,这也有点麻烦,但最终经过搜索后还是把这个事情解决了,处理方法都分享在 Github 上。
经过这样处理后,要构建新的模型,则只需要多加三行代码 keep_tokens 相关的代码,所需要的显存就大大降低,并且中文生成的效果基本不变了:
# 模型路径
config_path = '/root/kg/bert/mt5/mt5_base/t5_config.json'
checkpoint_path = '/root/kg/bert/mt5/mt5_base/model.ckpt-1000000'
spm_path = '/root/kg/bert/mt5/sentencepiece_cn.model'
keep_tokens_path = '/root/kg/bert/mt5/sentencepiece_cn_keep_tokens.json'
# 加载分词器
tokenizer = SpTokenizer(spm_path, token_start=None, token_end='</s>')
keep_tokens = json.load(open(keep_tokens_path))
# 加载模型
t5 = build_transformer_model(
config_path=config_path,
checkpoint_path=checkpoint_path,
keep_tokens=keep_tokens,
model='t5.1.1',
return_keras_model=False,
name='T5',
)
encoder = t5.encoder
decoder = t5.decoder
model = t5.model
3.2 效果
说白了,确实是又快又好。至于设备要求,平时跑过 BERT base 的同学,基本都应该能跑起 mT5 small/base 版,甚至 large 版也可以尝试一下,至于 XL 和 XXL,那就比较难搞了,建议还是放弃吧。
小结
参考文献
更多阅读
#投 稿 通 道#
让你的论文被更多人看到
如何才能让更多的优质内容以更短路径到达读者群体,缩短读者寻找优质内容的成本呢?答案就是:你不认识的人。
总有一些你不认识的人,知道你想知道的东西。PaperWeekly 或许可以成为一座桥梁,促使不同背景、不同方向的学者和学术灵感相互碰撞,迸发出更多的可能性。
PaperWeekly 鼓励高校实验室或个人,在我们的平台上分享各类优质内容,可以是最新论文解读,也可以是学习心得或技术干货。我们的目的只有一个,让知识真正流动起来。
📝 来稿标准:
• 稿件确系个人原创作品,来稿需注明作者个人信息(姓名+学校/工作单位+学历/职位+研究方向)
• 如果文章并非首发,请在投稿时提醒并附上所有已发布链接
• PaperWeekly 默认每篇文章都是首发,均会添加“原创”标志
📬 投稿邮箱:
• 投稿邮箱:hr@paperweekly.site
• 所有文章配图,请单独在附件中发送
• 请留下即时联系方式(微信或手机),以便我们在编辑发布时和作者沟通
🔍
现在,在「知乎」也能找到我们了
进入知乎首页搜索「PaperWeekly」
点击「关注」订阅我们的专栏吧
关于PaperWeekly
PaperWeekly 是一个推荐、解读、讨论、报道人工智能前沿论文成果的学术平台。如果你研究或从事 AI 领域,欢迎在公众号后台点击「交流群」,小助手将把你带入 PaperWeekly 的交流群里。