做社区网站用什么程序,深圳市建筑市场信息公开平台,360搜索引擎网址,广东建设网站公司文 | 苏剑林编 | 小轶背景当前#xff0c;大部分中文预训练模型都是以字为基本单位的#xff0c;也就是说中文语句会被拆分为一个个字。中文也有一些多粒度的语言模型#xff0c;比如创新工场的ZEN和字节跳动的AMBERT#xff0c;但这类模型的基本单位还是字#xff0c;只不… 文 | 苏剑林编 | 小轶背景当前大部分中文预训练模型都是以字为基本单位的也就是说中文语句会被拆分为一个个字。中文也有一些多粒度的语言模型比如创新工场的ZEN和字节跳动的AMBERT但这类模型的基本单位还是字只不过想办法融合了词信息。目前以词为单位的中文预训练模型很少据笔者所了解到就只有腾讯UER开源了一个以词为颗粒度的BERT模型但实测效果并不好。那么纯粹以词为单位的中文预训练模型效果究竟如何呢有没有它的存在价值呢最近我们预训练并开源了以词为单位的中文BERT模型称之为WoBERTWord-based BERT我的BERT。实验显示基于词的WoBERT在不少任务上有它独特的优势比如速度明显的提升同时效果基本不降甚至也有提升。在此对我们的工作做一个总结。开源地址https://github.com/ZhuiyiTechnology/WoBERT字还是词究竟是“字”好还是“词”好这是中文NLP一个很让人抓狂的问题也有一些工作去系统地研究这个问题。比较新的是香侬科技在ACL2019上发表的《Is Word Segmentation Necessary for Deep Learning of Chinese Representations?》里边得到了字几乎总是优于词的结论。前面也说了现在中文预训练模型确实也基本上都是以字为单位的。所以看上去这个问题已经解决了就是字更好事情远没有这么简单。就拿香侬科技的这篇论文来说它的实验结果是没有错但却是没有代表性的。为什么这样说呢因为在该文的实验设置下模型的embedding层皆从随机初始化状态开始训练。这样一来对于同样的任务以词为单位的模型Embedding层参数更多自然就更容易过拟合效果容易变差这不用做实验都能猜个大概。问题是我们用基于词的模型的时候通常并不是随机初始化的往往都是用预训练好的词向量的下游任务看情况选择是否微调词向量这才是分词的NLP模型的典型场景但论文里边却没有比较这个场景所以论文的结果并没有什么说服力。事实上“过拟合”现象具有两面性我们要防止过拟合但过拟合也正好说明了模型拥有比较强的拟合能力而如果我们想办法抑制过拟合那么就能够在同样复杂度下得到更强的模型或者在同样效果下得到更低复杂度的模型。而缓解过拟合问题的一个重要手段就是更充分的预训练所以不引入预训练的比较对以词为单位的模型来说是不公平的而我们的WoBERT正是证实了以词为单位的预训练模型的可取性。词的好处一般认为以字为单位的好处是参数更少不容易过拟合不依赖于分词算法避免边界切分错误没那么严重的稀疏性基本上不会出现未登录词。至于以词为单位的理由是序列变短处理速度更快在文本生成任务上能缓解Exposure Bias问题词义的不确定性更低降低建模复杂度。对于词的好处大家可能会有些疑惑。比如第2点词能缓解Exposure Bias这是因为理论上来说序列越短Exposure Bias问题就越不明显词模型单步预测出一个n字词相当于字的模型预测了n步这n步都递归依赖所以字的模型Exposure Bias问题更严重。至于第3点虽然有多义词的存在但是多数词的含义还是比较确定的至少比字义更加明确这样一来可能只需要一个Embedding层就能把词义建模好而不是像字模型那样要通用多层模型才能把字组合成词。看起来不相伯仲但事实上以字为单位的好处并非就是以词为单位的缺点了。只要多一些技巧以词为单位也能一定程度上避免这几个问题。比如以词为单位的参数确实增多了但是可以通过预训练来缓解过拟合所以这个问题不会很严重依赖分词算法是个问题如果我们只保留最常见的一部分词那么不管哪个分词工具分出来的结果都是差不多的差异性不大至于边界切分错误这个难以避免但是需要准确的边界的只是序列标注类任务而已文本分类、文本生成其实都不需要准确的边界因此不能就此否定词模型如果我们把大部分字也加入到词表中也不会出现未登录词。所以其实用词的好处是相当多的除了需要非常精确边界的序列标注类型的任务外多数NLP任务以词为单位都不会有什么问题。因此我们就去做了以词为单位的BERT模型了。Tokenizer往BERT里边加入中文词首先得让Tokenizer能分出词来。只需要把词加入到字典vocab.txt里边就行了吗并不是。BERT自带的Tokenizer会强行把中文字符用空格隔开因此就算你把词加入到字典中也不会分出中文词来。此外BERT做英文word piece的分词的时候使用的是最大匹配法这对中文分词来说精度也不够。为了分出词来我们修改了一下BERT的Tokenizer加入了一个“前分词pre_tokenize”操作。这样我们就可以分出中文词来具体操作如下把中文词加入到vocab.txt输入一个句子s用pre_tokenize先分一次词得到遍历各个如果在词表中则保留否则将用BERT自带的tokenize函数再分一次将每个的tokenize结果有序拼接起来作为最后的tokenize结果。在bert4keras0.8.8版本中实现上述改动只需要在构建Tokenizer的时候传入一行参数例如tokenizer Tokenizer(dict_path,do_lower_caseTrue,pre_tokenizelambda s: jieba.cut(s, HMMFalse)
)
其中pre_tokenize为外部传入的分词函数如果不传入则默认为None。简单起见WoBERT使用了结巴分词删除了BERT自带词表的冗余部分比如带##的中文词然后加入了20000个额外的中文词结巴分词自带的词表词频最高的两万个最终WoBERT的vocab.txt规模是33586。模型细节目前开源的WoBERT是Base版本在哈工大开源的RoBERTa-wwm-ext基础上进行继续预训练预训练任务为MLM。初始化阶段将每个词用BERT自带的Tokenizer切分为字然后用字embedding的平均作为词embedding的初始化。到这里WoBERT的技术要点基本上都说清楚了剩下的就是开始训练了。我们用单张24G的RTX训练了100万步大概训练了10天序列长度为512学习率为5e-6batch_size为16累积梯度16步相当于batch_size256训练了6万步左右。训练语料大概是30多G的通用型语料。训练代码已经在文章开头的链接中开源了。此外我们还提供了WoNEZHA这是基于华为开源的NEZHA进行再预训练的训练细节跟WoBERT基本一样。NEZHA的模型结构跟BERT相似不同的是它使用了相对位置编码而BERT用的是绝对位置编码因此理论上NEZHA能处理的文本长度是无上限的。这里提供以词为单位的WoNEZHA就是让大家多一个选择。模型效果最后说一下WoBERT的效果。简单来说在我们的评测里边WoBERT相比于BERT在不需要精确边界的NLP任务上基本都没有变差的有些还会有一定的提升而速度上则有明显提升所以一句话就是“提速不掉点”。比如中文榜单上的两个分类任务我们内部还测了不少任务结果都是类似的表明这些NLU任务上WoBERT和BERT基本上都差不多的。但是速度上WoBERT就比BERT有明显优势了下表是两个模型在处理不同字数的文本时的速度比较我们还测了WoBERTUniLM的方式Seq2Seq任务CSL/LCSTS标题生成结果是比以字为单位的模型有明显提升这说明以词为单位来做文本生成其实是更有优势的。要是生成更长的文本这个优势还能进一步放大。当然我们也不否认用WoBERT去做NER等序列标注任务时可能会有明显的掉点比如做人民日报的NER掉了3%左右可能让人意外的是经过bad case分析我们发现掉点的原因并不是因为切分错误而是因为稀疏性平均来说每个词的样本更少所以训练得没那么充分。不管怎么说我们把我们的工作开源出来给大家在使用预训练模型的时候多一个尝试的选择吧。文章小结在这篇文章里我们开源了以词为单位的中文BERT模型WoBERT并讨论了以词为单位的优缺点最后通过实验表明以词为单位的预训练模型在不少NLP任务尤其是文本生成上有它独特的价值一方面它有速度上的优势一方面效果上能媲美以字为单位的BERT欢迎大家测试。文末福利后台回复关键词【入群】 加入卖萌屋NLP/IR/Rec与求职讨论群有顶会审稿人、大厂研究员、知乎大V和妹纸等你来撩哦~