【DSW Gallery】基于EasyNLP的中文信息抽取

本文涉及的产品
交互式建模 PAI-DSW,5000CU*H 3个月
简介: EasyNLP提供多种模型的训练及预测功能,旨在帮助自然语言开发者方便快捷地构建模型并应用于生产。本文以中文信息抽取为例,为您介绍如何在PAI-DSW中基于EasyNLP快速使用K-Global Pointer算法进行中文信息抽取模型的训练、评估、推理。

直接使用

请打开基于EasyNLP的中文信息抽取,并点击右上角 “ 在DSW中打开” 。

image.png

基于EasyNLP的信息抽取

EasyNLP是阿里云PAI算法团队基于PyTorch开发的易用且丰富的NLP算法框架( https://github.com/alibaba/EasyNLP ),支持常用的中文预训练模型和大模型落地技术,并且提供了从训练到部署的一站式NLP开发体验。EasyNLP提供多种模型的训练及预测功能,旨在帮助自然语言开发者方便快捷地构建模型并应用于生产。

本文以信息抽取任务为例,如何在EasyNLP框架中使⽤K-Global Pointer模型。

关于K-Global Pointer算法

    Global Pointer模型是由苏剑林提出的解决命名实体识别任务的模型,其主要思想是构建一个\(n*n\)的矩阵\(A\)\(n\)为序列长度),\(A[i,j]\)代表的是序列\(i\)到序列\(j\)组成的连续子串为对应实体类型的概率,通过设计门槛值\(B\)即可将文本中具有特定意义的实体识别出来。

    K-Global Pointer模型是在Global Pointer模型的基础之上改进的。首先我们将仅支持命名实体识别的模型拓展成支持中文信息抽取三大任务的模型。然后,我们使用了MacBERT预训练语言模型来将文本序列转换成向量序列。最后我们针对不同的任务设计了一套prompt模板,其能帮助预训练语言模型“回忆”起自己在预训练时“学习”到的东西。接下来,我们将根据中文信息抽取三大任务分别进行阐述。

    针对命名实体识别任务,我们有文本\(w_1,w_2,w_3,\ldots,w_n\)以及需要提取的实体类型\(entity\_type\),对应的prompt为“找到文章中所有【\(entity\_type\)】类型的实体?”,对应的输入模型的文本\(H\)为“找到文章中所有【\(entity\_type\)】类型的实体?文章:【\(w_1,w_2,w_3,\ldots,w_n\)】”,模型经过相应的处理即可输出文本中实体类型为\(entity\_type\)的实体。

关于信息抽取

信息抽取的三大任务是命名实体识别、关系抽取、事件抽取。命名实体识别是指识别文本中具有特定意义的实体,包括人名、地名、机构名、专有名词等;关系抽取是指识别文本中实体之间的关系;事件抽取是指识别文本中的事件信息并以结构化的形式呈现出来。信息抽取技术被广泛应用于知识图谱的构建、机器阅读理解、智能问答和信息检索系统中。信息抽取的三大任务不是相互独立的关系,而是相互依存、彼此依赖的关系。命名实体识别是关系抽取、事件抽取的基础,关系抽取是事件抽取的基础。同时,关系抽取、事件抽取对命名实体识别任务有帮助,事件抽取对关系抽取任务有帮助。但目前关于仅使用一个模型完成中文信息抽取三大任务的研究相对较少,因此,我们提出K-Global Pointer算法并集成进EasyNLP算法框架中,使用户可以使用自定义数据集训练中文信息抽取模型并使用。

运行环境要求

建议用户使用:Python 3.6,Pytorch 1.8镜像,GPU机型 P100 or V100,内存至少为 32G

EasyNLP安装

建议从GitHub下载EasyNLP源代码进行安装,命令如下:

! echo y | pip uninstall pai-easynlp easynlp
! git clone https://github.com/alibaba/EasyNLP.git 
! pip install -r EasyNLP/requirements.txt -i http://mirrors.aliyun.com/pypi/simple
! cd EasyNLP && python setup.py install

安装完成easynlp之后,建议重启notebook,防止环境存在缓存,未更新

您可以使用如下命令验证是否安装成功:

import easynlp
easynlp.__file__

如果您系统内已经安装完easynlp的CLI工具,则说明EasyNLP代码库已经安装。

数据准备

首先,您需要进入指定模型目录,下载用于本示例的训练和测试集,命令如下:

!wget http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/ie/train.tsv
!wget http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/ie/train_part.tsv
!wget http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/ie/dev.tsv
!wget http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/ie/predict_input_EE.tsv
!wget http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/ie/predict_input_NER.tsv

训练和测试数据都是以\t隔开的.tsv文件,数据下载完成后,可以通过以下代码查看前5条数据。数据表示为train.tsv文件以及dev.tsv文件,这两个⽂件都包含以制表符\t分隔的五列,第一列是标签,第二列是上文K-Global Pointer模型详解中提到的\(H\),第三列是答案的开始,第四列是答案的的结束,第五列是答案。

print('Training data sample:')
! head -n 5 train.tsv
print("&"*50)
print('Development set data sample:')
! head -n 5 dev.tsv

初始化

在Python 3.6环境下,我们首先从刚刚安装好的EasyNLP中引入模型运行需要的各种库,并做一些初始化。在本教程中,我们使用hfl/macbert-large-zh。EasyNLP中集成了丰富的预训练模型库,如果想尝试其他预训练模型,如RoBERTa、albert等,也可以在user_defined_parameters中进行相应修改,具体的模型名称可见模型列表。这里只需要在user_defined_parameters中指定pretrain_model_name_or_path=hfl/macbert-large-zh,即可指定信息抽取任务的模型。

import torch.cuda
from easynlp.appzoo import InformationExtractionDataset
from easynlp.appzoo import get_application_predictor, get_application_model, get_application_evaluator, get_application_model_for_evaluation
from easynlp.core import Trainer, PredictorManager
from easynlp.utils import initialize_easynlp, get_args, get_pretrain_model_path
from easynlp.utils.global_vars import parse_user_defined_parameters
initialize_easynlp()
args = get_args()
args.user_defined_parameters = 'pretrain_model_name_or_path=hfl/macbert-large-zh'
user_defined_parameters = parse_user_defined_parameters(args.user_defined_parameters)
# 保存路径
args.checkpoint_dir = "./information_extraction_model/"
args.sequence_length=512
args.micro_batch_size=16
args.weight_decay=0.0
args.save_checkpoint_steps=500
args.gradient_accumulation_steps=8
args.epoch_num=1
args.learning_rate=2e-05
args.random_seed=42
args.worker_gpu=4
args.app_name = "information_extraction"
args.first_sequence= "sent"

注意:上述代码如果出现“Address already in use”错误,则需要运行以下代码清理端口上正在执行的程序。

netstat -tunlp|grep 6000

kill -9 PID (需要替换成上一行代码执行结果中对应的程序ID)

载入数据

我们使用EasyNLP中自带的InformationExtractionDataset,对训练和测试数据进行载入。主要参数如下:

  • pretrained_model_name_or_path:预训练模型名称路径,这里我们使用封装好的get_pretrain_model_path函数,来处理模型名称"bert-base-uncased"以得到其路径,并自动下载模型
  • data_file 训练或测试的数据文件
  • max_seq_length:总输入文本的最大长度,超过将截断,不足将padding
  • input_schema:输入tsv数据的格式,逗号分隔的每一项对应数据文件中每行以\t分隔的一项,每项开头为其字段标识,如question_text、answer_text、context_text等
  • first_sequence、second_sequence:用于说明input_schema中哪些字段用于作为问句、描述,input_schema中其他字段名(qas_id、answer_name、start_position_name)将在user_defined_parameters中进行声明
  • user_defined_parameters:任务特定的预声明参数。在机器阅读理解任务中,需要声明如下几种:
  • pretrain_model_name_or_path:同上
  • is_training:是否为训练过程,train_dataset为True,valid_dataset为False
args.label_name="label"
args.outputs = "aug.tsv"
args.data_threads=5
args.output_schema="augmented_data"
args.tables = "train.tsv,dev.tsv"
args.input_schema = "id:str:1,instruction:str:1,start:str:1,end:str:1,target:str:1"
args.pretrained_model_name_or_path = user_defined_parameters.get('pretrain_model_name_or_path', None)
args.pretrained_model_name_or_path = get_pretrain_model_path(args.pretrained_model_name_or_path)
train_dataset = InformationExtractionDataset(
        pretrained_model_name_or_path=args.pretrained_model_name_or_path,
        data_file=args.tables.split(",")[0],
        input_schema=args.input_schema,
        max_seq_length=args.sequence_length,
        first_sequence=args.first_sequence,
        second_sequence=args.second_sequence,
        label_name=args.label_name,
        label_enumerate_values=args.label_enumerate_values,
        user_defined_parameters=user_defined_parameters,
        is_training=True)
valid_dataset = InformationExtractionDataset(
        pretrained_model_name_or_path=args.pretrained_model_name_or_path,
        data_file=args.tables.split(",")[-1],
        max_seq_length=args.sequence_length,
        input_schema=args.input_schema,
        first_sequence=args.first_sequence,
        second_sequence=args.second_sequence,
        label_name=args.label_name,
        label_enumerate_values=args.label_enumerate_values,
        user_defined_parameters=user_defined_parameters,
        is_training=False)

由于之前我们选用了hfl/macbert-large-zh,因此这里也会对预训练模型进行自动下载并载入。

模型训练

处理好数据与模型载入后,我们开始训练模型。 我们使用EasyNLP中封装好的get_application_model函数进行训练时的模型构建,其参数如下:

  • app_name:任务名称,这里选择机器阅读理解"information_extraction"
  • pretrained_model_name_or_path:预训练模型名称路径,这里我们使用封装好的get_pretrain_model_path函数,来处理模型名称"bert-base-uncased"以得到其路径,并自动下载模型
  • user_defined_parameters:用户自定义参数,直接填入刚刚处理好的自定义参数user_defined_parameters
model = get_application_model(app_name="information_extraction",
                              pretrained_model_name_or_path=get_pretrain_model_path("hfl/macbert-large-zh"),
                              user_defined_parameters=user_defined_parameters
                              )
trainer = Trainer(model=model, 
                  train_dataset=train_dataset,
                  evaluator=get_application_evaluator(app_name="information_extraction", 
                                                      valid_dataset=valid_dataset,
                                                      eval_batch_size=16,
                                                      pretrained_model_name_or_path=get_pretrain_model_path("hfl/macbert-large-zh"),
                                                      user_defined_parameters=user_defined_parameters,
                                                      few_shot_anchor_args=args
                                                      ))
trainer.train()

模型评估

训练过程结束后,train好的模型被我们保存在一开始指定好的checkpoint_dir中,本地路径为"./information_extraction_model/"。我们可以对train好的模型进行效果评估。我们同样先使用EasyNLP中的get_application_model_for_evaluation方法构建评估模型。

model = get_application_model_for_evaluation(app_name="information_extraction",
                                             pretrained_model_name_or_path="./information_extraction_model/", 
                                             user_defined_parameters=user_defined_parameters
                                             )
evaluator = get_application_evaluator(app_name="information_extraction", 
                                      valid_dataset=valid_dataset,
                                      eval_batch_size=32, 
                                      user_defined_parameters=user_defined_parameters,
                                      few_shot_anchor_args=args
                                      )
model.to(torch.cuda.current_device())
evaluator.evaluate(model=model)

模型预测

我们同样可以使用训练好的模型进行信息抽取的预测。我们首先创建一个predictor,并据此实例化一个PredictorManager实例。我们指定预测好的结果输出在指定的tsv文件中。

命名实体识别

对于命名实体识别任务,数据表示为predict_input_NER.tsv文件,这个⽂件包含以制表符\t分隔的三列,第一列是标签,第二列是实体类型,第三列是文本。我们支持对同一个文本识别多种实体类型,仅需要在第二列中将不同的实体类型用;分隔开。

代码如下:

args.tables="predict_input_NER.tsv"
args.outputs="predict_output_NER.tsv" 
args.input_schema="id:str:1,scheme:str:1,content:str:1" 
args.output_schema="id,content,q_and_a" 
args.worker_gpu=4 
args.sequence_length=512 
args.micro_batch_size=16
args.checkpoint_dir="./information_extraction_model/"
args.data_threads=5 
args.user_defined_parameters='task=NER'
predictor = get_application_predictor(
            app_name=args.app_name,
            model_dir=args.checkpoint_dir,
            input_schema=args.input_schema,
            sequence_length=args.sequence_length,
            output_file=args.outputs,
            user_defined_parameters=parse_user_defined_parameters(args.user_defined_parameters))
predictor_manager = PredictorManager(
    predictor=predictor,
    input_file=args.tables.split(",")[0],
    skip_first_line=args.skip_first_line,
    input_schema=args.input_schema,
    output_file=args.outputs,
    output_schema=args.output_schema,
    append_cols=args.append_cols,
    batch_size=args.micro_batch_size
)
predictor_manager.run()
exit()

输入以下命令,可以展示通过训练后的模型预测出的内容。

print('Predicted results:  id  context  q_and_a')
! head -n 5 predict_output_NER.tsv

事件抽取任务

对于关系抽取任务,数据表示为predict_input_RE.tsv文件,这个⽂件包含以制表符\t分隔的三列,第一列是标签,第二列是关系类型,第三列是文本。我们支持对同一个文本识别多种关系类型,仅需要在第二列中将不同的关系类型用;分隔开。对于一个关系类型relation_type(subject_type-predicate-object_type)表示为subject_type:predicate。

代码如下

args.tables="predict_input_EE.tsv"
args.outputs="predict_output_EE.tsv" 
args.input_schema="id:str:1,scheme:str:1,content:str:1" 
args.output_schema="id,content,q_and_a" 
args.worker_gpu=4 
args.sequence_length=512 
args.micro_batch_size=16
args.checkpoint_dir="./information_extraction_model/"
args.data_threads=5 
args.user_defined_parameters='task=EE'
predictor = get_application_predictor(
            app_name=args.app_name,
            model_dir=args.checkpoint_dir,
            input_schema=args.input_schema,
            sequence_length=args.sequence_length,
            output_file=args.outputs,
            user_defined_parameters=parse_user_defined_parameters(args.user_defined_parameters))
predictor_manager = PredictorManager(
    predictor=predictor,
    input_file=args.tables.split(",")[0],
    skip_first_line=args.skip_first_line,
    input_schema=args.input_schema,
    output_file=args.outputs,
    output_schema=args.output_schema,
    append_cols=args.append_cols,
    batch_size=args.micro_batch_size
)
predictor_manager.run()
exit()
print('Predicted results:  id  context  q_and_a')
! head -n 5 predict_output_EE.tsv
Predicted results:  id  context  q_and_a
1 2022语言与智能技术竞赛由中国中文信息学会和中国计算机学会联合主办,百度公司、中国中文信息学会评测工作委员会和中国计算机学会自然语言处理专委会承办,已连续举办4届,成为全球最热门的中文NLP赛事之一。 [['竞赛名称(2022语言与智能技术竞赛)-承办方', '百度公司', 0.69364333152771, 66, 70], ['竞赛名称(2022语言与智能技术竞赛)-已举办次数', '4届', 0.7212715744972229, 113, 115]]

一步执行

值得一提的是,上述所有训练/评估/预测代码,都已经被集成在EasyNLP/examples/information_extraction/main.py中,此外,我们也预先编写好了多种可供直接执行的脚本。用户可以通过带参数运行main.py中指令,或者直接使用bash文件命令行执行的方式,一步执行上述所有训练/评估/预测操作。

main文件一步执行

用户通过以下代码带参数执行main.py中的指令,可直接对模型进行训练/评估/预测操作。

训练代码指令如下。参数说明如“载入数据”小节中所示。在本示例中,预训练模型指定为bert-base-uncased。

! python EasyNLP/examples/information_extraction/main.py \
    --mode train \
    --tables=train.tsv,dev.tsv \
    --input_schema=id:str:1,instruction:str:1,start:str:1,end:str:1,target:str:1 \
    --worker_gpu=4 \
    --app_name=information_extraction \
    --sequence_length=512 \
    --weight_decay=0.0 \
    --micro_batch_size=2 \
    --checkpoint_dir=./information_extraction_model/ \
    --data_threads=5 \
    --user_defined_parameters='pretrain_model_name_or_path=hfl/macbert-large-zh' \
    --save_checkpoint_steps=500 \
    --gradient_accumulation_steps=8 \
    --epoch_num=3  \
    --learning_rate=2e-05  \
    --random_seed=42

评估代码如下,参数含义与训练是一致的

! python EasyNLP/examples/information_extraction/main.py \
--mode evaluate \
--tables=dev.tsv \
--input_schema=id:str:1,instruction:str:1,start:str:1,end:str:1,target:str:1 \
--worker_gpu=4 \
--app_name=information_extraction \
--sequence_length=512 \
--weight_decay=0.0 \
--micro_batch_size=2 \
--checkpoint_dir=./information_extraction_model/ \
--data_threads=5

预测代码、参数含义同样与上面保持一致,以命名实体识别和事件抽取任务为例,输入为predict_input_NER.tsv或者predict_input_EE.tsv,输出结果可在predict_output_EE.tsv或者predict_output_NER.tsv中查看。

## 命名实体识别任务预测
! python EasyNLP/examples/information_extraction/main.py \
    --mode predict \
    --tables=predict_input_NER.tsv \
    --outputs=predict_output_NER.tsv \
    --input_schema=id:str:1,scheme:str:1,content:str:1 \
    --output_schema=id,content,q_and_a \
    --worker_gpu=4 \
    --app_name=information_extraction \
    --sequence_length=512 \
    --weight_decay=0.0 \
    --micro_batch_size=4 \
    --checkpoint_dir=./information_extraction_model/ \
    --data_threads=5 \
    --user_defined_parameters='task=NER'
## 事件抽取任务预测
! python EasyNLP/examples/information_extraction/main.py \
    --mode predict \
    --tables=predict_input_EE.tsv \
    --outputs=predict_output_EE.tsv \
    --input_schema=id:str:1,scheme:str:1,content:str:1 \
    --output_schema=id,content,q_and_a \
    --worker_gpu=4 \
    --app_name=information_extraction \
    --sequence_length=512 \
    --weight_decay=0.0 \
    --micro_batch_size=4 \
    --checkpoint_dir=./information_extraction_model/ \
    --data_threads=5 \
    --user_defined_parameters='task=EE'

利用bash文件命令行执行

我们在EasyNLP/examples/information_extraction/文件夹下封装好了多种可直接执行的bash脚本,用户同样可以通过使用bash文件命令行执行的方式来一步完成特征的抽取。以下以run_train_eval_predict_user_defined_local.sh脚本为例。

模型训练:

! cd EasyNLP/examples/information_extraction/ && bash run_train_eval_predict_user_defined_local.sh 0 train

模型评估

! cd EasyNLP/examples/information_extraction/ && bash run_train_eval_predict_user_defined_local.sh 0 evaluate

模型预测:

! cd EasyNLP/examples/information_extraction/ && bash run_train_eval_predict_user_defined_local.sh 0 predict


相关实践学习
使用PAI-EAS一键部署ChatGLM及LangChain应用
本场景中主要介绍如何使用模型在线服务(PAI-EAS)部署ChatGLM的AI-Web应用以及启动WebUI进行模型推理,并通过LangChain集成自己的业务数据。
机器学习概览及常见算法
机器学习(Machine Learning, ML)是人工智能的核心,专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能,它是使计算机具有智能的根本途径,其应用遍及人工智能的各个领域。 本课程将带你入门机器学习,掌握机器学习的概念和常用的算法。
相关文章
|
缓存 自然语言处理 算法
【DSW Gallery】基于EasyNLP Transformer模型的中文文图生成
EasyNLP提供多种模型的训练及预测功能,旨在帮助自然语言开发者方便快捷地构建模型并应用于生产。本文简要介绍文图生成的技术,以及如何在PAI-DSW中基于EasyNLP轻松实现文图生成,带你秒变艺术家。
【DSW Gallery】基于EasyNLP Transformer模型的中文文图生成
|
算法 PyTorch 算法框架/工具
【DSW Gallery】基于EasyCV的视频分类示例
EasyCV是基于Pytorch,以自监督学习和Transformer技术为核心的 all-in-one 视觉算法建模工具,并包含图像分类,度量学习,目标检测,姿态识别等视觉任务的SOTA算法。本文以视频分类为例,为您介绍如何在PAI-DSW中使用EasyCV。
【DSW Gallery】基于EasyCV的视频分类示例
|
文字识别 并行计算 算法
【DSW Gallery】基于EasyCV的文字识别示例
EasyCV是基于Pytorch,以自监督学习和Transformer技术为核心的 all-in-one 视觉算法建模工具,并包含图像分类,度量学习,目标检测,姿态识别等视觉任务的SOTA算法。本文以文字识别为例,为您介绍如何在PAI-DSW中使用EasyCV。
【DSW Gallery】基于EasyCV的文字识别示例
|
人工智能 并行计算 算法
【DSW Gallery】基于MOCOV2的自监督学习示例
EasyCV是基于Pytorch,以自监督学习和Transformer技术为核心的 all-in-one 视觉算法建模工具,并包含图像分类,度量学习,目标检测,姿态识别等视觉任务的SOTA算法。本文以自监督学习-MOCO为例,为您介绍如何在PAI-DSW中使用EasyCV。
【DSW Gallery】基于MOCOV2的自监督学习示例
|
机器学习/深度学习 人工智能 编解码
【DSW Gallery】基于EasyNLP-Diffusion模型的中文文图生成
EasyNLP提供多种模型的训练及预测功能,旨在帮助自然语言开发者方便快捷地构建模型并应用于生产。本文简要介绍文图生成的技术,以及如何在PAI-DSW中基于EasyNLP使用diffusion model进行finetune和预测评估。
【DSW Gallery】基于EasyNLP-Diffusion模型的中文文图生成
|
并行计算 算法 自动驾驶
【DSW Gallery】基于EasyCV的BEVFormer 3D检测示例
EasyCV是基于Pytorch,以自监督学习和Transformer技术为核心的 all-in-one 视觉算法建模工具,并包含图像分类,度量学习,目标检测,姿态识别等视觉任务的SOTA算法。本文将以BEVFormer 3D检测为例,为您介绍如何在PAI-DSW中使用EasyCV。
【DSW Gallery】基于EasyCV的BEVFormer 3D检测示例
|
并行计算 算法 PyTorch
【DSW Gallery】 基于EasyCV的Mask2Former图像分割示例
EasyCV是基于Pytorch,以自监督学习和Transformer技术为核心的 all-in-one 视觉算法建模工具,并包含图像分类,度量学习,目标检测,姿态识别等视觉任务的SOTA算法。本文将介绍使用EasyCV进行图像分割模型的训练和预测。
【DSW Gallery】 基于EasyCV的Mask2Former图像分割示例
|
分布式计算 算法 搜索推荐
【DSW Gallery】Gbdt-FM模型
GBDT+FM 模型是由 Gbdt+LR 延伸出来的模型。该模型利用GBDT自动进行特征筛选和组合,进而生成新的离散特征向量,再把该特征向量当做 FM 模型的输入,来产生最后的预测结果。该模型能够综合利用用户、物品和上下文等多种不同的特征,生成较为全面的推荐,在CTR点击率预估场景下使用较为广泛。
【DSW Gallery】Gbdt-FM模型
|
自然语言处理 Shell 开发者
【DSW Gallery】基于EasyNLP的中文新闻标题生成
EasyNLP提供多种模型的训练及预测功能,旨在帮助自然语言开发者方便快捷地构建模型并应用于生产。本文以中文新闻标题生成为例,为您介绍如何在PAI-DSW中使用EasyNLP。
【DSW Gallery】基于EasyNLP的中文新闻标题生成
|
机器学习/深度学习 自然语言处理 算法
【DSW Gallery】基于EasyNLP的多模态CLIP图文检索
EasyNLP提供多种模型的训练及预测功能,旨在帮助自然语言开发者方便快捷地构建模型并应用于生产。本文以多模态图文检索为例,为您介绍如何在PAI-DSW中基于EasyNLP快速使用CLIP进行跨模态图文检索任务的训练、评估、预测。
【DSW Gallery】基于EasyNLP的多模态CLIP图文检索