现在可以用Keras玩中文GPT2了(GPT2_ML)
By 苏剑林 | 2020-03-16 | 94664位读者 |前段时间留意到有大牛开源了一个中文的GPT2模型,是最大的15亿参数规模的,看作者给的demo,生成效果还是蛮惊艳的,就想着加载到自己的bert4keras来玩玩。不过早期的bert4keras整体架构写得比较“死”,集成多个不同的模型很不方便。前两周终于看不下去了,把bert4keras的整体结构重写了一遍,现在的bert4keras总能算比较灵活地编写各种Transformer结构的模型了,比如GPT2、T5等都已经集成在里边了。
GPT2科普 #
GPT,相信很多读者都听说过它了,简单来说,它就是一个基于Transformer结构的语言模型,源自论文《GPT:Improving Language Understanding by Generative Pre-Training》,但它又不是为了做语言模型而生,它是通过语言模型来预训练自身,然后在下游任务微调,提高下游任务的表现。它是“Transformer + 预训练 + 微调”这种模式的先驱者,相对而言,BERT都算是它的“后辈”,而GPT2,则是GPT的升级版——模型更大,训练数据更多——模型最大版的参数量达到了15亿。
中文版 #
看过GPT2的科普推文的读者,多数都会被它的生成效果所惊艳。不过再好也是别人家的语言,OpenAI并没有帮忙训练中文版。不过好消息是,一个叫GPT2_ML的项目开源了一个中文版的GPT2,而且还是最大的15亿参数级别的模型。
目前bert4keras集成的GPT2,正是GPT2_ML项目给出的,而不是OpenAI的那个,毕竟bert4keras优先服务中文版。值得指出的是,GPT2_ML的模型结构,跟OpenAI版的GPT2结构并不一样,也跟BERT的结构有所不同,三者的Block对比如下:
测试一下 #
首先,下载模型权重,地址为:
链接: https://pan.baidu.com/s/1OXBd16o82SpIzu57kwA8Mg 提取码: q79r
其中,主文件“model.ckpt-100000.data-00000-of-00001”还可以从Google Drive下载。下载完成后请检查一下model.ckpt-100000.data-00000-of-00001的SHA256(4a6e5124df8db7ac2bdd902e6191b807a6983a7f5d09fb10ce011f9a073b183e)。
然后安装不低于0.6.0版本的bert4keras(当前最新版),就可以跑下述测试代码了(如果因为版本迭代原因导致下述代码已经过期,那么请到 basic_language_model_gpt2_ml.py 查看最新版本):
#! -*- coding: utf-8 -*-
# 基本测试:中文GPT2模型
# 介绍链接:https://kexue.fm/archives/7292
import numpy as np
from bert4keras.models import build_transformer_model
from bert4keras.tokenizers import Tokenizer
from bert4keras.snippets import AutoRegressiveDecoder
from bert4keras.snippets import uniout
config_path = '/root/gpt2/config.json'
checkpoint_path = '/root/gpt2/model.ckpt-100000'
dict_path = '/root/gpt2/vocab.txt'
tokenizer = Tokenizer(dict_path,
token_start=None,
token_end=None,
do_lower_case=True) # 建立分词器
model = build_transformer_model(config_path=config_path,
checkpoint_path=checkpoint_path,
model='gpt2_ml') # 建立模型,加载权重
class ArticleCompletion(AutoRegressiveDecoder):
"""基于随机采样的文章续写
"""
@AutoRegressiveDecoder.set_rtype('probas')
def predict(self, inputs, output_ids, step):
token_ids = np.concatenate([inputs[0], output_ids], 1)
return model.predict(token_ids)[:, -1]
def generate(self, text, n=1, topk=5):
token_ids, _ = tokenizer.encode(text)
results = self.random_sample([token_ids], n, topk) # 基于随机采样
return [text + tokenizer.decode(ids) for ids in results]
article_completion = ArticleCompletion(start_id=None,
end_id=511, # 511是中文句号
maxlen=256,
minlen=128)
print(article_completion.generate(u'今天天气不错'))
部分结果:
>>> article_completion.generate(u'今天天气不错')
[u'今天天气不错,可以去跑步。昨晚看了一个关于跑步的纪录片,里面的女主讲述的是一个女孩子的成长,很励志,也很美丽。我也想跑,但是我不知道跑步要穿运动鞋,所以就买了一双运动鞋。这个纪录片是关于运动鞋的,有一 集讲了一个女孩子,从小学开始就没有穿过运动鞋,到了高中才开始尝试跑步。']>>> article_completion.generate(u'双十一')
[u'双十一马上就要到了!你还在为双11的物流配送而担心吗?你还在为没时间去仓库取货而发愁吗?你还在为不知道怎么买到便宜货而发愁吗?你还在为买不到心仪的产品而懊恼吗?那么,双十一就来了!今天小编带你来看看这些 快递,都是怎么送货的!1. 物流配送快递公司的配送,主要是由快递公司负责,快递公司负责派件,物流服务。']>>> article_completion.generate(u'科学空间')
[u'科学空间站科学空间站(英文:science space station),是中华人民共和国的一个空间站。该空间站是中国科学院大连物理研究所研制,主要研发和使用中国科学院大连物理研究所的核能动力空间站。科学空间站位于北京市海淀区,距离地面393米,总建筑面积约为1万平方米,总投资约为5亿元人民币。科学空间站于2018年12月26日开始动工,2021年6月建成并投入使用。']
是不是感觉还挺好的?
想Finetune? #
看到这效果,估计不少读者的想法就是:怎么用到我自己的模型上,能不能在我自己的任务上finetune一下?
不好意思,告诉大家一个比较悲观的结果:笔者用Adam优化器在公司的22G显存的TITAN RTX上测试finetune这个参数规模接近15亿的GPT2,发现batch_size=1都没法跑起来...最后发现,只有在AdaFactor优化器下,才能Finetune得动它。
关于AdaFactor,后面有机会再写文章讨论。
转载到请包括本文地址:https://kexue.fm/archives/7292
更详细的转载事宜请参考:《科学空间FAQ》
如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。
如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!
如果您需要引用本文,请参考:
苏剑林. (Mar. 16, 2020). 《现在可以用Keras玩中文GPT2了(GPT2_ML) 》[Blog post]. Retrieved from https://kexue.fm/archives/7292
@online{kexuefm-7292,
title={现在可以用Keras玩中文GPT2了(GPT2_ML)},
author={苏剑林},
year={2020},
month={Mar},
url={\url{https://kexue.fm/archives/7292}},
}
March 16th, 2020
gpt2-ml 作者举手
幸会幸会,欢迎莅临指导,哈哈~~期待大佬放出更多的中文模型哈。
@AutoRegressiveDecoder.set_rtype('probas')
AttributeError: type object 'AutoRegressiveDecoder' has no attribute 'set_rtype'
这行报错了,请问下大佬是修改了源码吗?
是的,已经补充了最新版本代码的地址。
我也是遇到同样问题,请问一下苏神,最新的0.8.8版本也没有,是哪个版本的呢
参考最新版本的examples进行改写,适配最新版本的代码。
March 17th, 2020
Transformer系的各种结构,不管LayerNorm是前置还是后置,经过LN之后好像都不是直接加激活函数,包括FeedForward里也通常是LN后再FC之后才加激活。这一点跟CNN里头通常BN+activ的做法好像很不一样。对这种处理,博主有什么理解吗?
估计是因为Self Attention本身带有一定的非线性了,所以就不用激活函数了。
March 20th, 2020
大佬,你的这一系列文章写得非常好,受益匪浅,就是代码有pytorch版本吗?
必须没有啊,对pytorch相当没兴趣。
March 28th, 2020
请教一下在这么多种模型中,那种语言模型的效果是最好的呢,好的原因呢。
没有哪个模型能在所有任务上都最好,更不要说好的原因了。
sorry,忘记说了,就是在这种文本生成这个单个项目下,那种是最优的呢。感觉这几种模型仅仅是结构上的不同而己。难道效果差异就很大么。
单看效果的话,模型越大越好,越烧钱越好。
April 1st, 2020
说实话,苏神你自己喜欢哪一个都ok,别人无权干涉,但如果你关注过automatic differentiation技术的发展,你会发现实际上你以前说过的Pytorch的缺点很没有道理。
就算它百般好,我还是不喜欢,不需要道理~
May 13th, 2020
请教2080ti不是跑不动这个模型,在加载模型的时候直接挂了
请贴关键错误信息
July 31st, 2020
mac跑了十分钟没跑出一次结果,留下了没有GPU的泪水
August 10th, 2020
苏老师好,我用您的这个代码(网页上的貌似出错,从网站拷贝最新的),在我的windows、cpu版本的机器上跑(tf=2.2.0,keras=1.3.1),貌似一直没有结果出来啊?我的服务器内存上百G应该没有问题啊,不知道是少原因?
“一直”是多久?cpu可能要跑20分钟。
August 12th, 2020
大佬,这个能用gpu跑吗,具体怎么操作?CPU跑着好慢
可以用gpu跑。如何配置gpu环境请自行搜索。
August 31st, 2020
请教苏神,如果我不做训练,直接加载模型参数进行文本生成,需要什么样的配置才能跑起来?
按道理,11G的显卡应该可以跑起预测过程。更低的配置我没有尝试过。
1080 8g显存跑成功
谢谢反馈。