军事畛域关系抽取:UIE Slim最新升级版含数据标注、serving部署、模型蒸馏等教学,助力工业利用场景疾速落地
本我的项目为UIE框架降级版本实体关系抽取,具体解说了数据标注,以及医疗畛域NER微调,同时实现基于SimpleServing的疾速服务化部署,并思考了在一些工业利用场景中对性能的要求较高,若不能无效压缩则无奈理论利用。因而,将UIE模型的常识迁徙到关闭域信息抽取小模型,同时应用FasterTokenizer进行文本预处理减速,整体提速7.6x倍。
我的项目成果预览:
- 小样本军事关系抽取数据集试验指标:
样本量 | Precision | Recall | F1 Score |
---|---|---|---|
0-shot | 0.64634 | 0.53535 | 0.58564 |
5-shot | 0.89474 | 0.85000 | 0.87179 |
10-shot | 0.92793 | 0.85833 | 0.89177 |
full-set | 0.92 | 0.92 | 0.92 |
- 性能比照
模型 | 推理耗时 | 晋升倍数 |
---|---|---|
UIE+faster | 30.83 | 1 |
uie+servering | 31.75 | 1- |
UIE Slim | 5.90 | 5.23 |
- 可视化展现
UIE(Universal Information Extraction):Yaojie Lu等人在ACL-2022中提出了通用信息抽取对立框架UIE。该框架实现了实体抽取、关系抽取、事件抽取、情感剖析等工作的对立建模,并使得不同工作间具备良好的迁徙和泛化能力。为了不便大家应用UIE的弱小能力,PaddleNLP借鉴该论文的办法,基于ERNIE 3.0常识加强预训练模型,训练并开源了首个中文通用信息抽取模型UIE。该模型能够反对不限定行业畛域和抽取指标的要害信息抽取,实现零样本疾速冷启动,并具备优良的小样本微调能力,疾速适配特定的抽取指标。
框架降级:预训练模型参数配置对立,自定义参数配置的保留和加载无需额定开发:
- Trainer API 新增 BF16 训练、Recompute 重计算、Sharding 等多项分布式能力,通过简略配置即可进行超大规模预训练模型训练;
- 模型压缩 API 反对量化训练、词表压缩等性能,压缩后的模型精度损失更小,模型部署的内存占用大大降低;
- 数据加强API 全面降级,反对字、词、句子三种粒度数据加强策略,可轻松定制数据加强策略
我的项目链接以及码源见文末
#应用最新版本paddlenlp!pip install -U paddlenlp
1. 基于Label Studio数据标注
1.1 Label Studio装置
以下标注示例用到的环境配置:
- Python 3.8+
- label-studio == 1.7.0
- paddleocr >= 2.6.0.1
在终端(terminal)应用pip装置label-studio:
pip install label-studio==1.7.0
装置实现后,运行以下命令行:
label-studio start
在浏览器关上http://localhost:8080/,输出用户名和明码登录,开始应用label-studio进行标注。
1.2 文本抽取标注教学
- 我的项目创立
点击创立(Create)开始创立一个新的我的项目,填写项目名称、形容,而后抉择Object Detection with Bounding Boxes
。
- 填写项目名称、形容
<div align="center">
<img src=https://user-images.githubusercontent.com/40840292/199661377-d9664165-61aa-4462-927d-225118b8535b.png height=230 width=1200 />
</div>
- 命名实体辨认、关系抽取、事件抽取、实体/评估维度分类工作抉择
`Relation Extraction
。
<div align="center">
<img src=https://user-images.githubusercontent.com/40840292/212617773-34534e68-4544-4b24-8f39-ae7f9573d397.png height=420 width=1200 />
</div>
- 增加标签(也可跳过后续在Setting/Labeling Interface中配置)
<div align="center">
<img src=https://user-images.githubusercontent.com/40840292/199662737-ed996a2c-7a24-4077-8a36-239c4bfb0a16.png height=380 width=1200 />
</div>
图中展现了实体类型标签的构建,其余类型标签的构建可参考
- 数据上传
先从本地上传txt格式文件,抉择List of tasks
,而后抉择导入本我的项目。
<div align="center">
<img src=https://user-images.githubusercontent.com/40840292/199667670-1b8f6755-b41f-41c4-8afc-06bb051690b6.png height=210 width=1200 />
</div>
- 标签构建
- Span类型标签
<div align="center">
<img src=https://user-images.githubusercontent.com/40840292/199667941-04e300c5-3cd7-4b8e-aaf5-561415414891.png height=480 width=1200 />
</div>
- Relation类型标签
<div align="center">
<img src=https://user-images.githubusercontent.com/40840292/199725229-f5e998bf-367c-4449-b83a-c799f1e3de00.png height=620 width=1200 />
</div>
Relation XML模板:
<Relations> <Relation value="歌手"/> <Relation value="发行工夫"/> <Relation value="所属专辑"/> </Relations>
- 工作标注
- 实体抽取
标注示例:
<div align="center">
<img src=https://user-images.githubusercontent.com/40840292/199879957-aeec9d17-d342-4ea0-a840-457b49f6066e.png height=140 width=1000 />
</div>
该标注示例对应的schema为:
schema = [ '工夫', '选手', '赛事名称', '得分']
- 关系抽取
<div align="center">
<img src=https://user-images.githubusercontent.com/40840292/199879866-03c1ecac-1828-4f35-af70-9ae61701c303.png height=230 width=1200 />
</div>
对于关系抽取,其P的类型设置非常重要,须要遵循以下准则
“{S}的{P}为{O}”须要可能形成语义正当的短语。比方对于三元组(S, 父子, O),关系类别为父子是没有问题的。但依照UIE以后关系类型prompt的结构形式,“S的父子为O”这个表白不是很通顺,因而P改成孩子更好,即“S的孩子为O”。正当的P类型设置,将显著晋升零样本成果。
该标注示例对应的schema为:
schema = { '作品名': [ '歌手', '发行工夫', '所属专辑' ]}
该标注示例对应的schema为:
schema = '情感偏向[正向,负向]'
- 数据导出
勾选已标注文本ID,抉择导出的文件类型为JSON
,导出数据:
<div align="center">
<img src=https://user-images.githubusercontent.com/40840292/199891344-023736e2-6f9d-454b-b72a-dec6689f8436.png height=180 width=1200 />
</div>
- 数据转换
将导出的文件重命名为label_studio.json
后,放入./data
目录下。通过label_studio.py脚本可转为UIE的数据格式。
- 抽取式工作
python label_studio.py \ --label_studio_file ./data/label_studio.json \ --save_dir ./data \ --splits 0.8 0.1 0.1 \ --task_type ext
- 更多配置
label_studio_file
: 从label studio导出的数据标注文件。save_dir
: 训练数据的保留目录,默认存储在data
目录下。negative_ratio
: 最大负例比例,该参数只对抽取类型工作无效,适当结构负例可晋升模型成果。负例数量和理论的标签数量无关,最大负例数量 = negative_ratio * 正例数量。该参数只对训练集无效,默认为5。为了保障评估指标的准确性,验证集和测试集默认结构全负例。splits
: 划分数据集时训练集、验证集所占的比例。默认为[0.8, 0.1, 0.1]示意依照8:1:1
的比例将数据划分为训练集、验证集和测试集。task_type
: 抉择工作类型,可选有抽取和分类两种类型的工作。options
: 指定分类工作的类别标签,该参数只对分类类型工作无效。默认为["正向", "负向"]。prompt_prefix
: 申明分类工作的prompt前缀信息,该参数只对分类类型工作无效。默认为"情感偏向"。is_shuffle
: 是否对数据集进行随机打散,默认为True。seed
: 随机种子,默认为1000.schema_lang
:抉择schema的语言,将会应该训练数据prompt的结构形式,可选有ch
和en
。默认为ch
。separator
: 实体类别/评估维度与分类标签的分隔符,该参数只对实体/评估维度分类工作无效。默认为"##"。
备注:
- 默认状况下 label_studio.py 脚本会依照比例将数据划分为 train/dev/test 数据集
- 每次执行 label_studio.py 脚本,将会笼罩已有的同名数据文件
- 在模型训练阶段咱们举荐结构一些负例以晋升模型成果,在数据转换阶段咱们内置了这一性能。可通过
negative_ratio
管制主动结构的负样本比例;负样本数量 = negative_ratio * 正样本数量。 - 对于从label_studio导出的文件,默认文件中的每条数据都是通过人工正确标注的。
- References
- Label Studio
2.基于军事畛域NER微调
2.1 加载数据数据标注
#加载数据集!wget https://bj.bcebos.com/paddlenlp/datasets/military.tar.gz!tar -xvf military.tar.gz!mv military data!rm military.tar.gz
--2023-05-30 14:54:45-- https://bj.bcebos.com/paddlenlp/datasets/military.tar.gz正在解析主机 bj.bcebos.com (bj.bcebos.com)... 182.61.200.229, 182.61.200.195, 2409:8c04:1001:1002:0:ff:b001:368a正在连接 bj.bcebos.com (bj.bcebos.com)|182.61.200.229|:443... 已连贯。已收回 HTTP 申请,正在期待回应... 200 OK长度: 378880 (370K) [application/x-gzip]正在保留至: “military.tar.gz”military.tar.gz 100%[===================>] 370.00K 2.01MB/s in 0.2s 2023-05-30 14:54:46 (2.01 MB/s) - 已保留 “military.tar.gz” [378880/378880])military/military/unlabeled_data.txtmilitary/label_studio.json
!python label_studio.py \ --label_studio_file ./data/military/label_studio.json \ --save_dir ./data \ --splits 0.8 0.2 0 \ --negative_ratio 3 \ --task_type ext
[32m[2023-05-29 17:11:33,160] [ INFO][0m - Converting annotation data...[0m100%|████████████████████████████████████████| 96/96 [00:00<00:00, 52190.95it/s][32m[2023-05-29 17:11:33,163] [ INFO][0m - Adding negative samples for first stage prompt...[0m100%|███████████████████████████████████████| 96/96 [00:00<00:00, 431106.19it/s][32m[2023-05-29 17:11:33,164] [ INFO][0m - Adding negative samples for second stage prompt...[0m100%|█████████████████████████████████████████| 96/96 [00:00<00:00, 5995.25it/s][32m[2023-05-29 17:11:33,180] [ INFO][0m - Converting annotation data...[0m100%|████████████████████████████████████████| 25/25 [00:00<00:00, 61717.25it/s][32m[2023-05-29 17:11:33,181] [ INFO][0m - Adding negative samples for first stage prompt...[0m100%|███████████████████████████████████████| 25/25 [00:00<00:00, 338250.32it/s][32m[2023-05-29 17:11:33,181] [ INFO][0m - Adding negative samples for second stage prompt...[0m100%|███████████████████████████████████████| 25/25 [00:00<00:00, 433295.87it/s][32m[2023-05-29 17:11:33,182] [ INFO][0m - Converting annotation data...[0m0it [00:00, ?it/s][32m[2023-05-29 17:11:33,182] [ INFO][0m - Adding negative samples for first stage prompt...[0m0it [00:00, ?it/s][32m[2023-05-29 17:11:33,190] [ INFO][0m - Save 1228 examples to ./data/train.txt.[0m[32m[2023-05-29 17:11:33,191] [ INFO][0m - Save 100 examples to ./data/dev.txt.[0m[32m[2023-05-29 17:11:33,191] [ INFO][0m - Save 0 examples to ./data/test.txt.[0m[32m[2023-05-29 17:11:33,191] [ INFO][0m - Finished! It takes 0.04 seconds[0m[0m
2.2 模型微调
举荐应用 Trainer API 对模型进行微调。只需输出模型、数据集等就能够应用 Trainer API 高效疾速地进行预训练、微调和模型压缩等工作,能够一键启动多卡训练、混合精度训练、梯度累积、断点重启、日志显示等性能,Trainer API 还针对训练过程的通用训练配置做了封装,比方:优化器、学习率调度等。
应用上面的命令,应用 uie-base 作为预训练模型进行模型微调,将微调后的模型保留至$finetuned_model:
单卡启动:
#单卡训练!python finetune.py \ --device gpu \ --logging_steps 10 \ --save_steps 100 \ --eval_steps 100 \ --seed 1000 \ --model_name_or_path uie-base \ --output_dir ./checkpoint/model_best \ --train_path data/train.txt \ --dev_path data/dev.txt \ --max_seq_len 512 \ --per_device_train_batch_size 32 \ --per_device_eval_batch_size 32 \ --num_train_epochs 20 \ --learning_rate 1e-5 \ --do_train \ --do_eval \ --do_export \ --export_model_dir ./checkpoint/model_best \ --overwrite_output_dir \ --disable_tqdm True \ --metric_for_best_model eval_f1 \ --load_best_model_at_end True \ --save_total_limit 1
局部后果展现:
[2023-05-29 17:31:53,018] [ INFO] - eval_loss: 0.0008850682061165571, eval_precision: 0.92, eval_recall: 0.92, eval_f1: 0.92, eval_runtime: 0.8828, eval_samples_per_second: 113.271, eval_steps_per_second: 4.531, epoch: 20.0[2023-05-29 17:31:53,018] [ INFO] - ***** eval metrics *****[2023-05-29 17:31:53,018] [ INFO] - epoch = 20.0[2023-05-29 17:31:53,019] [ INFO] - eval_f1 = 0.92[2023-05-29 17:31:53,019] [ INFO] - eval_loss = 0.0009[2023-05-29 17:31:53,019] [ INFO] - eval_precision = 0.92[2023-05-29 17:31:53,019] [ INFO] - eval_recall = 0.92[2023-05-29 17:31:53,019] [ INFO] - eval_runtime = 0:00:00.88[2023-05-29 17:31:53,019] [ INFO] - eval_samples_per_second = 113.271[2023-05-29 17:31:53,019] [ INFO] - eval_steps_per_second = 4.531[2023-05-29 17:31:53,020] [ INFO] - Exporting inference model to ./checkpoint/model_best/model[2023-05-29 17:31:59,117] [ INFO] - Inference model exported.
#多卡训练:GPU环境中应用,能够指定gpus参数进行多卡训练:# !python -u -m paddle.distributed.launch --gpus "0,1" finetune.py \# --device gpu \# --logging_steps 10 \# --save_steps 100 \# --eval_steps 100 \# --seed 1000 \# --model_name_or_path uie-base \# --output_dir ./checkpoint/model_best \# --train_path data/train.txt \# --dev_path data/dev.txt \# --max_seq_len 512 \# --per_device_train_batch_size 8 \# --per_device_eval_batch_size 8 \# --num_train_epochs 20 \# --learning_rate 1e-5 \# --do_train \# --do_eval \# --do_export \# --export_model_dir ./checkpoint/model_best \# --overwrite_output_dir \# --disable_tqdm True \# --metric_for_best_model eval_f1 \# --load_best_model_at_end True \# --save_total_limit 1
留神:如果模型是跨语言模型 UIE-M,还需设置 --multilingual
。
该示例代码中因为设置了参数 --do_eval
,因而在训练完会主动进行评估。
可配置参数阐明:
model_name_or_path
:必须,进行 few shot 训练应用的预训练模型。可抉择的有 "uie-base"、 "uie-medium", "uie-mini", "uie-micro", "uie-nano", "uie-m-base", "uie-m-large","uie-x-base"。multilingual
:是否是跨语言模型,用 "uie-m-base", "uie-m-large" 等模型进微调失去的模型也是多语言模型,须要设置为 True;默认为 False。device
: 训练设施,可抉择 'cpu'、'gpu'、'npu' 其中的一种;默认为 GPU 训练。logging_steps
: 训练过程中日志打印的距离 steps 数,默认10。save_steps
: 训练过程中保留模型 checkpoint 的距离 steps 数,默认100。eval_steps
: 训练过程中保留模型 checkpoint 的距离 steps 数,默认100。seed
:全局随机种子,默认为 42。output_dir
:必须,模型训练或压缩后保留的模型目录;默认为None
。train_path
:训练集门路;默认为None
。dev_path
:开发集门路;默认为None
。max_seq_len
:文本最大切分长度,输出超过最大长度时会对输出文本进行主动切分,默认为512。per_device_train_batch_size
:用于训练的每个 GPU 外围/CPU 的batch大小,默认为8。per_device_eval_batch_size
:用于评估的每个 GPU 外围/CPU 的batch大小,默认为8。num_train_epochs
: 训练轮次,应用早停法时能够抉择 100;默认为10。learning_rate
:训练最大学习率,UIE-X 举荐设置为 1e-5;默认值为3e-5。label_names
:训练数据标签label的名称,UIE-X 设置为'start_positions' 'end_positions';默认值为None。do_train
:是否进行微调训练,设置该参数示意进行微调训练,默认不设置。do_eval
:是否进行评估,设置该参数示意进行评估,默认不设置。do_export
:是否进行导出,设置该参数示意进行动态图导出,默认不设置。export_model_dir
:动态图导出地址,默认为None。overwrite_output_dir
: 如果True
,笼罩输入目录的内容。如果output_dir
指向检查点目录,则应用它持续训练。disable_tqdm
: 是否应用tqdm进度条。metric_for_best_model
:最优模型指标,UIE-X 举荐设置为eval_f1
,默认为None。load_best_model_at_end
:训练完结后是否加载最优模型,通常与metric_for_best_model
配合应用,默认为False。save_total_limit
:如果设置次参数,将限度checkpoint的总数。删除旧的checkpoints输入目录
,默认为None。
2.3 模型评估
评估形式阐明:采纳单阶段评估的形式,即关系抽取、事件抽取等须要分阶段预测的工作对每一阶段的预测后果进行别离评估。验证/测试集默认会利用同一层级的所有标签来结构出全副负例。
可开启debug模式对每个正例类别别离进行评估,该模式仅用于模型调试:
!python evaluate.py \ --model_path ./checkpoint/model_best \ --test_path ./data/dev.txt \ --batch_size 16 \ --device gpu \ --max_seq_len 512
#对 UIE-M 进行模型评估:# !python evaluate.py \# --model_path ./checkpoint/model_best \# --test_path ./data/dev.txt \# --batch_size 16 \# --max_seq_len 512 \# --multilingual
#debug!python evaluate.py \ --model_path ./checkpoint/model_best \ --test_path ./data/dev.txt \ --debug
局部后果展现:
[2023-05-29 17:32:09,124] [ INFO] - -----------------------------[2023-05-29 17:32:09,124] [ INFO] - Class Name: all_classes[2023-05-29 17:32:09,124] [ INFO] - Evaluation Precision: 0.92000 | Recall: 0.92000 | F1: 0.92000[2023-05-29 17:32:18,145] [ INFO] - Class Name: 武器名称[2023-05-29 17:32:18,145] [ INFO] - Evaluation Precision: 0.96000 | Recall: 0.96000 | F1: 0.96000[2023-05-29 17:32:18,961] [ INFO] - -----------------------------[2023-05-29 17:32:18,961] [ INFO] - Class Name: X的产国[2023-05-29 17:32:18,961] [ INFO] - Evaluation Precision: 1.00000 | Recall: 1.00000 | F1: 1.00000[2023-05-29 17:32:19,762] [ INFO] - -----------------------------[2023-05-29 17:32:19,762] [ INFO] - Class Name: X的研发单位[2023-05-29 17:32:19,762] [ INFO] - Evaluation Precision: 0.81481 | Recall: 0.81481 | F1: 0.81481[2023-05-29 17:32:20,554] [ INFO] - -----------------------------[2023-05-29 17:32:20,554] [ INFO] - Class Name: X的类型[2023-05-29 17:32:20,554] [ INFO] - Evaluation Precision: 1.00000 | Recall: 1.00000 | F1: 1.00000
可配置参数阐明:
device
: 评估设施,可抉择 'cpu'、'gpu'、'npu' 其中的一种;默认为 GPU 评估。model_path
: 进行评估的模型文件夹门路,门路下需蕴含模型权重文件model_state.pdparams
及配置文件model_config.json
。test_path
: 进行评估的测试集文件。batch_size
: 批处理大小,请联合机器状况进行调整,默认为16。max_seq_len
: 文本最大切分长度,输出超过最大长度时会对输出文本进行主动切分,默认为512。debug
: 是否开启debug模式对每个正例类别别离进行评估,该模式仅用于模型调试,默认敞开。multilingual
: 是否是跨语言模型,默认敞开。schema_lang
: 抉择schema的语言,可选有ch
和en
。默认为ch
,英文数据集请抉择en
。
2.4 模型预测
paddlenlp.Taskflow装载定制模型,通过task_path指定模型权重文件的门路,门路下须要蕴含训练好的模型权重文件model_state.pdparams。
相干bug:KeyError: 'sentencepiece_model_file'
同一个脚本先加载uie-x,再加载uie,报错KeyError: 'sentencepiece_model_file':https://github.com/PaddlePaddle/PaddleNLP/issues/5795
加载过uiem之后不能加载uie模型:https://github.com/PaddlePaddle/PaddleNLP/issues/5615
- 修复加载最新版本paddlenlp重启内核即可
- 重启我的项目,先加载uie,再加在uie-x则不出错
# !pip install --pre --upgrade paddlenlp -f https://www.paddlepaddle.org.cn/whl/paddlenlp.html
from pprint import pprintfrom paddlenlp import Taskflowschema = {"武器名称": ["产国", "类型", "研发单位"]}my_ie = Taskflow("information_extraction", schema=schema, task_path='./checkpoint/model_best')pprint(my_ie("格鲁曼FF/SF战斗机,是美国海军配备的第一种能够收放起落架的舰载战斗机,也是格鲁曼战斗机同美国海军结缘70年的开始。"))
[2023-05-29 17:41:37,740] [ INFO] - loading configuration file ./checkpoint/model_best/config.json[2023-05-29 17:41:37,744] [ INFO] - Model config ErnieConfig { "architectures": [ "UIE" ], "attention_probs_dropout_prob": 0.1, "dtype": "float32", "enable_recompute": false, "fuse": false, "hidden_act": "gelu", "hidden_dropout_prob": 0.1, "hidden_size": 768, "initializer_range": 0.02, "intermediate_size": 3072, "layer_norm_eps": 1e-12, "max_position_embeddings": 2048, "model_type": "ernie", "num_attention_heads": 12, "num_hidden_layers": 12, "pad_token_id": 0, "paddlenlp_version": null, "pool_act": "tanh", "task_id": 0, "task_type_vocab_size": 3, "type_vocab_size": 4, "use_task_id": true, "vocab_size": 40000}[2023-05-29 17:41:39,192] [ INFO] - All model checkpoint weights were used when initializing UIE.[2023-05-29 17:41:39,194] [ INFO] - All the weights of UIE were initialized from the model checkpoint at ./checkpoint/model_best.If your task is similar to the task the model of the checkpoint was trained on, you can already use UIE for predictions without further training.[2023-05-29 17:41:39,196] [ INFO] - Converting to the inference model cost a little time.[2023-05-29 17:41:46,626] [ INFO] - The inference model save in the path:./checkpoint/model_best/static/inference[2023-05-29 17:41:48,510] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load './checkpoint/model_best'.[{'武器名称': [{'end': 11, 'probability': 0.9973600367608348, 'relations': {'产国': [{'end': 15, 'probability': 0.9998343059352948, 'start': 13, 'text': '美国'}], '类型': [{'end': 11, 'probability': 0.9998778133542885, 'start': 8, 'text': '战斗机'}]}, 'start': 0, 'text': '格鲁曼FF/SF战斗机'}]}]
2.5 模型疾速服务化部署
在 UIE的服务化能力中提供基于PaddleNLP SimpleServing 来搭建服务化能力,通过几行代码即可搭建服务化部署能力。
- 环境筹备
应用有SimpleServing性能的PaddleNLP版本(或者最新的develop版本)
pip install paddlenlp >= 2.5.0
- Server服务启动
进入文件以后所在门路
paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8190
- Client申请启动
python client.py
服务化自定义参数
- Server 自定义参数
- schema替换
#Default schemaschema = {"武器名称": ["产国", "类型", "研发单位"]}
* 设置模型门路
#Default task_pathuie = Taskflow('information_extraction', task_path='./checkpoint/model_best/', schema=schema)
* 多卡服务化预测
PaddleNLP SimpleServing 反对多卡负载平衡预测,次要在服务化注册的时候,注册两个Taskflow的task即可,上面是示例代码
uie1 = Taskflow('information_extraction', task_path='../../../checkpoint/model_best/', schema=schema, device_id=0)uie2 = Taskflow('information_extraction', task_path='../../../checkpoint/model_best/', schema=schema, device_id=1)service.register_taskflow('uie', [uie1, uie2])
- 更多配置
from paddlenlp import Taskflowschema = uie = Taskflow("zero_shot_text_classification", schema=schema, model="uie-base", max_seq_len=512, batch_size=1, pred_threshold=0.5, precision="fp32")
schema
:定义工作标签候选汇合。model
:抉择工作应用的模型,默认为utc-base
, 可选有utc-xbase
,utc-base
,utc-medium
,utc-micro
,utc-mini
,utc-nano
,utc-pico
。max_seq_len
:最长输出长度,包含所有标签的长度,默认为512。batch_size
:批处理大小,请联合机器状况进行调整,默认为1。pred_threshold
:模型对标签预测的概率在0~1之间,返回后果去掉小于这个阈值的后果,默认为0.5。precision
:抉择模型精度,默认为fp32
,可选有fp16
和fp32
。fp16
推理速度更快。如果抉择fp16
,请先确保机器正确装置NVIDIA相关驱动和根底软件,确保CUDA>=11.2,cuDNN>=8.1.1,首次应用需依照提醒装置相干依赖。其次,须要确保GPU设施的CUDA计算能力(CUDA Compute Capability)大于7.0,典型的设施包含V100、T4、A10、A100、GTX 20系列和30系列显卡等。更多对于CUDA Compute Capability和精度反对状况请参考NVIDIA文档:GPU硬件与反对精度对照表。- Client 自定义参数
#Changed to input texts you wantedtexts = ['格鲁曼FF/SF战斗机,是美国海军配备的第一种能够收放起落架的舰载战斗机,也是格鲁曼战斗机同美国海军结缘70年的开始。']
# %cd /home/aistudio/deploy# !paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8190#Error loading ASGI app. Could not import module "server".#去终端执行即可
# %cd /home/aistudio/deploy# !python client.py
在notebook如果不行,能够间接进入终端进行调试,须要留神的是要在同一个门路下不然会报错:
3.UIE Slim 数据蒸馏
在UIE弱小的抽取能力背地,同样须要较大的算力反对计算。在一些工业利用场景中对性能的要求较高,若不能无效压缩则无奈理论利用。因而,咱们基于数据蒸馏技术构建了UIE Slim数据蒸馏零碎。其原理是通过数据作为桥梁,将UIE模型的常识迁徙到关闭域信息抽取小模型,以达到精度损失较小的状况下却能达到大幅度预测速度晋升的成果。
- Step 1: 应用UIE模型对标注数据进行finetune,失去Teacher Model。
- Step 2: 用户提供大规模无标注数据,需与标注数据同源。应用Taskflow UIE对无监督数据进行预测。
- Step 3: 应用标注数据以及步骤2失去的合成数据训练出关闭域Student Model。
- 数据集介绍
3.1 离线蒸馏
- 通过训练好的UIE定制模型预测无监督数据的标签
可配置参数阐明:
data_path
: 标注数据(doccano_ext.json
)及无监督文本(unlabeled_data.txt
)门路。model_path
: 训练好的UIE定制模型门路。save_dir
: 学生模型训练数据保留门路。synthetic_ratio
: 管制合成数据的比例。最大合成数据数量=synthetic_ratio*标注数据数量。task_type
: 抉择工作类型,可选有entity_extraction
,relation_extraction
,event_extraction
和opinion_extraction
。因为是关闭域信息抽取,需指定工作类型。seed
: 随机种子,默认为1000。
NOTE:schema须要依据标注数据在data_distill.py中进行配置,且schema须要蕴含标注数据中的所有标签类型。
!cp /home/aistudio/data/sample_index.json /home/aistudio/data/military
%cd data_distill!python data_distill.py \ --data_path /home/aistudio/data/military \ --save_dir student_data \ --task_type relation_extraction \ --synthetic_ratio 10 \ --model_path /home/aistudio/checkpoint/model_best #曾经训练好的模型
[Errno 2] No such file or directory: 'data_distill'/home/aistudio/data_distill[2023-05-29 17:53:52,694] [ INFO] - loading configuration file /home/aistudio/checkpoint/model_best/config.json[2023-05-29 17:53:52,696] [ INFO] - Model config ErnieConfig { "architectures": [ "UIE" ], "attention_probs_dropout_prob": 0.1, "dtype": "float32", "enable_recompute": false, "fuse": false, "hidden_act": "gelu", "hidden_dropout_prob": 0.1, "hidden_size": 768, "initializer_range": 0.02, "intermediate_size": 3072, "layer_norm_eps": 1e-12, "max_position_embeddings": 2048, "model_type": "ernie", "num_attention_heads": 12, "num_hidden_layers": 12, "pad_token_id": 0, "paddlenlp_version": null, "pool_act": "tanh", "task_id": 0, "task_type_vocab_size": 3, "type_vocab_size": 4, "use_task_id": true, "vocab_size": 40000}W0529 17:53:53.227413 11701 gpu_resources.cc:61] Please NOTE: device: 0, GPU Compute Capability: 8.0, Driver API Version: 11.2, Runtime API Version: 11.2W0529 17:53:53.231253 11701 gpu_resources.cc:91] device: 0, cuDNN Version: 8.2.[2023-05-29 17:53:54,118] [ INFO] - All model checkpoint weights were used when initializing UIE.[2023-05-29 17:53:54,118] [ INFO] - All the weights of UIE were initialized from the model checkpoint at /home/aistudio/checkpoint/model_best.If your task is similar to the task the model of the checkpoint was trained on, you can already use UIE for predictions without further training.[2023-05-29 17:53:54,119] [ INFO] - Converting to the inference model cost a little time.[2023-05-29 17:54:00,548] [ INFO] - The inference model save in the path:/home/aistudio/checkpoint/model_best/static/inference[2023-05-29 17:54:02,567] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load '/home/aistudio/checkpoint/model_best'.[2023-05-29 17:54:26,764] [ INFO] - Save 627 examples to student_data/train_data.json.[2023-05-29 17:54:26,765] [ INFO] - Save 25 examples to student_data/dev_data.json.[2023-05-29 17:54:26,765] [ INFO] - Save 0 examples to student_data/test_data.json.
3.2 老师模型评估
UIE微调阶段针对UIE训练格局数据评估模型成果(该评估形式非端到端评估,不适宜关系、事件等工作),可通过以下评估脚本针对原始标注格局数据评估模型成果
可配置参数阐明:
model_path
: 训练好的UIE定制模型门路。test_path
: 测试数据集门路。label_maps_path
: 学生模型标签字典。batch_size
: 批处理大小,默认为8。max_seq_len
: 最大文本长度,默认为256。task_type
: 抉择工作类型,可选有entity_extraction
,relation_extraction
,event_extraction
和opinion_extraction
。因为是关闭域信息抽取的评估,需指定工作类型。
!python evaluate_teacher.py \ --task_type relation_extraction \ --test_path ./student_data/dev_data.json \ --label_maps_path ./student_data/label_maps.json \ --model_path /home/aistudio/checkpoint/model_best
[2023-05-29 17:54:36,866] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load '/home/aistudio/checkpoint/model_best'.[2023-05-29 17:54:36,888] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load 'ernie-3.0-base-zh'.[2023-05-29 17:54:36,888] [ INFO] - Downloading https://bj.bcebos.com/paddlenlp/models/transformers/ernie_3.0/ernie_3.0_base_zh_vocab.txt and saved to /home/aistudio/.paddlenlp/models/ernie-3.0-base-zh[2023-05-29 17:54:37,036] [ INFO] - Downloading ernie_3.0_base_zh_vocab.txt from https://bj.bcebos.com/paddlenlp/models/transformers/ernie_3.0/ernie_3.0_base_zh_vocab.txt100%|█████████████████████████████████████████| 182k/182k [00:00<00:00, 401kB/s][2023-05-29 17:54:37,623] [ INFO] - tokenizer config file saved in /home/aistudio/.paddlenlp/models/ernie-3.0-base-zh/tokenizer_config.json[2023-05-29 17:54:37,623] [ INFO] - Special tokens file saved in /home/aistudio/.paddlenlp/models/ernie-3.0-base-zh/special_tokens_map.json[2023-05-29 17:54:40,622] [ INFO] - Evaluation precision: {'entity_f1': 0.92, 'entity_precision': 0.92, 'entity_recall': 0.92, 'relation_f1': 0.86667, 'relation_precision': 0.86667, 'relation_recall': 0.86667}
3.3 学生模型训练
可配置参数阐明:
train_path
: 训练集文件门路。dev_path
: 验证集文件门路。batch_size
: 批处理大小,默认为16。learning_rate
: 学习率,默认为3e-5。save_dir
: 模型存储门路,默认为./checkpoint
。max_seq_len
: 最大文本长度,默认为256。weight_decay
: 示意AdamW优化器中应用的 weight_decay 的系数。warmup_proportion
: 学习率warmup策略的比例,如果0.1,则学习率会在前10%训练step的过程中从0缓缓增长到learning_rate, 而后再迟缓衰减,默认为0.0。num_epochs
: 训练轮数,默认为100。seed
: 随机种子,默认为1000。encoder
: 抉择学生模型的模型底座,默认为ernie-3.0-mini-zh
。task_type
: 抉择工作类型,可选有entity_extraction
,relation_extraction
,event_extraction
和opinion_extraction
。因为是关闭域信息抽取,需指定工作类型。logging_steps
: 日志打印的距离steps数,默认10。valid_steps
: evaluate的距离steps数,默认200。device
: 选用什么设施进行训练,可选cpu或gpu。init_from_ckpt
: 可选,模型参数门路,热启动模型训练;默认为None。
!python train.py \ --task_type relation_extraction \ --train_path student_data/train_data.json \ --dev_path student_data/dev_data.json \ --label_maps_path student_data/label_maps.json \ --num_epochs 200 \ --encoder ernie-3.0-mini-zh\ --device "gpu"\ --eval_steps 100\ --logging_steps 50\ --save_dir './checkpoint-mini'\ --batch_size 32
3.4 学生模型评估
!python evaluate.py \ --model_path /home/aistudio/data_distill/checkpoint-mini/model_best \ --test_path student_data/dev_data.json \ --task_type relation_extraction \ --label_maps_path student_data/label_maps.json \ --encoder ernie-3.0-mini-zh
[2023-05-29 18:28:24,274] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load 'ernie-3.0-mini-zh'.[2023-05-29 18:28:24,274] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/ernie-3.0-mini-zh/ernie_3.0_mini_zh_vocab.txt[2023-05-29 18:28:24,297] [ INFO] - tokenizer config file saved in /home/aistudio/.paddlenlp/models/ernie-3.0-mini-zh/tokenizer_config.json[2023-05-29 18:28:24,297] [ INFO] - Special tokens file saved in /home/aistudio/.paddlenlp/models/ernie-3.0-mini-zh/special_tokens_map.json[2023-05-29 18:28:24,298] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.modeling.ErnieModel'> to load 'ernie-3.0-mini-zh'.[2023-05-29 18:28:24,299] [ INFO] - Model config ErnieConfig { "attention_probs_dropout_prob": 0.1, "enable_recompute": false, "fuse": false, "hidden_act": "gelu", "hidden_dropout_prob": 0.1, "hidden_size": 384, "initializer_range": 0.02, "intermediate_size": 1536, "layer_norm_eps": 1e-12, "max_position_embeddings": 2048, "model_type": "ernie", "num_attention_heads": 12, "num_hidden_layers": 6, "pad_token_id": 0, "paddlenlp_version": null, "pool_act": "tanh", "task_id": 0, "task_type_vocab_size": 16, "type_vocab_size": 4, "use_task_id": true, "vocab_size": 40000}W0529 18:28:25.889279 23259 gpu_resources.cc:61] Please NOTE: device: 0, GPU Compute Capability: 8.0, Driver API Version: 11.2, Runtime API Version: 11.2W0529 18:28:25.891964 23259 gpu_resources.cc:91] device: 0, cuDNN Version: 8.2.[2023-05-29 18:28:26,071] [ WARNING] - Some weights of the model checkpoint at ernie-3.0-mini-zh were not used when initializing ErnieModel: ['ernie.encoder.layers.6.norm2.bias', 'ernie.encoder.layers.6.linear2.weight', 'ernie.encoder.layers.6.self_attn.out_proj.bias', 'ernie.encoder.layers.6.norm1.weight', 'ernie.encoder.layers.6.self_attn.out_proj.weight', 'ernie.encoder.layers.6.self_attn.q_proj.bias', 'ernie.encoder.layers.6.self_attn.v_proj.weight', 'ernie.encoder.layers.6.self_attn.k_proj.bias', 'ernie.encoder.layers.6.linear2.bias', 'ernie.encoder.layers.6.linear1.bias', 'ernie.encoder.layers.6.self_attn.v_proj.bias', 'ernie.encoder.layers.6.norm2.weight', 'ernie.encoder.layers.6.self_attn.k_proj.weight', 'ernie.encoder.layers.6.self_attn.q_proj.weight', 'ernie.encoder.layers.6.norm1.bias', 'ernie.encoder.layers.6.linear1.weight']- This IS expected if you are initializing ErnieModel from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).- This IS NOT expected if you are initializing ErnieModel from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).[2023-05-29 18:28:26,072] [ WARNING] - Some weights of ErnieModel were not initialized from the model checkpoint at ernie-3.0-mini-zh and are newly initialized: ['ernie.pooler.dense.bias', 'ernie.pooler.dense.weight']You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.[2023-05-29 18:28:28,078] [ INFO] - Evaluation precision: {'entity_f1': 0.90155, 'entity_precision': 0.93548, 'entity_recall': 0.87, 'relation_f1': 0.82517, 'relation_precision': 0.86765, 'relation_recall': 0.78667}
- Evaluation precision: {'entity_f1': 0.90155, 'entity_precision': 0.93548, 'entity_recall': 0.87, 'relation_f1': 0.82517, 'relation_precision': 0.86765, 'relation_recall': 0.78667}
3.5 Taskflow部署学生模型
- 通过Taskflow一键部署关闭域信息抽取模型,
task_path
为学生模型门路。
from pprint import pprintfrom paddlenlp import Taskflowie = Taskflow("information_extraction",model="uie-data-distill-gp", task_path="/home/aistudio/data_distill/checkpoint-mini/model_best") # Schema is fixed in closed-domain information extractionpprint(ie("格鲁曼FF/SF战斗机,是美国海军配备的第一种能够收放起落架的舰载战斗机,也是格鲁曼战斗机同美国海军结缘70年的开始。"))
[2023-05-29 20:55:17,301] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load '/home/aistudio/data_distill/checkpoint-mini/model_best'.[{'武器名称': [{'end': 11, 'probability': 0.99916863, 'relations': {'产国': [{'end': 15, 'probability': 0.99942076, 'relations': {}, 'start': 13, 'text': '美国'}], '类型': [{'end': 11, 'probability': 0.9989723, 'relations': {}, 'start': 8, 'text': '战斗机'}]}, 'start': 0, 'text': '格鲁曼FF/SF战斗机'}]}]
3.6 服务化疾速部署
#终端运行# %cd /home/aistudio/data_distill/distill_deploy#!paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8189#!python client.py
4.性能晋升测评(重点)
比照原模型、SimpleServing、以及蒸馏后的模型推理速度
4.1 UIE-base+FasterTokenizer
from pprint import pprintimport jsonfrom paddlenlp import Taskflowimport pandas as pd#运行工夫import timedef openreadtxt(file_name): data = [] file = open(file_name,'r',encoding='UTF-8') #关上文件 file_data = file.readlines() #读取所有行 for row in file_data: data.append(row) #将每行数据插入data中 return data# 工夫1old_time = time.time()data_input=openreadtxt('/home/aistudio/data/military/unlabeled_data.txt')schema = {"武器名称": ["产国", "类型", "研发单位"]}few_ie = Taskflow('information_extraction', schema=schema,use_faster=True,batch_size=32,task_path='/home/aistudio/checkpoint/model_best',)# 工夫1current_time = time.time()print("数据模型载入运行工夫为" + str(current_time - old_time) + "s")#工夫2old_time1 = time.time()results=few_ie(data_input)current_time1 = time.time()print("模型计算运行工夫为" + str(current_time1 - old_time1) + "s")#工夫2#工夫三old_time3 = time.time()test = pd.DataFrame(data=results)test.to_csv('/home/aistudio/output/reslut.txt', sep='\t', index=False,header=False) #本地current_time3 = time.time()print("数据导出运行工夫为" + str(current_time3 - old_time3) + "s")print("数据后果已导出")
[2023-05-29 20:57:04,668] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load '/home/aistudio/checkpoint/model_best'.数据模型载入运行工夫为3.4314684867858887s模型计算运行工夫为30.832460403442383s数据导出运行工夫为0.012335062026977539s数据后果已导出
4.2 UIE-base+Servering推理
#%cd /home/aistudio/deploy#!paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8191#!python client-test.py
4.3 UIE-base Slim
#数据蒸馏模型from pprint import pprintimport jsonfrom paddlenlp.taskflow import Taskflowimport pandas as pd#运行工夫import timedef openreadtxt(file_name): data = [] file = open(file_name,'r',encoding='UTF-8') #关上文件 file_data = file.readlines() #读取所有行 for row in file_data: data.append(row) #将每行数据插入data中 return data# 工夫1old_time = time.time()data_input=openreadtxt('/home/aistudio/data/military/unlabeled_data.txt')few_ie = Taskflow("information_extraction", model="uie-data-distill-gp", task_path="/home/aistudio/data_distill/checkpoint-mini/model_best",batch_size=32) # Schema 在闭域信息抽取中是固定的# 工夫1current_time = time.time()print("数据模型载入运行工夫为" + str(current_time - old_time) + "s")#工夫2old_time1 = time.time()results=few_ie(data_input)current_time1 = time.time()print("模型计算运行工夫为" + str(current_time1 - old_time1) + "s")#工夫2#工夫三old_time3 = time.time()test = pd.DataFrame(data=results)test.to_csv('/home/aistudio/output/reslut.txt', sep='\t', index=False,header=False) #本地# with open("/home/aistudio/output/reslut.txt", "w+",encoding='UTF-8') as f: #a : 写入文件,若文件不存在则会先创立再写入,但不会笼罩原文件,而是追加在文件开端# for result in results:# line = json.dumps(result, ensure_ascii=False) #对中文默认应用的ascii编码.想输入真正的中文须要指定ensure_ascii=False# f.write(line + "\n")current_time3 = time.time()print("数据导出运行工夫为" + str(current_time3 - old_time3) + "s")print("数据后果已导出")
[2023-05-29 20:57:35,608] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load '/home/aistudio/data_distill/checkpoint-mini/model_best'.数据模型载入运行工夫为1.6323919296264648s模型计算运行工夫为5.898466348648071s数据导出运行工夫为0.011991262435913086s数据后果已导出
# cd /home/aistudio/data_distill/distill_deploy#!paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8193#!python client-test.py
5.可视化显示
代码见我的项目中gradio文件
6.总结
6.1 计划比照总结
- 小样本军事关系抽取数据集试验指标:
样本量 | Precision | Recall | F1 Score |
---|---|---|---|
0-shot | 0.64634 | 0.53535 | 0.58564 |
5-shot | 0.89474 | 0.85000 | 0.87179 |
10-shot | 0.92793 | 0.85833 | 0.89177 |
full-set | 0.92 | 0.92 | 0.92 |
- 性能比照
模型 | 推理耗时 | 晋升倍数 |
---|---|---|
UIE+faster | 30.83 | 1 |
uie+servering | 31.75 | 1- |
UIE Slim | 5.90 | 5.23 |
本我的项目为UIE框架降级版本关系抽取,具体解说了数据标注,以及军事畛域RE微调,同时实现基于SimpleServing的疾速服务化部署,并思考了在一些工业利用场景中对性能的要求较高,若不能无效压缩则无奈理论利用。因而,将UIE模型的常识迁徙到关闭域信息抽取小模型,同时应用FasterTokenizer进行文本预处理减速,整体提速7.6x倍。
6.2 更多优质我的项目举荐
NLP专栏简介:数据加强、智能标注、用意辨认算法|多分类算法、文本信息抽取、多模态信息抽取、可解释性剖析、性能调优、模型压缩算法等:
- [小样本文本分类利用:基于UTC的医疗用意多分类,训练调优部署一条龙]
- [“中国法研杯”司法人工智能挑战赛:基于UTC的多标签/档次分类小样本文本利用]
- [Paddlenlp之UIE模型实战实体抽取工作【打车数据、快递单】]
- [Paddlenlp之UIE关系抽取模型【高管关系抽取为例】]
- [UIE Slim满足工业利用场景,解决推理部署耗时问题,晋升效力!]
- [基于Labelstudio的UIE半监督智能标注计划(本地版),赶快用起来啦!]
- [基于Labelstudio的UIE半监督深度学习的智能标注计划(云端版),提效!]
- [基于ERNIELayout&PDFplumber-UIEX多计划学术论文信息抽取]
- [基线晋升至96.45%:2022 司法杯犯罪事实实体辨认+数据蒸馏+被动学习]
- [[信息抽取]基于ERNIE3.0的多对多信息抽取算法:属性关系抽取]
我的项目链接以及码源
码源链接在文章末跳转订阅可见
- 参考链接
- GlobalPointer
- GPLinker
- JunnYu/GPLinker_pytorch
- CBLUE