# pytorch_bert_bilstm_crf_ner
# 依赖
```python
python==3.6 (可选)
pytorch==1.6.0 (可选)
pytorch-crf==0.7.2
transformers==4.5.0
numpy==1.22.4
packaging==21.3
```
****
这里总结下步骤,以cner数据为例:
```python
先去hugging face下载相关文件到chinese-bert-wwwm-ext下。
目录结构:
--pytorch_bilstm_crf_ner
--model_hub
----chinese-bert-wwm-ext
------vocab.txt
------config.json
------pytorch_model.bin
1、原始数据放在data/cner/raw_data/下,并新建mid_data和final_data两个文件夹。
2、将raw_data下的数据处理成mid_data下的格式。其中:
--labels.txt:实体类别
["PRO", "ORG", "CONT", "RACE", "NAME", "EDU", "LOC", "TITLE"]
--nor_ent2id.json:BIOES格式的标签
{"O": 0, "B-PRO": 1, "I-PRO": 2, "E-PRO": 3, "S-PRO": 4, "B-ORG": 5, "I-ORG": 6, "E-ORG": 7, "S-ORG": 8, "B-CONT": 9, "I-CONT": 10, "E-CONT": 11, "S-CONT": 12, "B-RACE": 13, "I-RACE": 14, "E-RACE": 15, "S-RACE": 16, "B-NAME": 17, "I-NAME": 18, "E-NAME": 19, "S-NAME": 20, "B-EDU": 21, "I-EDU": 22, "E-EDU": 23, "S-EDU": 24, "B-LOC": 25, "I-LOC": 26, "E-LOC": 27, "S-LOC": 28, "B-TITLE": 29, "I-TITLE": 30, "E-TITLE": 31, "S-TITLE": 32}
--train.json/dev.json/test.json:是一个列表,列表里面每个元素是:
[
{
"id": 0,
"text": "常建良,男,",
"labels": [
[
"T0",
"NAME",
0,
3, # 后一位
"常建良"
]
]
},
......
]
3、在preprocess.py里面修改数据集名称和设置文本最大长度,并按照其它数据一样添加一段代码。运行后得到final_data下的数据。
4、运行指令进行训练、验证和测试:
python main.py \
--bert_dir="../model_hub/chinese-bert-wwm-ext/" \
--data_dir="./data/cner/" \
--data_name="cner" \
--model_name="bert" \# 默认为bert
--log_dir="./logs/" \
--output_dir="./checkpoints/" \
--num_tags=33 \# BIOES标签的数目
--seed=123 \
--gpu_ids="0" \
--max_seq_len=150 \# 文本最大长度,和prepcoess.py里面保持一致
--lr=3e-5 \
--crf_lr=3e-2 \
--other_lr=3e-4 \
--train_batch_size=32 \# 训练batch_size
--train_epochs=3 \# 训练epoch
--eval_batch_size=32 \# 验证batch_size
--lstm_hidden=128 \
--num_layers=1 \
--use_lstm="False" \# 是否使用bilstm
--use_idcnn="True" \# 是否使用idcnn。idcnn和bilstm只能选择一种
--use_crf="True" \# 是否使用crf
--dropout_prob=0.3 \
--dropout=0.3
```
运行的时候需要在命令行运行,且不要带上后面的注释。windows下运行需要将指令变成一行,即删除掉"\\"。
****
### 温馨提示
- 新增了转换为onnx并进行推理,具体内容在convert_onnx下,```python convert_onnx.py```,只支持对单条数据的推理。在CPU下,原本推理时间:0.714256477355957s,转换后推理时间:0.4593505859375s。需要安装onnxruntime和onnx库。原本的pytorch-crf不能转换为onnx,这里使用了[here](https://github.com/facebookresearch/pytext/blob/master/pytext/models/crf.py)。目前只测试了bert_crf模型,其余的可根据需要自行调整。
#### 问题汇总
- ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions.
解决方法:```pip install numpy==1.22.4```
- packaging.version.InvalidVersion: Invalid version: '0.10.1,<0.11'
解决方法:```pip install packaging==21.3```
#### 2023-05-12
重新写了一个简洁版本的BERT-BILSTM-CRF,代码更简洁,更方便使用:https://github.com/taishan1994/BERT-BILSTM-CRF
#### 2023-03-17
适配pytorch2.0版本,主要是加入torch.compile(model)。虽然程序已跑通,但可能还存在一些问题导致速度并没有提升。
#### 2022-10-10
补充知识蒸馏实例。在knowledge_distillation/kd.py里面是具体代码,该实例将bert_idcnn_crf_cner蒸馏到idcnn_crf_cner上。具体步骤:
- 先训练一个教师模型:bert_idcnn_crf_cner。
- 再训练一个学生模型:idcnn_crf_cner。
- 然后修改kd.py里面参数文件的路径,并修改相关参数运行kd.py即可。
在cner数据集上蒸馏之后的效果没有原来的好,可能是cner的数据量太少了。教师模型和学生模型之间的差异太小。
#### 2022-09-23
- 在predict.py里面新增batch_predict:若一条文本大于当前设置的文本最大长度,则对句子进行切分,切分后进行批量预测,在scripts/server.py可使用merge_with_loc进行结果的合并。
- 增加tensorboardX可视化损失函数变化过程。通过```--use_tensorboard=="True"```指定使用。命令行```tensorboard --logdir=./tensorboard```查看结果。
- 新增onenotes4.0数据,这里只提供训练数据,并提供转换数据process.py。
#### 2022-08-18
- 新增weibo和msra数据,具体运行实例这里不补充,可当练手用。
- 将预测代码提取至predict.py里面,使用时需要注意以下几方面:
- 修改args_path
- 修改model_name
#### 2022-09-15
新增IDCNN模型,[IDCNN代码来源](https://github.com/circlePi/IDCNN-CRF-Pytorch/blob/master/IDCNN-CRF/cnn.py),使用单独的IDCNN_crf需要设置```model_name="idcnn"```。另外,也可将其和bert相关模型结合使用,根据use_idcnn参数使用,另外bilstm和idcnn是不可同时使用:
```python
python main.py \
--bert_dir="../model_hub/chinese-bert-wwm-ext/" \
--data_dir="./data/cner/" \
--data_name="cner" \
--model_name="bert" \
--log_dir="./logs/" \
--output_dir="./checkpoints/" \
--num_tags=33 \
--seed=123 \
--gpu_ids="0" \
--max_seq_len=150 \
--lr=3e-5 \
--crf_lr=3e-2 \
--other_lr=3e-4 \
--train_batch_size=32 \
--train_epochs=3 \
--eval_batch_size=32 \
--lstm_hidden=128 \
--num_layers=1 \
--use_lstm="False" \
--use_idcnn="True" \
--use_crf="True" \
--dropout_prob=0.3 \
--dropout=0.3
```
| 评价指标:F1 | 模型大小 | PRO | ORG | CONT | RACE | NAME | EDU | LOC | TITLE | F1 |
| ------------------- | -------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ----- | ------ |
| idcnn_crf_cner | 64.95M | 0.76 | 0.86 | 1.00 | 0.97 | 0.97 | 0.95 | 0.80 | 0.87 | 0.8817 |
| bert_idcnn_crf_cner | 393.25M | 0.92 | 0.92 | 1.00 | 0.90 | 0.99 | 0.97 | 1.00 | 0.90 | 0.9232 |
#### 2022-09-14
新增单独的**bilstm_crf**和**crf**模型,使用的词汇表是根据自己选择的预训练模型的vocab.txt。使用bilstm_crf时需要设置```model_name="bilstm"```,使用crf需要设置```model_name="crf"```。需要注意bilstm默认使用crf,crf默认只使用其自己。运行:
```python
python main.py \
--bert_dir="../model_hub/chinese-bert-wwm-ext/" \
--data_dir="./data/cner/" \
--data_name="cner" \
--model_name="bilstm" \
--log_dir="./logs/" \
--output_dir="./checkpoints/" \
--num_tags=33 \
--seed=123 \
--gpu_ids="0" \
--max_seq_len=150 \
--lr=3e-5 \
--crf_lr=3e-2 \
--other_lr=3e-4 \
--train_batch_size=32 \
--train_epochs=20 \
--eval_batch_size=32 \
--lstm_hidden=128 \
--num_layers=1 \
--use_lstm="True" \
--use_crf="True" \
--dropout_prob=0.3 \
--dropout=0.3
```
效果:针对于cner数据集
| 评价指标:F1 | 模型大小 | PRO | ORG | CONT | RACE | NAME | EDU | LOC | TITLE | F1 |
| --------------- | -------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ----- | ------ |
| bilstm_crf_cner | 65.45M | 0.90 | 0.86 | 1.00 | 0.97 | 0.98 | 0.97 | 1.00 | 0.87 | 0.8853 |
| crf_cner | 62.00M | 0.77 | 0.81 | 1.00 | 1.00 | 0.90 | 0.94 | 1.00 | 0.84 | 0.8453 |
#### 2022-09-02
- 补充将模型启动为服务代码,代码位于scripts目录下,针对于不同的数据集和模型,只需要修改开头的args的路径即可。
在linux下使用:
- ./start_server.sh:启动服务
- ./stop_server.sh:停止服务
- ./restart_server.sh:停止服务并重新启动
在windows下直接运�