关系预测任务
任务简介
关系预测是自然语言处理当中的一项重要的任务,用于预测文本中两个指定实体之间关系。是关系抽取、自动知识图谱构建的重要一环,在问答系统、搜索引擎、推荐系统中都有着十分广泛的应用。
ERNIE预训练模型选择
文心提供的ERNIE预训练模型的参数文件和配置文件在 wenxin_appzoo/wenxin_appzoo/models_hub目录下,使用对应的sh脚本,即可拉取对应的模型、字典、必要环境等文件。目前支持关系预测的预训练模型为:
模型名称 | 下载脚本 | 备注 |
---|---|---|
ERNIE 3.0 | sh download_ernie_3.0_ch.sh | 参数、字典与infer所需环境下载存放于 ernie_3.0_ch_dir目录 |
ERNIE 3.0-1.5B | download_ernie_3.0_1.5b_ch.sh | 参数、字典和网络配置文件下载存放于ernie_1.5b_ch_dir目录 |
快速开始
代码结构
任务代码位于:./wenxin_appzoo/tasks/relation_prediction
├── data # 训练数据
│ └── finre
│ ├── dev
│ │ └── dev.json
│ ├── label_map.json
│ ├── predict
│ │ └── predict.json
│ ├── test
│ │ └── test.json
│ └── train
│ └── train.json
├── data_set_reader # 数据加载相关类
│ ├── ernie_relation_pred_base_dataset_reader.py
│ └── ernie_relation_pred_dataset_reader.py
├── examples
│ ├── cls_ernie_1.5b_finre_ch.json # ERNIE3.0-1.5B训练和eval的json配置文件
│ ├── cls_ernie_1.5b_finre_ch_infer.json # ERNIE3.0-1.5B利用inference-model预测的json配置文件
│ ├── cls_ernie_1.5b_finre_ch_save_infer_from_ckpt.json # ERNIE3.0-1.5B转化checkpoints为inference_model的配置文件
│ ├── cls_ernie_3.0_finre_ch_infer.json # ERNIE3.0利用inference-model预测的json配置文件
│ ├── cls_ernie_3.0_finre_ch.json # ERNIE3.0训练与eval的json配置文件
│ └── cls_ernie_3.0_finre_ch_save_infer_from_ckpt.json # ERNIE3.0转化checkpoints为inference_model的配置文件
├── inference # 推理相关类
│ ├── custom_inference.py
│ ├── custom_relationpred_inference_ernie3.py
│ └── __init__.py
├── __init__.py
├── model # 模型文件
│ ├── ernie3_relation_pred.py
│ ├── ernie_billions_relation_pred.py
│ └── __init__.py
├── package # ernie_3词表与配置文件
│ ├── config
│ │ ├── ernie_base_config.json
│ │ └── ernie_config.json
│ └── dict
│ └── vocab_ernie.txt
├── reader
│ ├── categorical_field_reader.py
│ └── multi_label_field_reader.py
├── run_infer_ernie3.py # ernie_3推理入口文件,只依靠json进行模型预测的入口脚本
├── run_infer.py
├── run_trainer.py # 训练文件入口文件,只依靠json进行模型训练的入口脚本
└── trainer
├── custom_dynamic_trainer.py
├── custom_trainer_ernie3.py
├── custom_trainer.py
└── __init__.py
数据准备
文心中的训练集、验证集、测试集分别存放在./data/${具体任务名} 目录下的train, dev, test文件夹下。目前上线的具体任务为FinRE,是一个金融领域的关系预测数据集,数据整体为一个list形式的json文件,其中的每一项就是一条训练样本,具体形式如下:
[
{"label": "合并", "text": "东方航空AH股临时停牌传将与上航合并", "ents": [[0, 4], [14, 16]]},
{"label": "减持", "text": "去年底,太原重工根据祁县公司的财务状况,对其计提全额减值准备<N>万元。", "ents": [[4, 8], [10, 14]]},
{"label": "被减持", "text": "去年底,太原重工根据祁县公司的财务状况,对其计提全额减值准备<N>万元。", "ents": [[10, 14], [4, 8]]},
...
]
其中,每个样本包含三个字段:
- "text": 输入文本。
- "ents": 待预测关系的两个实体在输入文本中的位置(起点与终点,不含终点对应的字符)。
- "label": 需要预测的标签,通过训练目录下的label_map.json文件可以将文本标签转为数字id。
同时用于预测的预测集存放在同目录的predict文件夹下,文件中删除了"label"字段:
[
{"text": "近日,在“<N>深圳光电显示周暨深圳彩电节”期间,京东方正式发布AM-OLED发展规划,积极布局新型显示技术。", "ents": [[8, 12], [25, 28]]},
{"text": "随后华为和中兴都对该指控做出了回应。", "ents": [[2, 4], [5, 7]]},
]
如果您要使用自己的数据集进行训练/预测的话,可以按照上述内容将数据处理为相同的格式。
模型准备
模型均存放于./wenxin_appzoo/models_hub文件夹下,进入文件夹执行下载脚本即可获得模型参数等。
cd ./wenxin_appzoo/models_hub
#如果使用ernie3.0模型,则使用下面命令下载
sh download_ernie_3.0_ch.sh
#如果使用ernie3.0-1.5b模型,则使用下面命令下载
sh download_ernie_3.0_1.5b_ch.sh
训练准备
训练与验证的配置代码如下:(examples/cls_ernie_3.0_finre_ch.json)
{
"dataset_reader": {
"train_reader": {
"name": "train_reader", ## 训练、验证、测试各自基于不同的数据集,数据格式也可能不一样,可以在json中配置不同的reader,此处为训练集的reader。
"type": "ErnieRelationClassifyReader", ## 采用ErnieClassificationReader,其封装了常见的读取tsv、json文件、组batch等操作。
"fields": [], ## 由于此任务直接从json文件中获取指定域,故这里置为空
"config": {
"data_path": "./data/finre/train", ## 数据路径。
"shuffle": true, ## 数据在读取过程中是否需要打乱顺序。
"batch_size": 4, ## 超参数之一,表示每个step训练多少个样本,每个step训练的总样本数为batch_size×卡数。
"epoch": 5, ## 超参数之一,表示这个数据集中的数据会被重复训练多少轮。
"sampling_rate": 1.0, ## 数据集的采样率,文心预留参数,暂时不起作用,后续版本会升级。
"need_data_distribute": true,
"extra_params":{
"vocab_path":"../../models_hub/ernie_3.0_ch_dir/vocab.txt", ## 指定词表
"label_map_config":"./data/finre/label_map.json",
"max_seq_len":512, ## 控制截断长度,输入文本整体不超过max_seq_len个tokens
"do_lower_case":true,
"in_tokens":false,
"tokenizer": "FullTokenizer" ## 指定输入文本的分词器,ernie_3固定为FullTokenizer分词器。
}
}
},
"test_reader": { # 此处为测试集的reader。
"name": "test_reader",
"type": "ErnieRelationClassifyReader",
"fields": [],
"config": {
"data_path": "./data/finre/test",
"shuffle": false,
"batch_size": 16,
"epoch": 1,
"sampling_rate": 1.0,
"need_data_distribute": true,
"extra_params":{
"vocab_path":"../../models_hub/ernie_3.0_ch_dir/vocab.txt",
"label_map_config":"./data/finre/label_map.json",
"max_seq_len":512,
"do_lower_case":true,
"in_tokens":false,
"tokenizer": "FullTokenizer"
}
}
},
"dev_reader": { # 此处为验证集的reader。
"name": "dev_reader",
"type": "ErnieRelationClassifyReader",
"fields": [],
"config": {
"data_path": "./data/finre/dev",
"shuffle": false,
"batch_size": 16,
"epoch": 1,
"sampling_rate": 1.0,
"need_data_distribute": true,
"extra_params":{
"vocab_path":"../../models_hub/ernie_3.0_ch_dir/vocab.txt",
"label_map_config":"./data/finre/label_map.json",
"max_seq_len":512,
"do_lower_case":true,
"in_tokens":false,
"tokenizer": "FullTokenizer"
}
}
}
},
"model": {
"type": "Ernie3RelationPred",
"num_labels":44, ## 任务类别的个数,依据任务调整
"embedding": {
"emb_dim": 4096,
"use_amp": true,
"mem_len": 0,
"weight_sharing": false,
"training_server": true, # 是否开启server的训练。对于生成任务不起效。
"config_path": "../../models_hub/ernie_3.0_ch_dir/ernie_config.json"
},
"optimization":{ ## 优化器设置,文心ERNIE推荐的默认设置。
"learning_rate": 2e-5,
"use_lr_decay": true,
"use_default_decay": false,
"lr_scheduler": "linear_warmup_decay",
"use_release_paddle": false,
"epsilon": 1e-6,
"warmup_steps": 0,
"warmup_proportion": 0.1,
"weight_decay": 0.01,
"use_dynamic_loss_scaling": false,
"init_loss_scaling": 524288,
"incr_every_n_steps": 1000,
"decr_every_n_nan_or_inf": 2,
"incr_ratio": 2.0,
"decr_ratio": 0.5,
"use_layer_decay": false,
"layer_decay_ratio": 0.95,
"n_layers": 60, # 整体模型层数
"sharing_layers": 48 # server层数
}
},
"trainer": {
"type" : "CustomTrainerErnie3",
"PADDLE_PLACE_TYPE": "gpu",
"PADDLE_IS_FLEET": 1,
"is_recompute": true, # 是否开启重计算,默认开启。通过使用内存与磁盘存储训练前向阶段的激活值,减少了显存的占用,可以加载具有更多参数的模型。
"ramdom_seed": 1,
"use_amp": true, # 是否开启混合精度训练,默认开启。
"use_sharding": true, # 是否开启sharding,默认开启。可以将模型参数自动分配到多个显卡上,实现超大模型训练的关键分布式训练技术。
"save_inference_model": false, # 是否开启训练时保存inference_model,默认关闭。注意:暂不支持开启sharding训练时保存inference_model,请使用checkpoints到inference_model的转化工具。
"use_fast_executor": true,
"train_log_step": 10,
"is_do_train": 1,
"is_eval_dev": 1, # 是否开启dev集评估,默认开启
"is_eval_test": 1, # 是否开启test集评估,默认开启
"eval_step": 100, ## 进行测试集或验证集评估的间隔步数。
"save_model_step": 1000000000000, ## 保存模型时的间隔步数,建议设置为eval_step的整数倍。
"load_parameters": "", ## 加载包含各op参数值的训练好的模型,用于热启动。此处填写checkpoint路径。不填则表示不使用热启动。
"load_checkpoint": "", ## 加载包含学习率等所有参数的训练模型,用于热启动。此处填写checkpoint路径。不填则表示不使用热启动。
"pre_train_model": [
{
"name": "ernie_3.0_ch", ## 预训练模型的名称name
"params_path": "../../models_hub/ernie_3.0_ch_dir/params" ## 预训练模型的目录params_path
}
],
"output_path": "./output/cls_ernie_3.0_finre_ch" ## 保存模型的输出路径
}
}
注:ERNIE3.0-1.5B可在单卡中运行,若采用单卡运行时use_sharding设为false,此时save_inference_model可设为true,即无需通过转化工具即可保存预测模型。
开始训练
进入指定任务的目录,关系预测的目录为wenxin_appzoo/wenxin_appzoo/tasks/relation_prediction, 运行
- ERNIE3.0百亿
# ERNIE3.0百亿
fleetrun --log_dir log ./run_trainer.py --param_path "./examples/cls_ernie_3.0_finre_ch.json" 1>log/lanch.log 2>&1
- ERNIE3.0-1.5B
# ERNIE3.0-1.5B
fleetrun --log_dir log ./run_trainer.py --param_path "./examples/cls_ernie_1.5b_finre_ch.json" 1>log/lanch.log 2>&1
- 通过上述脚本调用json文件开启训练 (注意ERNIE3.0-1.5B单卡训练时也需fleetrun启动)。
- 训练阶段日志文件于log文件夹下,workerlog.N 保存了第N张卡的log日志内容,如遇到程序报错可以通过查看不同卡的workerlog.N定位到有效的报错信息。
- 训练模型保存于./output/cls_ernie_3.0_finre_ch文件夹下。
预测准备
将训练过程中保存的checkpoints格式参数转成预测推理的inference_model参数格式,配置文件如下:
(注:若ERNIE 3.0-1.5B单卡运行且保存了预测模型时,可跳过使用转化工具这个步骤,直接预测即可)
{
"dataset_reader": {
"train_reader": {
"name": "train_reader",
"type": "ErnieRelationClassifyReader",
"fields": [],
"config": {
"data_path": "./data/finre/train",
"shuffle": true,
"batch_size": 4,
"epoch": 5,
"sampling_rate": 1.0,
"need_data_distribute": true,
"extra_params":{
"vocab_path":"../../models_hub/ernie_3.0_ch_dir/vocab.txt",
"label_map_config":"./data/finre/label_map.json",
"max_seq_len":512,
"do_lower_case":true,
"in_tokens":false,
"tokenizer": "FullTokenizer"
}
}
}
},
"model": {
"type": "Ernie3RelationPred",
"num_labels":44,
"embedding": {
"emb_dim": 4096,
"use_amp": true,
"mem_len": 0,
"weight_sharing": false,
"training_server": true,
"config_path": "../../models_hub/ernie_3.0_ch_dir/ernie_config.json"
},
"optimization":{
"learning_rate": 2e-5,
"use_lr_decay": true,
"use_default_decay": false,
"lr_scheduler": "linear_warmup_decay",
"use_release_paddle": false,
"epsilon": 1e-6,
"warmup_steps": 0,
"warmup_proportion": 0.1,
"weight_decay": 0.01,
"use_dynamic_loss_scaling": false,
"init_loss_scaling": 524288,
"incr_every_n_steps": 1000,
"decr_every_n_nan_or_inf": 2,
"incr_ratio": 2.0,
"decr_ratio": 0.5,
"use_layer_decay": false,
"layer_decay_ratio": 0.95,
"n_layers": 60,
"sharing_layers": 48
}
},
"trainer": {
"type" : "CustomTrainerErnie3",
"PADDLE_PLACE_TYPE": "cpu",
"PADDLE_IS_FLEET": 1,
"is_recompute": false,
"ramdom_seed": 1,
"use_amp": false,
"use_sharding": false,
"save_inference_model": true,
"use_fast_executor": true,
"train_log_step": 10,
"is_do_train": 1,
"is_eval_dev": 0,
"is_eval_test": 0,
"eval_step": 100,
"save_model_step": 1000000000000,
"load_parameters": "",
"load_checkpoint": "",
"pre_train_model": [
{
"name": "ernie_3.0_ch",
"params_path": "../../models_hub/ernie_3.0_ch_dir/params"
}
],
"output_path": "./output/cls_ernie_3.0_finre_ch"
}
}
- 设置学习率learning_rate为0,load_parameters中填入训练时保存的checkpoints的文件路径。
- 运行如下脚本保存inference_model,耗时大约20分钟。
export CPU_NUM='1'
export CUDA_VISIBLE_DEVICES=0 # mask out other gpus for saving inference-model
fleetrun --log_dir log ./run_trainer.py --param_path "./examples/cls_ernie_3.0_finre_ch_save_infer_from_ckpt.json" 1>log/lanch.log 2>&1
- 预测模型保存于./output/cls_ernie_3.0_finre_ch/save_inference_model路径下
预测配置文件如下: (examples/cls_ernie_3.0_finre_ch_infer.json)
{
"dataset_reader": {
"predict_reader": {
"name": "predict_reader",
"type": "ErnieRelationClassifyReader",
"fields": [],
"config": {
"data_path": "./data/finre/predict",
"shuffle": false,
"batch_size": 1,
"epoch": 1,
"sampling_rate": 1.0,
"need_data_distribute": true,
"extra_params":{
"vocab_path":"../../models_hub/ernie_3.0_ch_dir/vocab.txt",
"label_map_config":"./data/finre/label_map.json",
"max_seq_len":512,
"do_lower_case":true,
"in_tokens":false,
"tokenizer": "FullTokenizer"
}
}
}
},
"inference": {
"type": "CustomRelationPredInferenceErnie3",
"output_path": "./output/predict_result.txt",
"output_server_path": "./output/predict_result_server.txt",
"PADDLE_PLACE_TYPE": "gpu",
"turn_on_trt": true,
"training_server": true,
"use_cache": false,
"num_labels": 44,
"thread_num": 2,
"inference_model_path": "./output/cls_ernie_3.0_finre_ch/save_inference_model/inference_step_1/",
"config_path": "../../models_hub/ernie_3.0_ch_dir/ernie_config.json",
"extra_param": {
"meta":{
"job_type": "relation_pred"
},
"max_seq_len": 512
}
}
}
开始预测
运行如下命令执行预测:
- ERNIE 3.0百亿模型预测:
# 下面为inference必须要导入的环境变量以及依赖的python
BASE_PATH="../../models_hub/ernie_3.0_ch_dir/infer_env/"
export CUDA_VISIBLE_DEVICES=0 # 屏蔽其它显卡
export PATH="${BASE_PATH}/py37/bin/:$PATH"
export PYTHONPATH="${BASE_PATH}/py37/"
# ERNIE 3.0百亿模型依赖TensorRT以fp16精度进行单卡预测,下面为所需的tensorRT库,以及对应的cuda和cuddn版本
export LD_LIBRARY_PATH=$BASE_PATH:${BASE_PATH}/cuda-11.0.3/lib64:${BASE_PATH}/cudnn-11.0-linux-x64-v8.0.5.39/lib64:${BASE_PATH}/TensorRT-7.2.1.6/lib:/home/opt/nvidia_lib:${BASE_PATH}/libs:$LD_LIBRARY_PATH
export FLAGS_allocator_strategy=auto_growth # for inference,没有这一行会报显存溢出的错误
mkdir -p log
fleetrun --log_dir log ./run_infer_ernie3.py.py --param_path "./examples/cls_ernie_3.0_finre_ch_infer.json" 1>log/lanch.log 2>&1
- ERNIE 3.0-1.5B模型预测:
python ./run_infer_ernie3.py --param_path "./examples/cls_ernie_1.5b_finre_ch_infer.json"
- 预测结果保存于./output/predict_result.txt中,如果训练过程中training_server保持开启,则会额外产生一个./output/predict_result_server.txt文件用于保存server的预测结果