4

聊聊从大模型来看NLP解决方案之UIE - 又见阿郎

 4 months ago
source link: https://www.cnblogs.com/zhiyong-ITNote/p/18149938
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

聊聊从大模型来看NLP解决方案之UIE

转载请备注出处:https://www.cnblogs.com/zhiyong-ITNote

自然语言处理NLP任务的实现,相比较以前基于传统机器学习算法实现方法,现在越来越集中使用大模型来实现。
通过——数据标注-模型训练-模型调优/微调-模型压缩-预测部署的大模型流程,覆盖NLP多场景满足开发者落地实现与灵活定制的需求。
PaddleNLP是其中典型的NLP解决方案库,通过聚合业界优质预训练模型并提供开箱即用的开发体验,覆盖NLP多场景的模型库搭配产业实践范例可满足开发者灵活定制的需求。

预训练基座模型主要以ERINE系列大模型为主,毕竟是自家的噻。

之前相关的NLP系列文档也是基于预训练大模型的解决方案来实现的。可参考:
聊聊PaddleNLP库与层次多标签文本分类任务
聊聊层次多标签分类NLP任务的实践

UIE:Universal Information Extraction,通用信息抽取统一框架。官方文档:UIE
该框架实现了实体抽取、关系抽取、事件抽取、情感分析等任务的统一建模,并使得不同任务间具备良好的迁移和泛化能力。PaddleNLP借鉴论文的方法,基于ERNIE 3.0知识增强预训练模型,训练并开源了首个中文通用信息抽取模型UIE。该模型可以支持不限定行业领域和抽取目标的关键信息抽取,实现零样本快速冷启动,并具备优秀的小样本微调能力,快速适配特定的抽取目标。

paddlenlp.Taskflow提供通用信息抽取、评价观点抽取等能力,可抽取多种类型的信息,包括但不限于命名实体识别(如人名、地名、机构名等)、关系(如电影的导演、歌曲的发行时间等)、事件(如某路口发生车祸、某地发生地震等)、以及评价维度、观点词、情感倾向等信息。用户可以使用自然语言自定义抽取目标,无需训练即可统一抽取输入文本中的对应信息。实现开箱即用,并满足各类信息抽取需求。
以实体抽取任务为例:
命名实体识别(Named Entity Recognition,简称NER),是指识别文本中具有特定意义的实体。在开放域信息抽取中,抽取的类别没有限制,用户可以自己定义。

  • 例如抽取的目标实体类型是"时间"、"选手"和"赛事名称", schema构造如下:
['时间', '选手', '赛事名称']

调用示例:

>>> from pprint import pprint
>>> from paddlenlp import Taskflow

>>> schema = ['时间', '选手', '赛事名称'] # Define the schema for entity extraction
>>> ie = Taskflow('information_extraction', schema=schema)
>>> pprint(ie("2月8日上午北京冬奥会自由式滑雪女子大跳台决赛中中国选手谷爱凌以188.25分获得金牌!")) # Better print results using pprint
[{'时间': [{'end': 6,
          'probability': 0.9857378532924486,
          'start': 0,
          'text': '2月8日上午'}],
  '赛事名称': [{'end': 23,
            'probability': 0.8503089953268272,
            'start': 6,
            'text': '北京冬奥会自由式滑雪女子大跳台决赛'}],
  '选手': [{'end': 31,
          'probability': 0.8981548639781138,
          'start': 28,
          'text': '谷爱凌'}]}]
  • 例如抽取的目标实体类型是"肿瘤的大小"、"肿瘤的个数"、"肝癌级别"和"脉管内癌栓分级", schema构造如下:
['肿瘤的大小', '肿瘤的个数', '肝癌级别', '脉管内癌栓分级']

在上例中我们已经实例化了一个Taskflow对象,这里可以通过set_schema方法重置抽取目标。调用示例:

>>> schema = ['肿瘤的大小', '肿瘤的个数', '肝癌级别', '脉管内癌栓分级']
>>> ie.set_schema(schema)
>>> pprint(ie("(右肝肿瘤)肝细胞性肝癌(II-III级,梁索型和假腺管型),肿瘤包膜不完整,紧邻肝被膜,侵及周围肝组织,未见脉管内癌栓(MVI分级:M0级)及卫星子灶形成。(肿物1个,大小4.2×4.0×2.8cm)。"))
[{'肝癌级别': [{'end': 20,
            'probability': 0.9243267447402701,
            'start': 13,
            'text': 'II-III级'}],
  '肿瘤的个数': [{'end': 84,
             'probability': 0.7538413804059623,
             'start': 82,
             'text': '1个'}],
  '肿瘤的大小': [{'end': 100,
             'probability': 0.8341128043459491,
             'start': 87,
             'text': '4.2×4.0×2.8cm'}],
  '脉管内癌栓分级': [{'end': 70,
               'probability': 0.9083292325934664,
               'start': 67,
               'text': 'M0级'}]}]

UIE支持多种NLP任务,毕竟是统一信息抽取框架。其它的任务可以参考官方文档。

肯定是自家的预训练基座啦。

模型 结构 语言
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 中、英文

uie模型是基于ERINE基座模型训练出来的。

微调—定制化

其实在我个人的角度来看,上述的内容在很多的框架、平台都已经有了;譬如Modelscope,我现在养成习惯,遇到啥NLP相关的、大模型相关的,就去Modelscope找解决策略。但在Modelscope上有个最大的问题,当然这是我个人的看法——微调支持不够,很多的模型/库压根没有微调。老实说,这的确是帮助不大,在很多时候我们需要的是可以接入的定制化实现。

这也正常,毕竟如果开放了微调,支持灵活的定制化,对开源方就不太友好了。

而相比较来说,PaddleNLP的微调支持就很到位了。

基于doccano标注平台做数据标注。可参考: 聊聊层次多标签分类NLP任务的实践

荐使用 Trainer API对模型进行微调。只需输入模型、数据集等就可以使用 Trainer API 高效快速地进行预训练、微调和模型压缩等任务,可以一键启动多卡训练、混合精度训练、梯度累积、断点重启、日志显示等功能,Trainer API 还针对训练过程的通用训练配置做了封装,比如:优化器、学习率调度等。
使用下面的命令,使用 uie-base 作为预训练模型进行模型微调,将微调后的模型保存至$finetuned_model:
单卡启动:

export finetuned_model=./checkpoint/model_best

python 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 20 \
    --learning_rate 1e-5 \
    --label_names "start_positions" "end_positions" \
    --do_train \
    --do_eval \
    --do_export \
    --export_model_dir $finetuned_model \
    --overwrite_output_dir \
    --disable_tqdm True \
    --metric_for_best_model eval_f1 \
    --load_best_model_at_end  True \
    --save_total_limit 1

paddlenlp.Taskflow装载定制模型,通过task_path指定模型权重文件的路径,路径下需要包含训练好的模型权重文件model_state.pdparams。

>>> from pprint import pprint
>>> from paddlenlp import Taskflow

>>> schema = ['出发地', '目的地', '费用', '时间']
# 设定抽取目标和定制化模型权重路径
>>> my_ie = Taskflow("information_extraction", schema=schema, task_path='./checkpoint/model_best')
>>> pprint(my_ie("城市内交通费7月5日金额114广州至佛山"))
[{'出发地': [{'end': 17,
           'probability': 0.9975287467835301,
           'start': 15,
           'text': '广州'}],
  '时间': [{'end': 10,
          'probability': 0.9999476678061399,
          'start': 6,
          'text': '7月5日'}],
  '目的地': [{'end': 20,
           'probability': 0.9998511131226735,
           'start': 18,
           'text': '佛山'}],
  '费用': [{'end': 15,
          'probability': 0.9994474579292856,
          'start': 12,
          'text': '114'}]}]
  • 模型导出:模型训练、压缩时已经自动进行了静态图的导出以及 tokenizer 配置文件保存,保存路径${finetuned_model} 下应该有 .pdimodel、.pdiparams 模型文件可用于推理。
  • 模型部署:
# UIE 模型 CPU 推理
python deploy/python/infer.py --model_dir ./checkpoint/model_best --device cpu
# UIE 模型 GPU 推理
python deploy/python/infer.py --model_dir ./checkpoint/model_best --device gpu

PaddleNLP是基于预训练大模型的NLP任务解决方案库,因此其实践流程其实都是一样的:数据标注-模型训练-模型调优/微调-模型压缩-预测部署。通过对PaddleNLP库的实践与了解熟悉,我个人觉得,非常有助于掌握NLP与大模型在实际应用中的落地。建议大家多了解学习。

转载请备注出处:https://www.cnblogs.com/zhiyong-ITNote

更多PaddleNLP与大模型的文章,请上个人公众号查阅:

image

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK