医疗领域实体抽取:UIE Slim最新升级版含数据标注、serving部署、模型蒸馏等教学,助力工业应用场景快速落地

举报
汀丶 发表于 2023/05/30 13:36:11 2023/05/30
【摘要】 医疗领域实体抽取:UIE Slim最新升级版含数据标注、serving部署、模型蒸馏等教学,助力工业应用场景快速落地

医疗领域实体抽取:UIE Slim最新升级版含数据标注、serving部署、模型蒸馏等教学,助力工业应用场景快速落地

本项目为UIE框架升级版本实体关系抽取,详细讲解了数据标注,以及医疗领域NER微调,同时完成基于SimpleServing的快速服务化部署,并考虑了在一些工业应用场景中对性能的要求较高,若不能有效压缩则无法实际应用。因此,将UIE模型的知识迁移到封闭域信息抽取小模型,同时使用FasterTokenizer进行文本预处理加速,整体提速7.6x倍。

  • 框架升级:预训练模型参数配置统一,自定义参数配置的保存和加载无需额外开发:
    • Trainer API 新增 BF16 训练、Recompute 重计算、Sharding 等多项分布式能力,通过简单配置即可进行超大规模预训练模型训练;
    • 模型压缩 API 支持量化训练、词表压缩等功能,压缩后的模型精度损失更小,模型部署的内存占用大大降低;
    • 数据增强API 全面升级,支持字、词、句子三种粒度数据增强策略,可轻松定制数据增强策略

相关链接以及码源见文末

1.通用信息抽取案例展示

paddlenlp.Taskflow提供通用信息抽取、评价观点抽取等能力,可抽取多种类型的信息,包括但不限于命名实体识别(如人名、地名、机构名等)、关系(如电影的导演、歌曲的发行时间等)、事件(如某路口发生车祸、某地发生地震等)、以及评价维度、观点词、情感倾向等信息。用户可以使用自然语言自定义抽取目标,无需训练即可统一抽取输入文本中的对应信息。

1.1 实体抽取

命名实体识别(Named Entity Recognition,简称NER),是指识别文本中具有特定意义的实体。在开放域信息抽取中,抽取的类别没有限制,用户可以自己定义。

#使用最新版本paddlenlp
!pip install -U paddlenlp
#中文案例
from pprint import pprint
from paddlenlp import Taskflow

schema = ['肿瘤的大小', '肿瘤的个数', '肝癌级别', '脉管内癌栓分级']
ie = Taskflow('information_extraction', schema=schema)
pprint(ie("(右肝肿瘤)肝细胞性肝癌(II-III级,梁索型和假腺管型),肿瘤包膜不完整,紧邻肝被膜,侵及周围肝组织,未见脉管内癌栓(MVI分级:M0级)及卫星子灶形成。(肿物1个,大小4.2×4.0×2.8cm)。"))

[2023-05-26 16:55:28,241] [    INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load '/home/aistudio/.paddlenlp/taskflow/information_extraction/uie-base'.


[{'肝癌级别': [{'end': 20,
            'probability': 0.9246461700957553,
            'start': 13,
            'text': 'II-III级'}],
  '肿瘤的个数': [{'end': 84,
             'probability': 0.7917904385206498,
             'start': 82,
             'text': '1个'}],
  '肿瘤的大小': [{'end': 100,
             'probability': 0.8300156430113255,
             'start': 87,
             'text': '4.2×4.0×2.8cm'}],
  '脉管内癌栓分级': [{'end': 70,
               'probability': 0.9117306589152285,
               'start': 67,
               'text': 'M0级'}]}]

1.2 关系抽取

关系抽取(Relation Extraction,简称RE),是指从文本中识别实体并抽取实体之间的语义关系,进而获取三元组信息,即<主体,谓语,客体

from pprint import pprint
from paddlenlp import Taskflow
schema = {'竞赛名称': ['主办方', '承办方', '已举办次数']} 
ie = Taskflow('information_extraction', schema=schema)
pprint(ie('2022语言与智能技术竞赛由中国中文信息学会和中国计算机学会联合主办,百度公司、中国中文信息学会评测工作委员会和中国计算机学会自然语言处理专委会承办,已连续举办4届,成为全球最热门的中文NLP赛事之一。'))

1.3 混合任务抽取

例如在法律场景同时对文本进行实体抽取和关系抽取,schema可按照如下方式进行构造:

schema = ['法院', {'原告': '委托代理人'}, {'被告': '委托代理人'}]
ie.set_schema(schema)
pprint(ie("北京市海淀区人民法院\n民事判决书\n(199x)建初字第xxx号\n原告:张三。\n委托代理人李四,北京市 A律师事务所律师。\n被告:B公司,法定代表人王五,开发公司总经理。\n委托代理人赵六,北京市 C律师事务所律师。")) # Better print results using pprint
[{'原告': [{'end': 37,
          'probability': 0.9949732561990032,
          'relations': {'委托代理人': [{'end': 46,
                                   'probability': 0.7957008469207665,
                                   'start': 44,
                                   'text': '李四'}]},
          'start': 35,
          'text': '张三'}],
  '法院': [{'end': 10,
          'probability': 0.922022839827882,
          'start': 0,
          'text': '北京市海淀区人民法院'}],
  '被告': [{'end': 67,
          'probability': 0.8437379661680566,
          'relations': {'委托代理人': [{'end': 92,
                                   'probability': 0.7265425929861387,
                                   'start': 90,
                                   'text': '赵六'}]},
          'start': 64,
          'text': 'B公司'}]}]

1.4 更多模型配置选择

模型 结构 语言
uie-base (默认) 12-layers, 768-hidden, 12-heads 中文
uie-base-en 12-layers, 768-hidden, 12-heads 英文
uie-medical-base 12-layers, 768-hidden, 12-heads 中文
uie-medium 6-layers, 768-hidden, 12-heads 中文
uie-mini 6-layers, 384-hidden, 12-heads 中文
uie-micro 4-layers, 384-hidden, 12-heads 中文
uie-nano 4-layers, 312-hidden, 12-heads 中文
uie-m-large 24-layers, 1024-hidden, 16-heads 中、英文
uie-m-base 12-layers, 768-hidden, 12-heads 中、英文
from paddlenlp import Taskflow
ie = Taskflow('information_extraction',
                  schema="",
                  schema_lang="zh",
                  batch_size=1,
                  model='uie-base',
                  position_prob=0.5,
                  precision='fp32',
                  use_fast=False)
# #中英文混合抽取
# from pprint import pprint
# from paddlenlp import Taskflow

# schema = ['Time', 'Player', 'Competition', 'Score']
# ie = Taskflow('information_extraction', schema=schema, model="uie-m-base", schema_lang="en")
# pprint(ie(["2月8日上午北京冬奥会自由式滑雪女子大跳台决赛中中国选手谷爱凌以188.25分获得金牌!", "Rafael Nadal wins French Open Final!"]))
[2023-05-26 17:05:25,736] [    INFO] - We are using <class 'paddlenlp.transformers.ernie_m.tokenizer.ErnieMTokenizer'> to load '/home/aistudio/.paddlenlp/taskflow/information_extraction/uie-m-base'.


[{'Competition': [{'end': 23,
                   'probability': 0.9372359354800146,
                   'start': 6,
                   'text': '北京冬奥会自由式滑雪女子大跳台决赛'}],
  'Player': [{'end': 31,
              'probability': 0.6994761471998885,
              'start': 28,
              'text': '谷爱凌'}],
  'Score': [{'end': 39,
             'probability': 0.9887921351112396,
             'start': 32,
             'text': '188.25分'}],
  'Time': [{'end': 6,
            'probability': 0.9783122597547802,
            'start': 0,
            'text': '2月8日上午'}]},
 {'Competition': [{'end': 35,
                   'probability': 0.985105301913876,
                   'start': 18,
                   'text': 'French Open Final'}],
  'Player': [{'end': 12,
              'probability': 0.9374054078857128,
              'start': 0,
              'text': 'Rafael Nadal'}]}]

2.数据标注教学

2.1基于Label Studio数据标注

2.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进行标注。

2.1.2 文本抽取标注教学

  • 项目创建

点击创建(Create)开始创建一个新的项目,填写项目名称、描述,然后选择Object Detection with Bounding Boxes

  • 填写项目名称、描述
  • 命名实体识别、关系抽取、事件抽取、实体/评价维度分类任务选择``Relation Extraction`。
  • 添加标签(也可跳过后续在Setting/Labeling Interface中配置)

图中展示了实体类型标签的构建,其他类型标签的构建可参考

  • 数据上传

先从本地上传txt格式文件,选择List of tasks,然后选择导入本项目。

  • 标签构建
  • Span类型标签
  • Relation类型标签

Relation XML模板:

  <Relations>
    <Relation value="歌手"/>
    <Relation value="发行时间"/>
    <Relation value="所属专辑"/>
  </Relations>
  • 任务标注
  • 实体抽取

标注示例:

该标注示例对应的schema为:

schema = [
    '时间',
    '选手',
    '赛事名称',
    '得分'
]
  • 关系抽取

对于关系抽取,其P的类型设置十分重要,需要遵循以下原则

“{S}的{P}为{O}”需要能够构成语义合理的短语。比如对于三元组(S, 父子, O),关系类别为父子是没有问题的。但按照UIE当前关系类型prompt的构造方式,“S的父子为O”这个表达不是很通顺,因此P改成孩子更好,即“S的孩子为O”。合理的P类型设置,将显著提升零样本效果

该标注示例对应的schema为:

schema = {
    '作品名': [
        '歌手',
        '发行时间',
        '所属专辑'
    ]
}

该标注示例对应的schema为:

schema = '情感倾向[正向,负向]'
  • 数据导出

勾选已标注文本ID,选择导出的文件类型为JSON,导出数据:

  • 数据转换

将导出的文件重命名为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

3.基于医疗领域NER微调

3.1 加载数据数据标注

#加载数据集
!wget https://bj.bcebos.com/paddlenlp/datasets/uie/data_distill/data.zip && unzip data.zip -d ./data
!python doccano.py \
    --doccano_file ./data/data/doccano_ext.json \
    --task_type ext \
    --save_dir ./data \
    --splits 0.8 0.15 0.05 \
    --schema_lang ch

备注:

  • 默认情况下 doccano.py 脚本会按照比例将数据划分为 train/dev/test 数据集
  • 每次执行 doccano.py 脚本,将会覆盖已有的同名数据文件
  • 在模型训练阶段我们推荐构造一些负例以提升模型效果,在数据转换阶段我们内置了这一功能。可通过negative_ratio控制自动构造的负样本比例;负样本数量 = negative_ratio * 正样本数量。
  • 对于从doccano导出的文件,默认文件中的每条数据都是经过人工正确标注的。

此外,也可以通过数据标注平台 Label Studio 进行数据标注。本示例提供了 labelstudio2doccano.py 脚本,将 label studio 导出的 JSON 数据文件格式转换成 doccano 导出的数据文件格式,后续的数据转换与模型微调等操作不变。

python labelstudio2doccano.py --labelstudio_file label-studio.json

可配置参数说明:

  • labelstudio_file: label studio 的导出文件路径(仅支持 JSON 格式)。
  • doccano_file: doccano 格式的数据文件保存路径,默认为 “doccano_ext.jsonl”。
  • task_type: 任务类型,可选有抽取(“ext”)和分类(“cls”)两种类型的任务,默认为 “ext”。

3.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 42 \
    --model_name_or_path uie-base \
    --output_dir ./checkpoint/model_best \
    --train_path data/train.txt \
    --dev_path data/dev.txt  \
    --max_seq_length 512  \
    --per_device_eval_batch_size 16 \
    --per_device_train_batch_size  16 \
    --num_train_epochs 20 \
    --learning_rate 1e-5 \
    --label_names "start_positions" "end_positions" \
    --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-26 17:57:40,257] [    INFO] - eval_loss: 0.0049851336516439915, eval_precision: 0.6474820143884892, eval_recall: 0.72, eval_f1: 0.6818181818181818, eval_runtime: 1.4021, eval_samples_per_second: 132.655, eval_steps_per_second: 8.558, epoch: 20.0
[2023-05-26 17:57:40,257] [    INFO] - ***** eval metrics *****
[2023-05-26 17:57:40,257] [    INFO] -   epoch                   =       20.0
[2023-05-26 17:57:40,257] [    INFO] -   eval_f1                 =     0.6818
[2023-05-26 17:57:40,257] [    INFO] -   eval_loss               =      0.005
[2023-05-26 17:57:40,257] [    INFO] -   eval_precision          =     0.6475
[2023-05-26 17:57:40,257] [    INFO] -   eval_recall             =       0.72
[2023-05-26 17:57:40,257] [    INFO] -   eval_runtime            = 0:00:01.40
[2023-05-26 17:57:40,257] [    INFO] -   eval_samples_per_second =    132.655
[2023-05-26 17:57:40,257] [    INFO] -   eval_steps_per_second   =      8.558
#多卡训练:GPU环境中使用,可以指定gpus参数进行多卡训练:
# !export finetuned_model=./checkpoint/model_best
# !python -u -m paddle.distributed.launch --gpus "0,1" finetune.py \
#     --device gpu \
#     --logging_steps 10 \
#     --save_steps 100 \
#     --eval_steps 100 \
#     --seed 42 \
#     --model_name_or_path uie-base \
#     --output_dir $finetuned_model \
#     --train_path data/train.txt \
#     --dev_path data/dev.txt  \
#     --max_seq_length 512  \
#     --per_device_eval_batch_size 16 \
#     --per_device_train_batch_size  16 \
#     --num_train_epochs 100 \
#     --learning_rate 1e-5 \
#     --do_train \
#     --do_eval \
#     --do_export \
#     --export_model_dir $finetuned_model \
#     --label_names "start_positions" "end_positions" \
#     --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

可配置参数说明:

3.3 模型评估

评估方式说明:采用单阶段评价的方式,即关系抽取、事件抽取等需要分阶段预测的任务对每一阶段的预测结果进行分别评价。验证/测试集默认会利用同一层级的所有标签来构造出全部负例。

可开启debug模式对每个正例类别分别进行评估,该模式仅用于模型调试:

!python evaluate.py \
    --model_path ./checkpoint/model_best \
    --test_path ./data/dev.txt \
    --batch_size 16 \
    --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-26 17:59:33,311] [    INFO] - Class Name: all_classes
# [2023-05-26 17:59:33,311] [    INFO] - Evaluation Precision: 0.64748 | Recall: 0.72000 | F1: 0.68182



[2023-05-26 18:00:38,849] [    INFO] - -----------------------------
[2023-05-26 18:00:38,849] [    INFO] - Class Name: 疾病
[2023-05-26 18:00:38,849] [    INFO] - Evaluation Precision: 0.90000 | Recall: 0.84375 | F1: 0.87097
[2023-05-26 18:00:38,953] [    INFO] - -----------------------------
[2023-05-26 18:00:38,953] [    INFO] - Class Name: 手术治疗
[2023-05-26 18:00:38,953] [    INFO] - Evaluation Precision: 0.73333 | Recall: 0.84615 | F1: 0.78571
[2023-05-26 18:00:39,100] [    INFO] - -----------------------------
[2023-05-26 18:00:39,101] [    INFO] - Class Name: 检查
[2023-05-26 18:00:39,101] [    INFO] - Evaluation Precision: 0.65625 | Recall: 0.63636 | F1: 0.64615
[2023-05-26 18:00:39,200] [    INFO] - -----------------------------
[2023-05-26 18:00:39,200] [    INFO] - Class Name: X的手术治疗
[2023-05-26 18:00:39,200] [    INFO] - Evaluation Precision: 0.84615 | Recall: 0.84615 | F1: 0.84615
[2023-05-26 18:00:39,291] [    INFO] - -----------------------------
[2023-05-26 18:00:39,291] [    INFO] - Class Name: X的实验室检查
[2023-05-26 18:00:39,291] [    INFO] - Evaluation Precision: 0.66667 | Recall: 0.62500 | F1: 0.64516
[2023-05-26 18:00:39,371] [    INFO] - -----------------------------
[2023-05-26 18:00:39,371] [    INFO] - Class Name: X的影像学检查
[2023-05-26 18:00:39,371] [    INFO] - Evaluation Precision: 0.66667 | Recall: 0.55556 | F1: 0.60606

可配置参数说明:

  • model_path: 进行评估的模型文件夹路径,路径下需包含模型权重文件model_state.pdparams及配置文件model_config.json
  • test_path: 进行评估的测试集文件。
  • batch_size: 批处理大小,请结合机器情况进行调整,默认为16。
  • max_seq_len: 文本最大切分长度,输入超过最大长度时会对输入文本进行自动切分,默认为512。
  • debug: 是否开启debug模式对每个正例类别分别进行评估,该模式仅用于模型调试,默认关闭。
  • multilingual: 是否是跨语言模型,默认关闭。
  • schema_lang: 选择schema的语言,可选有chen。默认为ch,英文数据集请选择en

3.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

  1. 修复加载最新版本paddlenlp重启内核即可
  2. 重启项目,先加载uie,再加在uie-x则不出错
!pip install --pre --upgrade paddlenlp -f https://www.paddlepaddle.org.cn/whl/paddlenlp.html
from pprint import pprint
from paddlenlp import Taskflow

schema = {"疾病": ["手术治疗", "实验室检查", "影像学检查"]}
my_ie = Taskflow("information_extraction", schema=schema, task_path='./checkpoint/model_best')
pprint(my_ie("关于脑膜膨出或脑脑膜膨出的诊断,根据囊性包块的部位、大小和外观,透光试验阳性,加上相应的病史及临床表现,一般作出正确诊断并不难。头颅CT平扫可显示颅骨缺损及由此向外膨出具有脑脊液同样密度的囊性肿物,如合并脑脑膜膨出则可见囊内有脑组织密度影。"))

[2023-05-29 10:12:14,567] [    INFO] - loading configuration file ./checkpoint/model_best/config.json
[2023-05-29 10:12:14,571] [    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 10:12:16,072] [    INFO] - All model checkpoint weights were used when initializing UIE.

[2023-05-29 10:12:16,074] [    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 10:12:16,078] [    INFO] - Converting to the inference model cost a little time.
[2023-05-29 10:12:23,647] [    INFO] - The inference model save in the path:./checkpoint/model_best/static/inference
[2023-05-29 10:12:25,616] [    INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load './checkpoint/model_best'.


[{'疾病': [{'end': 6,
          'probability': 0.9975638704756875,
          'relations': {'实验室检查': [{'end': 36,
                                   'probability': 0.9964935361743485,
                                   'start': 32,
                                   'text': '透光试验'}],
                        '影像学检查': [{'end': 70,
                                   'probability': 0.9986574055854476,
                                   'start': 64,
                                   'text': '头颅CT平扫'}]},
          'start': 2,
          'text': '脑膜膨出'}]}]

4.基于SimpleServing 的模型快速服务化部署

在 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 schema
schema = 
* 设置模型路径
# Default task_path
uie = 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 Taskflow
schema = 
uie = Taskflow("zero_shot_text_classification",
                   schema=schema,
                   model="uie-base",
                   max_seq_len=512,
                   batch_size=1,
                   pred_threshold=0.5,
                   precision="fp32")
# Changed to input texts you wanted
texts = ['麻疹感染@### 诊断性检查 最常使用的诊断试验是麻疹特异性IgM抗体检测。麻疹感染@出疹后3-14天敏感性最高']
%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如果不行,可以直接进入终端进行调试,需要注意的是要在同一个路径下不然会报错:

import json

import requests

url = "http://0.0.0.0:8190/taskflow/uie"
headers = {"Content-Type": "application/json"}
texts = ["麻疹感染@### 诊断性检查 最常使用的诊断试验是麻疹特异性IgM抗体检测。麻疹感染@出疹后3-14天敏感性最高"]
data = {
    "data": {
        "text": texts,
    }
}
r = requests.post(url=url, headers=headers, data=json.dumps(data))
datas = json.loads(r.text)
print(datas)


from paddlenlp import SimpleServer, Taskflow

# The schema changed to your defined schema
schema = {"疾病": ["手术治疗", "实验室检查", "影像学检查"]}
# The task path changed to your best model path
uie = Taskflow("information_extraction", schema=schema, task_path="/home/aistudio/checkpoint/model_best")
# If you want to define the finetuned uie service
app = SimpleServer()
app.register_taskflow("taskflow/uie", uie)

5.UIE Slim 数据蒸馏

在UIE强大的抽取能力背后,同样需要较大的算力支持计算。在一些工业应用场景中对性能的要求较高,若不能有效压缩则无法实际应用。因此,我们基于数据蒸馏技术构建了UIE Slim数据蒸馏系统。其原理是通过数据作为桥梁,将UIE模型的知识迁移到封闭域信息抽取小模型,以达到精度损失较小的情况下却能达到大幅度预测速度提升的效果。

  • Step 1: 使用UIE模型对标注数据进行finetune,得到Teacher Model。

  • Step 2: 用户提供大规模无标注数据,需与标注数据同源。使用Taskflow UIE对无监督数据进行预测。

  • Step 3: 使用标注数据以及步骤2得到的合成数据训练出封闭域Student Model。

  • 数据集介绍

示例数据包含以下两部分:

名称 数量
doccano格式标注数据(doccano_ext.json) 200
无标注数据(unlabeled_data.txt) 1277

5.1 离线蒸馏

  • 通过训练好的UIE定制模型预测无监督数据的标签

可配置参数说明:

  • data_path: 标注数据(doccano_ext.json)及无监督文本(unlabeled_data.txt)路径。
  • model_path: 训练好的UIE定制模型路径。
  • save_dir: 学生模型训练数据保存路径。
  • synthetic_ratio: 控制合成数据的比例。最大合成数据数量=synthetic_ratio*标注数据数量。
  • task_type: 选择任务类型,可选有entity_extractionrelation_extractionevent_extractionopinion_extraction。因为是封闭域信息抽取,需指定任务类型。
  • seed: 随机种子,默认为1000。
!unzip data.zip -d ./data
!python doccano.py \
    --doccano_file ./data/data/doccano_ext.json \
    --task_type ext \
    --save_dir ./data \
    --splits 0.8 0.15 0.05 \
    --schema_lang ch
!cp /home/aistudio/data/sample_index.json /home/aistudio/data/data
# %cd data_distill
!python data_distill.py \
    --data_path /home/aistudio/data/data \
    --save_dir student_data \
    --task_type relation_extraction \
    --synthetic_ratio 10 \
    --model_path /home/aistudio/checkpoint/model_best #已经训练好的模型

5.2 老师模型评估

UIE微调阶段针对UIE训练格式数据评估模型效果(该评估方式非端到端评估,不适合关系、事件等任务),可通过以下评估脚本针对原始标注格式数据评估模型效果

!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

5.3 学生模型训练

!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"\
    --valid_steps 100\
    --logging_steps 50\
    --save_dir './checkpoint-mini'\
    --batch_size 32

5.4 Taskflow部署学生模型

  • 通过Taskflow一键部署封闭域信息抽取模型,task_path为学生模型路径。
from pprint import pprint
from paddlenlp import Taskflow
ie = 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 extraction
pprint(ie("麻疹感染@### 诊断性检查 最常使用的诊断试验是麻疹特异性IgM抗体检测。麻疹感染@出疹后3-14天敏感性最高"))
[2023-05-29 16:06:31,608] [    INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load '/home/aistudio/data_distill/checkpoint-mini/model_best'.


[{'疾病': [{'end': 4,
          'probability': 0.9999304,
          'relations': {'实验室检查': [{'end': 37,
                                   'probability': 0.9997897,
                                   'relations': {},
                                   'start': 25,
                                   'text': '麻疹特异性IgM抗体检测'}]},
          'start': 0,
          'text': '麻疹感染'}]}]

7.总结

7.1 方案对比总结

模型 推理耗时 提升倍数
UIE+faster 71.23 1
uie+servering 70.56 1+
UIE Slim 9.32 7.6

本项目为UIE框架升级版本实体关系抽取,详细讲解了数据标注,以及医疗领域NER微调,同时完成基于SimpleServing的快速服务化部署,并考虑了在一些工业应用场景中对性能的要求较高,若不能有效压缩则无法实际应用。因此,将UIE模型的知识迁移到封闭域信息抽取小模型,同时使用FasterTokenizer进行文本预处理加速,整体提速7.6x倍。

7.2 更多优质项目推荐

NLP专栏简介:数据增强、智能标注、意图识别算法|多分类算法、文本信息抽取、多模态信息抽取、可解释性分析、性能调优、模型压缩算法等:

  1. [小样本文本分类应用:基于UTC的医疗意图多分类,训练调优部署一条龙]

  2. [“中国法研杯”司法人工智能挑战赛:基于UTC的多标签/层次分类小样本文本应用]

  3. [Paddlenlp之UIE模型实战实体抽取任务【打车数据、快递单】]

  4. [Paddlenlp之UIE关系抽取模型【高管关系抽取为例】]

  5. [UIE Slim满足工业应用场景,解决推理部署耗时问题,提升效能!]

  6. [基于Labelstudio的UIE半监督智能标注方案(本地版),赶快用起来啦!]

  7. [基于Labelstudio的UIE半监督深度学习的智能标注方案(云端版),提效!]

  8. [基于ERNIELayout&PDFplumber-UIEX多方案学术论文信息抽取]

  9. [基线提升至96.45%:2022 司法杯犯罪事实实体识别+数据蒸馏+主动学习]

  10. [[信息抽取]基于ERNIE3.0的多对多信息抽取算法:属性关系抽取]

项目链接以及码源

码源链接在文章末跳转订阅可见

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。