淮南学校网站建设电话,外管局网站上做存量权益登记,企业电话名单从哪里弄,免费网站空间怎么文 | 苏剑林编 | 兔子酱前段时间刷Arixv的时候#xff0c;发现清华大学开源了一个大规模的中文闲聊语料库LCCC#xff0c;从开源的文件上来看#xff0c;这可能是目前开源的数量最大、质量最好的闲聊语料库了#xff0c;而且还包含了部分多轮对话聊天#xff0c;总的来说可… 文 | 苏剑林编 | 兔子酱前段时间刷Arixv的时候发现清华大学开源了一个大规模的中文闲聊语料库LCCC从开源的文件上来看这可能是目前开源的数量最大、质量最好的闲聊语料库了而且还包含了部分多轮对话聊天总的来说可玩性还是蛮强的。笔者也被它吸引到了尝试着用它来训练了一个闲聊对话模型结果看上去还是不错的在此分享一下自己的经验。论文名称《A Large-Scale Chinese Short-Text Conversation Dataset》论文链接https://arxiv.org/abs/2008.03946项目地址https://github.com/thu-coai/CDial-GPTArxiv访问慢的小伙伴也可以在 【夕小瑶的卖萌屋】订阅号后台回复关键词 【0917】 下载论文PDF~语料简介这里简单介绍一下LCCC这个数据集Large-scale Cleaned Chinese Conversation具体细节大家可以去Github上看下载链接也在上面。LCCC分base和large两个版本base主要是来源于微博对话large则是在base的基础上融合了其他开源对话语料按照作者的说法LCCC经过了严格的清洗过程所以整体质量看上去还是很不错的。为了简化任务所有样本都被处理成双人对话。下面是一些样本示例A: 等过年咱们回去买点兔头好好吃顿火锅B: 太原就没看见有好吃的兔头A: 我从虹桥给你带个回去那天瞅到一正宗的B: 最爱你了A: 那是必须A: 嗯嗯我再等等你现在在上海吧上海风好像比南京还大呢少出门吧B: 对啊我在家没事儿。一定要小心啊A: 我去年也去转了一圈还碰见以前的体育老师了合了个影B: 哈哈我还去找高一时侯的英语老师没找到她刚好有事情没在学校A: 你也是真心找回忆了哦B: 哈哈毕业了没去过想去看看啊模型设计知道了数据长什么样之后我们接下来就要去设计模型了。显然我们需要做的就是训练一个模型预测下一个该回复什么。既然语料里包含了多轮对话那么我们还要求这个模型支持多轮对话。考虑对话历史的最简单的方式就是把直到当前句的所有历史对话都拼接成单句文本来作为模型的输入信息。给定一些输入预测一个输出从形式上来看我们应该用Seq2Seq模型。直接用Seq2Seq其实问题也不大但标准的Seq2Seq一般用于形式比较固定的输入输出比如输入的文本长度应该是集中在某个范围内不宜变化太大但考虑多轮对话的话理论上我们也不知道前面有多少轮对话因此原则上输入文本长度是无限制的。用Seq2Seq的话还有训练效率低的问题就是我们每轮对话每次我们只能训练一句回复如果一个多轮对话有n句回复那么就要拆分为n个样本来训练了。因此我们需要一个长度能相当自由地变化的、同时能预测整个多轮对话的模型实现这个需求的比较适当的选择就是单向语言模型LM、GPT做法如下图如图所示我们选择当前主流的Transformer模型按照BERT的常规输入格式将每句对话用[SEP]拼接起来然后就训练一个从左往右的单向语言模型。为了区分不同的说话角色我们对不同的说话者用不同的Segment Id区分。此外考虑到BERT和GPT都是用了绝对位置编码可处理的文本长度存在一个上限而对话轮数理论上是无限的所以这里我们采用了相对位置编码的NEZHA作为基本结构并使用NEZHA的预训练权重作为模型的初始化权重。说白了就是往NEZHA里边加入了下三角形式的Attention Mask使其变为一个语言模型相关介绍请参考《从语言模型到Seq2SeqTransformer如戏全靠Mask》[1]。训练细节首先给出笔者的参考实现以及训练好的模型https://github.com/bojone/nezha_gpt_dialog代码基于bert4keras实现基本结构是NEZHA Base。为了使得训练更加“平民化”笔者只用了一张卡22G的RTX配合梯度累积来训练显存不够大的读者可以缩小batch_size。开源的模型是用的学习率、0.01的权重衰减率的Adam优化器进行训练的训练了1000万步20多天单步batch_size为16累积梯度步数为16所以相当于以256的batch_size训练了62.5万步最终的loss大概是2.83平均每个token的交叉熵。我们来测试一下我们的训练结果。 print(chatbot.response([u我最近天天吃火锅]))火锅好吃啊 print(chatbot.response([u我最近天天吃火锅]))我也是 print(chatbot.response([u我最近天天吃火锅]))哈哈哈哈哈哈我最近一周吃了两顿火锅 print(chatbot.response([u我最近天天吃火锅]))我也是每次都吃的撑 print(chatbot.response([u我最近天天吃火锅]))吃火锅不长胖 print(chatbot.response([u我最近天天吃火锅]))火锅好啊 print(chatbot.response([u我最近天天吃火锅]))你们那边有这种火锅 print(chatbot.response([u我最近天天吃火锅]))火锅好吃吗我也想吃 print(chatbot.response([u我最近天天吃火锅]))吃吧吃了就开心了 print(chatbot.response([u我最近天天吃火锅]))我也想天天吃火锅 print(chatbot.response([u我最近天天吃火锅]))火锅吃不了多久的。 print(chatbot.response([u你那天气好吗]))还好不热有点冷 print(chatbot.response([u你那天气好吗, u还好不热有点冷, u那你得穿多厚的衣服]))我穿了两件对比分析CDial-GPT也开源了自己训练的预训练模型笔者也将它转换为bert4keras能加载的格式了CDial-GPT-tf[2]读者也可以测试比对一下。从训练上来看CDial-GPT使用pytorch实现的模型基本结构是GPT Base使用了4张2080Ti总batch_size为32累积梯度64步论文说训练了30个epoch总步数约2100万步笔者的两倍因此大概相当于batch_size为2048训练了33万步。在输入设计上CDial-GPT也有所不同如下图如图所示CDial-GPT跟我们前述设计的主要不同是多轮对话之间的拼接方式我们之前是直接用[SEP]连接它是用[speaker1]、[speaker2]图中简记为S1、S2这样的角色标记来连接最后才用一个[SEP]表示回复结束。这样一来由于预测部分的格式跟历史的格式不一样因此每次只能训练一句回复多轮对话要拆分为多个样本来训练理论上是增加了训练复杂性的要训练多步才能把一个多轮对话样本训练完。至于效果上个人测试的感觉是两者没什么明显差别。有兴趣的读者也可以自行比较测试。文章总结本文主要分享了一次对话模型实践基于开源的LCCC闲聊语料库利用语言模型GPT对多轮对话进行生成式建模得到了一个相对通用的闲聊对话模型最后将本文的思路与CDial-GPT本身开源的模型进行了比较。文末福利后台回复关键词【入群】 加入卖萌屋NLP/IR/Rec与求职讨论群有顶会审稿人、大厂研究员、知乎大V和妹纸等你来撩哦~参考文献[1] 《从语言模型到Seq2SeqTransformer如戏全靠Mask》:https://kexue.fm/archives/6933[2] CDial-GPT-tf:https://github.com/bojone/CDial-GPT-tf