编组
控制台用户中心

欢迎来到澜舟孟子社区!

澜舟科技为有兴趣入门 NLP 技术的开发者提供各种学习资源指引

code扫码加入孟子开源社区微信群

NLP 入门基础课程

前言

Python 编程

编程相关工具

数学基础

数据处理和分析基础

机器学习基础

深度学习基础

自然语言处理基础

NLP 高级课程

自动摘要生成指南

自动摘要生成指南#

自动文摘的目的是通过对原文本进行压缩、提炼,为用户供简明扼要的文字描述。自动文摘是一个信息压缩过程,将输入的一篇或多篇文档内容总结为一段简要描述。该过程中不可避免会有信息损失,但是要求保留尽可能多的重要信息。自动文摘也是自然语言生成领域中的一个重要任务。本文中,我们以文本摘要任务为例,展示孟子预训练模型在下游任务上微调的流程。整体流程可以分为4部分:

  • 数据加载
  • 数据预处理
  • 模型训练
  • 模型推理

下面通过中文科学文献数据(CSL)文本摘要数据进行演示。

数据下载地址: https://github.com/CLUEbenchmark/CLGE

本文完整示例代码地址: https://github.com/Langboat/Mengzi/blob/main/examples/Mengzi_summary.ipynb

数据加载#

CSL数据以json的形式存储,我们可以通过定义read_json函数读取数据文件,将数据加载进内存。

def read_json(input_file: str) -> list:
with open(input_file, 'r') as f:
lines = f.readlines()
return list(map(json.loads, tqdm(lines, desc='Reading...')))
train = read_json("csl/v1/train.json")
dev = read_json("csl/v1/dev.json")

数据集的具体信息如下:

数据划分数据量
训练集2500
测试集500

每个训练样本的原始格式如下:

{
'id': 2364,
'title': '基于语义规则的Web服务发现方法',
'abst': '语义Web服务发现问题研究的核心内容是服务描述与对应的服务发现方法。服务描述分为服务请求描述与服务发布描述,但目前的服务发现方法,并未将请求描述与发布描述分开,以比对服务请求描述与服务发布描述中对应部分作为匹配依据,导致服务请求描述构建困难以及发现结果不够理想。提出以语义规则刻画服务请求描述,以本体构建服务发布描述,进行有效的以语义规则驱动的Web服务发现。对语义规则添加影响因子使得服务匹配精度可以通过匹配度来度量,并按照给定的调节系数来决定最终匹配是否成功。最后以OWL-STCV2测试服务集合进行了对比实验,证实该方法有效地提高了查全率与查准率高,特别是Top-k查准率。'
}

数据预处理#

数据预处理的目的是将原始数据处理为模型可以接受的输入形式,相当于在原始数据和模型输入之间建立管道。 模型输入,可接受的字段为 input_ids、labels,其中 input_ids 为输入文本的 tokenized 表示,可以直接通过 transformers 提供的 Tokenizer 进行转换;labels 为模型期望输出文本的tokenized 表示。 通过定义 DataCollatorForSeq2Seq 数据预处理类,并将其传递给模型完成上述流程。详情见代码。

模型训练#

训练模型前需要指定模型训练的超参数,包括训练的轮数、学习率和学习率管理策略等等。 这一点可以通过实例化 TrainingArguments 类来实现,接着将其传递给 Trainer 来传入这些超参数;然后通过 huggingface 定义的 trainer.train() 方法来进行训练,训练完成后通过 trainer.save_model()方法来保存最佳模型。

Mengzi_tokenizer = T5Tokenizer.from_pretrained(model_path)
Mengzi_model = T5ForConditionalGeneration.from_pretrained(model_path)
trainer = Trainer(
tokenizer=Mengzi_tokenizer,
model=Mengzi_model,
args=training_args,
data_collator=collator,
train_dataset=trainset,
eval_dataset=devset
)
trainer.train()
trainer.save_model("test/best")

模型推理#

最佳模型保存在了 test/best 位置,我们可以加载最佳模型并利用其进行摘要生成。 下面是我们利用模型进行推理的一种实现方式,将希望简化的文本 tokenized 后传入模型,得到经过 tokenizer 解码后即可获得摘要后的文本。当然,读者也可以利用自己熟悉的方式进行生成。

def predict(sources, batch_size=8):
_model = model.eval() #将模型转换为预测模式,使模型内部的dropout失效。
kwargs = {"num_beams": 4}
outputs = []
for start in tqdm(range(0, len(sources), batch_size)):
batch = sources[start:start+batch_size]
input_tensor = tokenizer(batch, return_tensors="pt", truncation=True, padding=True, max_length=512).input_ids.cuda()
outputs.extend(model.generate(input_ids=input_tensor, **kwargs))
return tokenizer.batch_decode(outputs, skip_special_tokens=True)

生成结果评测#

采用自动文摘任务上常用的自动评测指标 Rouge-1, Rouge-2, Rouge-L 对生成文本的质量进行评测。

def rouge_score(candidate, reference):
text1 = " ".join(list(candidate))
text2 = " ".join(list(reference))
score = rouge.get_scores(text1, text2)
print(score)
return score
def compute_rouge(preds, refs):
r1=[]
r2=[]
R_L=[]
for pred, ref in zip(preds, refs):
score = rouge_score(pred, ref)
r1.append(scores[0]["rouge-1"]["f"])
r2.append(scores[0]["rouge-2"]["f"])
R_L.append(scores[0]["rouge-l"]["f"])
return sum(r1)/len(r1), sum(r2)/len(r2), sum(R_L)/len(R_L)
R_1, R_2, R_L = compute_rouge(generations, titles)

已经完成了所有课程的学习?

一起用新一代 NLP 技术推动下一波生产力进化的浪潮吧!

产品服务

商务合作邮箱

bd@langboat.com

ewm

公司地址

北京市海淀区北四环西路(街)52 号方正国际大厦 16 层 1603


gongan京公网安备 11010802035393号京ICP备 2021021087号

经营许可证编号:合字 B2-20220333

大模型备案号:Beijing-MengZiGPT-20231205


合作:

bd@langboat.com

地址:

北京市海淀区北四环西路(街)52 号方正国际大厦 16 层 1603

公众号:

ewm

support
business