随着大数据和人工智能技术的快速发展,构建领域特定的知识图谱已成为信息管理和决策支持的重要手段。武器装备知识图谱不仅能够对复杂的武器系统进行结构化展示,还可以通过关系推理揭示武器与装备之间的潜在联系。
1、技术路线
本文将详细介绍如何基于开源的WQZB数据构建武器装备知识图谱,技术路线包括以下三个关键步骤:
1、WQ装备关系抽取模型训练
通过对开源WQZB数据进行标注与预处理,使用深度学习模型进行武器装备关系的自动抽取。我们将训练一个专门针对武器与装备关系的抽取模型,确保能够高效、精准地识别出各类武器及其相关属性和关联关系。
2、Neo4j部署
Neo4j 是一个广泛使用的图数据库,能够很好地存储和查询知识图谱。在这一部分,我们将详细讲解如何在本地或服务器上安装和配置Neo4j环境,并为后续的知识图谱存储和查询提供支持。
3、WQ装备关系抽取服务集成到Neo4j
通过调用已部署的WQ装备关系抽取API,自动化地将抽取的关系数据存储到Neo4j中,形成武器装备知识图谱。我们还将介绍如何通过Neo4j的查询语言Cypher进行图谱的可视化展示与关系查询。
通过这些步骤,本文将带领大家构建一个完整的武器装备知识图谱系统,能够帮助用户直观地了解武器与装备之间的复杂关系。
服务器配置
cuda版本11.2,RTX A6000 *4 192g显存
默认环境以构建完成。
Python 3.7.16
paddle-bfloat 0.1.7
paddle2onnx 1.0.5
paddlefsl 1.1.0
paddlenlp 2.4.5
paddlepaddle-gpu 2.4.1.post112
2、实现方法
2.1 、WQ装备关系抽取模型构建及训练
对于简单的抽取目标可以直接使用paddlenlp.Taskflow实现零样本(zero-shot)抽取,对于细分场景我们推荐使用定制功能(标注少量数据进行模型微调)以进一步提升效果。
2.1.1 代码结构
.
├── utils.py # 数据处理工具
├── finetune.py # 模型微调、压缩脚本
├── evaluate.py # 模型评估脚本
└── README.md
2.1.2 数据标注
我们推荐使用 Label Studio 进行文本信息抽取数据标注,本项目打通了从数据标注到训练的通道,也即Label Studio导出数据可以通过 label_studio.py 脚本轻松将数据转换为输入模型时需要的形式,实现无缝衔接。标注方法的详细介绍请参考 Label Studio数据标注指南。
这里我们提供预先标注好的军事关系抽取数据集的文件,可以运行下面的命令行下载数据集,我们将展示如何使用数据转化脚本生成训练/验证/测试集文件,并使用UIE模型进行微调。
下载军事关系抽取数据集:
wget https://bj.bcebos.com/paddlenlp/datasets/military.tar.gz
tar -xvf military.tar.gz
mv military data
rm military.tar.gz
生成训练/验证集文件:
python ../label_studio.py \
--label_studio_file ./data/label_studio.json \
--save_dir ./data \
--splits 0.76 0.24 0 \
--negative_ratio 3 \
--task_type ext
更多不同类型任务(含实体抽取、关系抽取、文档分类等)的标注规则及参数说明,请参考Label Studio数据标注指南。
2.1.3 模型微调
推荐使用 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 16 \
--per_device_eval_batch_size 16 \
--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
如果在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
该示例代码中由于设置了参数 --do_eval,因此在训练完会自动进行评估。
可配置参数说明:
- device: 训练设备,可选择 ‘cpu’、‘gpu’、‘npu’ 其中的一种;默认为 GPU 训练。
- logging_steps: 训练过程中日志打印的间隔 steps 数,默认10。
- save_steps: 训练过程中保存模型 checkpoint 的间隔 steps 数,默认100。
- eval_steps: 训练过程中保存模型 checkpoint 的间隔 steps 数,默认100。
- seed:全局随机种子,默认为 42。
- model_name_or_path:进行 few shot 训练使用的预训练模型。默认为 “uie-x-base”。
- 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.1.4 模型评估
通过运行以下命令进行模型评估:
python evaluate.py \
--model_path ./checkpoint/model_best \
--test_path ./data/dev.txt \
--device gpu \
--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 \
--device gpu \
--max_seq_len 512 \
--multilingual
评估方式说明:采用单阶段评价的方式,即关系抽取、事件抽取等需要分阶段预测的任务对每一阶段的预测结果进行分别评价。验证/测试集默认会利用同一层级的所有标签来构造出全部负例。
可开启debug模式对每个正例类别分别进行评估,该模式仅用于模型调试:
python evaluate.py \
--model_path ./checkpoint/model_best \
--test_path ./data/dev.txt \
--debug
输出打印示例:
[2022-11-21 12:48:41,794] [ INFO] - -----------------------------
[2022-11-21 12:48:41,795] [ INFO] - Class Name: 武器名称
[2022-11-21 12:48:41,795] [ INFO] - Evaluation Precision: 0.96667 | Recall: 0.96667 | F1: 0.96667
[2022-11-21 12:48:44,093] [ INFO] - -----------------------------
[2022-11-21 12:48:44,094] [ INFO] - Class Name: X的产国
[2022-11-21 12:48:44,094] [ INFO] - Evaluation Precision: 1.00000 | Recall: 0.99275 | F1: 0.99636
[2022-11-21 12:48:46,474] [ INFO] - -----------------------------
[2022-11-21 12:48:46,475] [ INFO] - Class Name: X的研发单位
[2022-11-21 12:48:46,475] [ INFO] - Evaluation Precision: 0.77519 | Recall: 0.64935 | F1: 0.70671
[2022-11-21 12:48:48,800] [ INFO] - -----------------------------
[2022-11-21 12:48:48,801] [ INFO] - Class Name: X的类型
[2022-11-21 12:48:48,801] [ 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.1.5 模型推理
from pprint import pprint
from paddlenlp import Taskflow
schema = {"武器名称": ["产国", "类型", "研发单位"]}
# 设定抽取目标和定制化模型权重路径
my_ie = Taskflow("information_extraction", schema=schema, task_path='./checkpoint/model_best')
pprint(my_ie("威尔哥(Virgo)减速炸弹是由瑞典FFV军械公司专门为瑞典皇家空军的攻击机实施低空高速轰炸而研制,1956年开始研制,1963年进入服役,装备于A32“矛盾”、A35“龙”、和AJ134“雷”攻击机,主要用于攻击登陆艇、停放的飞机、高炮、野战火炮、轻型防护装甲车辆以及有生力量。"))
结果
[{'武器名称': [{'end': 14,
'probability': 0.9998632702221926,
'relations': {'产国': [{'end': 18,
'probability': 0.9998815094394331,
'start': 16,
'text': '瑞典'}],
'研发单位': [{'end': 25,
'probability': 0.9995875123178521,
'start': 18,
'text': 'FFV军械公司'}],
'类型': [{'end': 14,
'probability': 0.999877336059086,
'start': 12,
'text': '炸弹'}]},
'start': 0,
'text': '威尔哥(Virgo)减速炸弹'}]}]
2.1.6 模型服务封装
采用docker+fastapi+Uvicorn方式部署,接口测试结果如下:
2.2、Neo4j部署
Neo4j部署可采用本地安装和docker安装两种方式。本项目采用本地安装的方式
官网下载JDK:
https://www.oracle.com/java/technologies/downloads/#java11-windows
官网下载neo4j安装文件:
https://neo4j.com/download-center/#releases
解压文件,以管理员身份进入bin目录,第一次需要执行 neo4j install-service 安装服务
------------------------------------------------------注意:!!!!!-----------------------------------
neo4j-community-4.3.6-windows 必须安装jdk-11.0.13_windows-x64_bin(jdk11及11以上版本)
2.1 结果验证
http://localhost:7474/browser/
输入安装过程中设置的用户名和密码。登录成功如下。
3、WQ装备关系抽取服务集成到Neo4j
3.1、方法说明
- 读取txt文件:process_txt_file 函数会读取WQ装备txt 文件中的每一行文本,并调用API提取武器装备信息。
文件内容如下:
一共108条测试数据。 - API调用:get_weapon_api 函数调用远程API,提取武器相关的数据。
关系提取:get_weapon_relation_results 函数会解析API的返回数据,提取武器和装备之间的关系。 - Neo4j存储:通过 load_data_to_neo4j 函数,将提取的武器-装备关系存储到 Neo4j 数据库中。
- 保存为JSON:提取的关系也会被保存为一个 .json 文件,便于后续分析。
3.2、主要代码
def get_weapon_api(text):
request_param = {"text": text}
try:
r = requests.post("http://172.16.100.51:6410/weapon", json=request_param)
r.raise_for_status() # 检查请求是否成功
data = r.json()['data'][0]['武器名称']
return data
except requests.RequestException as e:
print(f"请求发生错误: {e}")
except KeyError as e:
print(f"数据格式输入有问题 KeyError: {e}")
except Exception as e:
print(f"发生未知错误: {e}")
# 连接Neo4j
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "neo4jZH"))
def create_relation(tx, weapon, equipment, relation_type):
query = (
"MERGE (w:Weapon {name: $weapon}) "
"MERGE (e:Equipment {name: $equipment}) "
"MERGE (w)-[:RELATED_TO {type: $relation_type}]->(e)"
)
tx.run(query, weapon=weapon, equipment=equipment, relation_type=relation_type)
3.3、结果展示
以美国为例,结果如下:
3、说明
此项目只作为试验demo,具体实现安装实际要求。不足之处,支持的关系较少,cypher查询较为简单。后续会优化相关模型和cypher查询