Datawhale干货
作者:章岳,苏州大学研究生,达摩院实习
近期参加了2022 蜜度中文文本智能校对大赛,经过2个月的比赛,在600余名参赛者中取得了第一名的成绩,相关技术也已在钉钉文档等产品落地应用。借此机会,笔者想和大家分享下对中文文本纠错任务的一些看法。
笔者所在的团队是苏州大学-阿里达摩院联队,成员包括章岳、蒋浩辰、章波、包祖贻四位,指导老师是李正华和李辰老师。
团队成员拥有自然语言处理方向的丰富研究经验,特别是对中英文的拼写、语法纠错有长期的研究和积累,相关研究成果已经在自然语言处理顶级学术会议EMNLP、NAACL等发表, 获得过CGED、CTC等纠错评测的多次冠军,并持续将研究成果开源开放,如MuCGEC数据集和模型库等。除了科研成果外,我们也将相关技术落地应用,为钉钉文档、阿里邮箱等多款产品提供文本纠错功能。
中文文本纠错任务作为中文自然语言处理的一项较为重要的下游任务,在搜索、教育、新闻等领域都有着落地的价值。在英文上,文本纠错任务已经得到了广泛的研究,已有Grammarly等成熟的文本纠错工具。而由于中文的复杂性与自由性,中文文本纠错的研究距离实际落地使用还有很大的距离,因此仍有着广阔的研究空间。
中文文本纠错任务的形式非常简单:给定一个中文句子,纠正其中可能含有的各种类型的错误,包括但不限于拼写、语法和语义错误。比如下面的例子:
{
"source": "精娘啤酒+汉堡,这对CP磕了磕了!",
"target": "精酿啤酒+汉堡,这对CP磕了磕了!",
"type": "negative",
"id": 2600372
},
虽然形式简单,但该任务难点众多,比如:
1)训练数据稀缺:真实的纠错训练数据相较于其他常见的生成任务(如机器翻译、摘要等)难获得很多,首先是语病在日常文本中非常稀疏,其次需要标注者拥有良好的语文背景;
2)中文表达灵活:不像英语等语言有着大量易于纠正的词形错误(单复数、人称、时态),中文的表达博大精深,很多错误非常隐晦且难于修改,需要丰富的语法知识,现阶段的模型很难处理。
与传统的中文纠错评测(NLPCC18,CGED系列)不同,本次赛事评测主要面向的是汉语母语者文本,更贴近真实场景。经过对主办方提供的开发集进行仔细观察后,我们总结了本次数据的一些特点:
此外,本次评测,主办方仅提供了约3000条真实数据用于模型训练,因此合适的数据增强策略显得尤为重要。
常见的中文文本错误,大致可以分为三类:拼写错误、语法错误(比如词序,词语误用)和语义错误(比如句式杂糅和语义重复)。
由于这三类错误的差异较大,我们在以往的实践中发现很难用一个/一种模型就能较好地解决所有类型的错误,因此我们使用了一个三段式流水线纠错的系统,如下图所示:
针对拼写错误,我们使用了基于BERT的序列标注模型加以解决。当将BERT应用到拼写纠错任务时,我们利用BERT获取句子中每个字符的语义向量表示,将其传入一个全连接分类器,输出端的词表为常见字符。
我们也额外尝试了其他最新中文拼写纠错模型(如Realise[1]等),发现在同等数据量下,考虑了字音字形等多模态信息的拼写纠错模型确实能获得更好的性能。但复杂的模型往往需要更大的训练/推理开销,而我们发现在scaling up训练集规模后,单纯的BERT模型也可以取得非常优异的效果。因此为了加速训练,我们仍然只使用了最简单的BERT+Softmax的范式。
在模型训练方面,我们采用了基于混淆集生成的大规模人造语料预训练加小规模真实数据微调的方法。此外,我们发现:Google提供的BERT官方词表中缺失了一些常见的中文标点和汉字,这可能导致一些常见词无法生成。因此我们又挑选了一部分常用标点、汉字(主要来自中文Gigaword和Wikipedia)对其进行了补全。
在解码方面,我们发现模型可能会出现不恰当的修改,甚至会改变句子原义。针对上述问题,我们在模型解码时引入字音字形信息和混淆集信息作为约束,使得模型在每个位置不但要考虑候选字生成的概率,也要考虑是否和原字匹配。具体做法是:模型最终选取结果的依据是BERT输出得分和字符相似度得分的加权和。
语法纠错方面,我们使用了序列到编辑(Sequence-to-Edit,Seq2Edit)和序列到序列(Sequence-to-Sequence,Seq2Seq)两类模型,并且采用编辑级别投票的方式对二者进行集成。相关模型的代码已经开源在:
https://github.com/HillZhang1999/MuCGEC
基于Seq2Edit的语法纠错模型已经被广泛应用在中英文语法纠错任务中,特点是速度快(非自回归),修改精度高。本次评测,我们使用了Grammarly开源的GECToR[2]。
GECToR模型本质上是一个序列标注模型,它的解码空间是插入、删除、替换等编辑操作。通过并行预测编辑并将其应用于原句子,GECToR模型能够完成长度可变的语法纠错。上述过程也可以多轮迭代进行,从而进一步提升修改效果。
基于Seq2Seq的模型采用了目前最常用的Transformer结构,目标是直接将病句“翻译”为正确句子。特别地,我们使用了预训练语言模型对Seq2Seq模型进行初始化。
本次评测中,我们使用了复旦开源的Chinese-BART-Large模型[3],并对其进行了适配和优化(主要是融入了一些外部知识,相关工作会在近期开源),发现Seq2Seq模型由于能够充分利用语言模型知识、修改灵活,在中文纠错任务上表现得尤为优异。
在相同训练设置下,我们发现Seq2Seq大约优于Seq2Edit结构5个F值,但Seq2Edit模型推理速度约为Seq2Seq模型的20倍以上。
我们最近也上传了一个可供测试的Seq2Seq中文纠错demo,效果还是不错的:
https://modelscope.cn/models/damo/nlp_bart_text-error-correction_chinese/summary
我们在之前的研究中发现[4],Seq2Edit和Seq2Seq模型针对不同类型的错误有着各自的长处,因此集成二者能够取得非常优异的效果。在本次评测中,我们使用一套自适应阈值的编辑级别集成方式,具体的流程为:
实际比赛中,我们集成了6个Seq2Seq和6个Seq2Edit模型,每个模型通过替换随机种子得到。针对一些模型本身纠错精确度较高的错误类型,如拼写错误和词序错误,我们会降低集成的阈值来提升召回度;
而对于一些精确度较低的错误类型,比如词语缺失类错误,我们会提升集成的阈值。我们发现,最近NAACL22[6]的一篇文章和我们的思路相近,不过他们使用了一个逻辑回归模型来学习这一阈值,效果理论上应该会更优。
此外,我们发现,单个模型很容易对命名实体进行误纠,例如人名、地名等,但是集成模型可以很好地缓解这一现象,因为模型对于命名实体的修改往往很不确定,导致这些修改较容易在集成时被过滤掉。
实际评测中,我们发现该集成方法可以提升性能接近10个F1值。
我们通过网络爬虫爬取了互联网上大量的语义错误相关问题,如:“大约...左右是病句吗”,抽取出其中的语义错误模板并扩充为正则表达式形式“大约.*左右”。
我们为此类模板定义了两种简单的修改方式,删除左侧词语和删除右侧词语,并且利用预训练语言模型来自动确定修改动作,最后积累了1000余个模板。相关模板和方法详细介绍已经开源在:
GitHub - HillZhang1999/gec_error_template: Automatically Mining Error Templates for Grammatical Error Correction
此外,通过对本次评测数据的观察,我们也额外提出了一些后处理的小Tricks,如:
本次评测,主办方仅提供了3000条真实数据用于训练,即便加入开发集的4000条数据,总共也不过7000条训练数据。对于data-hungry的生成模型来说,这些数据很明显是不够的,因此我们也在数据增强、清洗等方面进行了一些尝试。
现阶段,文本纠错任务上的主流数据增强方式有两种:基于规则和基于反向翻译(Back-Translation)。在我们之前的实践中,发现反向翻译的方法可以在中文上取得不错的效果,但是其不可控并且需要训练正反两个模型,开销很大,因此我们着重探索了基于规则的数据增强方式。
首先,我们需要挑选用于加噪的单语语料。在本次评测的早期,我们在开发集上评估了团队之前积累的系统,发现了几个有趣的现象:
因此,我们选用了悟道语料[7]作为本次评测加噪的单语语料,这份数据集采集自互联网,主题多样且采集时间很接近,能够取得很好的效果。
我们首先对原句子进行分词,然后对每10个词的片段随机挑选1个位置植入错误,这主要是为了保留错误位置的上下文语义,以及更符合汉语母语者文本错误稀疏的特点。加噪过程中,采样的具体概率分布依据从比赛开发集中统计得到的近似分布确定。
具体加噪操作如下表所示:
其中,需要适用到以下词表/混淆集资源,比如:
我们发现,一份能够基本覆盖测试集错误映射的词表/混淆集,对于系统性能非常重要。因此,开发纠错系统离不开资源构建等工程性工作。
我们发现,由于单语语料采集自互联网,本身就含有比例不低的各类文本错误,可能对训练模型的结果产生影响,因此我们使用了一种非常简单的迭代式数据清洗方案。具体的做法是:
上述做法的好处有两点,一个是能不断缓解原始单语数据中潜在噪音的影响,另一个就是相当于在做自知识蒸馏;实践中我们发现上述方法(3次迭代)能够提升模型性能2-3个点。
参数设置上,我们对各模型的学习率、Dropout率、Batch-size等参数进行了网格搜索。
拼写纠错模型方面,我们采用约2亿自造的伪数据(第3节方法,仅替换)进行预训练,然后用主办方提供的100万伪语料过滤的拼写错误进行微调,最后用主办方提供的真实数据过滤的拼写错误进行精调;
语法纠错模型方面,我们采用约1亿自造的伪数据(第3节方法)进行预训练,然后用主办方提供的100万伪语料进行微调,最后用主办方提供的真实数据进行精调;
拼写纠错和Seq2Edit模型,使用了阿里的StructBERT以及哈工大的MacBERT、PERT作为Encoder,经线下测试效果优于原始BERT和RoBERTa,因为上述三模型在预训练时均更贴近纠错任务(StructBERT和PERT植入了乱序噪声,MacBERT考虑了词义)。最后决赛也是取得了不错的成绩:
本次比赛,虽然我们的系统取得了不错的成绩,但中文纠错现有的研究距离真实的落地要求仍然相距甚远。这里简单总结下这个任务的难点与后续可能的研究方向。