├── README.md ├── get_result.py ├── model_hub └── chinese-bert-wwm-ext │ └── 占位.txt ├── pytorch_GlobalPointer_Ner ├── README.md ├── checkpoints │ ├── bert-1-eff │ │ └── args.json │ └── 占位.txt ├── config.py ├── data │ ├── cner │ │ ├── mid_data │ │ │ ├── dev.json │ │ │ ├── labels.json │ │ │ ├── test.json │ │ │ └── train.json │ │ └── raw_data │ │ │ ├── __init__.py │ │ │ ├── dev.char.bmes │ │ │ ├── process.py │ │ │ ├── test.char.bmes │ │ │ └── train.char.bmes │ └── guwen │ │ ├── mid_data │ │ ├── dev.json │ │ ├── labels.json │ │ ├── test.json │ │ └── train.json │ │ └── raw_data │ │ ├── dev-label.txt │ │ ├── dev.txt │ │ ├── process.py │ │ ├── source.txt │ │ ├── target.txt │ │ ├── test1.txt │ │ └── testtgt.txt ├── data_loader.py ├── globalpoint.py ├── globalpoint2.py ├── logs │ ├── bert-1-eff.log │ ├── bert-1.log │ └── bert.log ├── main.py ├── preprocess.py ├── tensorboard │ └── 占位.txt └── utils │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-37.pyc │ ├── common_utils.cpython-37.pyc │ ├── cut_sentence.cpython-37.pyc │ ├── metric_utils.cpython-37.pyc │ └── train_utils.cpython-37.pyc │ ├── common_utils.py │ ├── cut_sentence.py │ ├── metric_utils.py │ └── train_utils.py └── pytorch_GlobalPointer_triple_extraction ├── README.md ├── checkpoints ├── bert │ └── args.json └── 占位.txt ├── config.py ├── data └── guwen │ ├── mid_data │ └── predicates.json │ └── raw_data │ ├── dev.json │ ├── process.py │ ├── test.json │ └── train.json ├── data_loader.py ├── logs └── bert.log ├── main.py ├── model.py └── utils ├── __pycache__ ├── common_utils.cpython-37.pyc ├── metric_utils.cpython-37.pyc └── train_utils.cpython-37.pyc ├── common_utils.py ├── metric_utils.py └── train_utils.py /README.md: -------------------------------------------------------------------------------- 1 | # classical_chinese_extraction 2 | 文言文信息抽取(实体识别+关系抽取)。实体识别和关系抽取使用的网络均为globalpointer。 3 | 4 | # 依赖 5 | 6 | 使用pytorch,并需要以下依赖。 7 | 8 | ```python 9 | pip install datasets 10 | pip install transformers 11 | pip install tensorboardX 12 | pip install seqeval 13 | ``` 14 | 15 | # 实体识别 16 | 17 | 进入到pytorch_GlobalPointer_Ner,执行: 18 | 19 | ```python 20 | python main.py \ 21 | --bert_dir="../model_hub/chinese-bert-wwm-ext/" \ 22 | --data_dir="./data/guwen/" \ 23 | --log_dir="./logs/" \ 24 | --output_dir="./checkpoints/" \ 25 | --num_tags=6 \ 26 | --head_size=64 \ 27 | --seed=123 \ 28 | --gpu_ids="0" \ 29 | --max_seq_len=256 \ 30 | --lr=5e-5 \ 31 | --other_lr=5e-5 \ 32 | --train_batch_size=16 \ 33 | --train_epochs=10 \ 34 | --eval_steps=100 \ 35 | --eval_batch_size=16 \ 36 | --max_grad_norm=1 \ 37 | --warmup_proportion=0.1 \ 38 | --adam_epsilon=1e-8 \ 39 | --weight_decay=0.01 \ 40 | --dropout_prob=0.3 \ 41 | --use_tensorboard="False" \ 42 | --use_efficient_globalpointer="True" 43 | ``` 44 | 45 | 得到: 46 | 47 | ```python 48 | 49 | precision:0.5376 recall:0.7349 micro_f1:0.6210 50 | INFO:__main__: precision recall f1-score support 51 | 52 | BOO 0.00 0.00 0.00 0 53 | WAR 0.00 0.00 0.00 0 54 | JOB 0.55 0.70 0.62 439 55 | LOC 0.52 0.52 0.52 218 56 | ORG 0.05 0.75 0.09 4 57 | PER 0.57 0.82 0.67 750 58 | 59 | micro-f1 0.54 0.73 0.62 1411 60 | 61 | INFO:__main__:冬十月,天子拜太祖兖州牧。十二月,雍丘溃,超自杀。夷邈三族。邈诣袁术请救,为其众所杀,兖州平,遂东略陈地。 62 | INFO:__main__:{'JOB': [['兖州牧', 9]], 'LOC': [['雍丘', 17], ['兖州', 43], ['陈地', 50]], 'PER': [['天子', 4], ['太祖', 7], ['超', 21], ['邈', 26], ['邈', 30], ['袁术', 32]]} 63 | ``` 64 | 65 | # 关系抽取 66 | 67 | 进入到pytorch_GlobalPointer_triple_extraaction,执行: 68 | 69 | ```python 70 | python main.py \ 71 | --bert_dir="../model_hub/chinese-bert-wwm-ext/" \ 72 | --data_dir="./data/guwen/" \ 73 | --log_dir="./logs/" \ 74 | --output_dir="./checkpoints/" \ 75 | --num_tags=25 \ 76 | --seed=123 \ 77 | --gpu_ids="0" \ 78 | --max_seq_len=256 \ 79 | --lr=5e-5 \ 80 | --other_lr=5e-5 \ 81 | --train_batch_size=32 \ 82 | --train_epochs=10 \ 83 | --eval_steps=100 \ 84 | --eval_batch_size=8 \ 85 | --max_grad_norm=1 \ 86 | --warmup_proportion=0.1 \ 87 | --adam_epsilon=1e-8 \ 88 | --weight_decay=0.01 \ 89 | --dropout_prob=0.3 \ 90 | --use_tensorboard="False" \ 91 | --use_dev_num=1000 92 | ``` 93 | 94 | 得到: 95 | 96 | ```python 97 | precision=0.2100 recall=0.1145 f1_score=0.1482 98 | 99 | 文本: 冬十月,天子拜太祖兖州牧。十二月,雍丘溃,超自杀。夷邈三族。邈诣袁术请救,为其众所杀,兖州平,遂东略陈地。 100 | 主体: [['邈']] 101 | 客体: [['兖州牧']] 102 | 关系: [[('邈', '任职', '兖州牧')]] 103 | ==================================================================================================== 104 | ``` 105 | 106 | # 联合结果 107 | 108 | ```python 109 | python get_result.py 110 | 111 | {'JOB': [['兖州牧', 9]], 'LOC': [['雍丘', 17], ['兖州', 43], ['陈地', 50]], 'PER': [['天子', 4], ['太祖', 7], ['超', 21], ['邈', 26], ['邈', 30], ['袁术', 32]]} 112 | 文本: 冬十月,天子拜太祖兖州牧。十二月,雍丘溃,超自杀。夷邈三族。邈诣袁术请救,为其众所杀,兖州平,遂东略陈地。 113 | 主体: [['邈']] 114 | 客体: [['兖州牧']] 115 | 关系: [[('邈', '任职', '兖州牧')]] 116 | ==================================================================================================== 117 | ``` 118 | 119 | # 补充 120 | 121 | - 实体识别的效果还可以,但关系抽取的效果不尽人意,因为给的数据集里面每一条文本只包含一种关系,实际上可能包含多种关系的。 122 | - 上述是对文言文数据集的一种尝试,整体框架很容易迁移到其他数据集上,具体每个模块下都有说明(其他数据)。 123 | -------------------------------------------------------------------------------- /get_result.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import torch 4 | import numpy as np 5 | from collections import defaultdict 6 | from transformers import BertTokenizer 7 | from pytorch_GlobalPointer_triple_extraction.utils.train_utils import load_model_and_parallel 8 | from pytorch_GlobalPointer_triple_extraction.model import GlobalPointerRe 9 | from pytorch_GlobalPointer_Ner.utils.common_utils import read_json 10 | from pytorch_GlobalPointer_Ner.globalpoint import GlobalPointerNer 11 | 12 | class Dict2Class(dict): 13 | 14 | def __getattr__(self, key): 15 | return self.get(key) 16 | 17 | def __setattr__(self, key, value): 18 | self[key] = value 19 | 20 | def ner_predict(args, raw_text, model, tokenizer, id2tag, device): 21 | model.eval() 22 | with torch.no_grad(): 23 | tokens = [i for i in raw_text] 24 | encode_dict = tokenizer.encode_plus(text=tokens, 25 | max_length=args.max_seq_len, 26 | padding='max_length', 27 | truncation='longest_first', 28 | is_pretokenized=True, 29 | return_token_type_ids=True, 30 | return_attention_mask=True) 31 | tokens = ['[CLS]'] + tokens + ['[SEP]'] 32 | token_ids = torch.from_numpy(np.array(encode_dict['input_ids'])).unsqueeze(0) 33 | attention_masks = torch.from_numpy(np.array(encode_dict['attention_mask'], dtype=np.uint8)).unsqueeze(0) 34 | token_type_ids = torch.from_numpy(np.array(encode_dict['token_type_ids'])).unsqueeze(0) 35 | logits = model(token_ids.to(device), attention_masks.to(device), token_type_ids.to(device), None) 36 | batch_size = logits.size(0) 37 | pred_tmp = defaultdict(list) 38 | for i in range(batch_size): 39 | logit = logits[i, ...] 40 | for j in range(args.num_tags): 41 | logit_ = logit[j, :len(tokens), :len(tokens)] 42 | for start, end in zip(*np.where(logit_.cpu().numpy() > 0.5)): 43 | pred_tmp[id2tag[j]].append(["".join(tokens[start:end + 1]), start-1]) 44 | 45 | print(dict(pred_tmp)) 46 | 47 | 48 | def re_predict(args, 49 | raw_text, 50 | model, 51 | tokenizer, 52 | id2tag, 53 | device): 54 | model.eval() 55 | with torch.no_grad(): 56 | tokens = [i for i in raw_text] 57 | if len(tokens) > args.max_seq_len - 2: 58 | tokens = tokens[:args.max_seq_len - 2] 59 | tokens = ['[CLS]'] + tokens + ['[SEP]'] 60 | token_ids = tokenizer.convert_tokens_to_ids(tokens) 61 | attention_masks = [1] * len(token_ids) 62 | token_type_ids = [0] * len(token_ids) 63 | if len(token_ids) < args.max_seq_len: 64 | token_ids = token_ids + [0] * (args.max_seq_len - len(tokens)) 65 | attention_masks = attention_masks + [0] * (args.max_seq_len - len(tokens)) 66 | token_type_ids = token_type_ids + [0] * (args.max_seq_len - len(tokens)) 67 | assert len(token_ids) == args.max_seq_len 68 | assert len(attention_masks) == args.max_seq_len 69 | assert len(token_type_ids) == args.max_seq_len 70 | token_ids = torch.from_numpy(np.array(token_ids)).unsqueeze(0).to(device) 71 | attention_masks = torch.from_numpy(np.array(attention_masks, dtype=np.uint8)).unsqueeze(0).to(device) 72 | token_type_ids = torch.from_numpy(np.array(token_type_ids)).unsqueeze(0).to(device) 73 | entity_output, head_output, tail_output = model(token_ids, attention_masks, token_type_ids) 74 | 75 | cur_batch_size = entity_output.shape[0] 76 | spos = [] 77 | subjects = [] 78 | objects = [] 79 | # print(entity_output.shape, head_output.shape, tail_output.shape) 80 | for i in range(cur_batch_size): 81 | example = raw_text 82 | l = len(example) 83 | subject = [] 84 | object = [] 85 | subject_ids = [] 86 | object_ids = [] 87 | spo = [] 88 | single_entity_output = entity_output[i, ...] 89 | single_head_output = head_output[i, ...] 90 | single_tail_output = tail_output[i, ...] 91 | single_head_output = single_head_output[:, 1:l+1:, 1:l+1] 92 | single_tail_output = single_tail_output[:, 1:l+1:, 1:l+1] 93 | subject_entity_outpout = single_entity_output[:1, 1:l+1:, 1:l+1].squeeze() 94 | object_entity_output = single_entity_output[1:, 1:l+1:, 1:l+1].squeeze() 95 | # 注意这里阈值为什么是0 96 | subject_entity_outpout = np.where(subject_entity_outpout.cpu().numpy() > 0) 97 | object_entity_output = np.where(object_entity_output.cpu().numpy() > 0) 98 | for m,n in zip(*subject_entity_outpout): 99 | subject_ids.append((m, n)) 100 | for m,n in zip(*object_entity_output): 101 | object_ids.append((m, n)) 102 | for sh, st in subject_ids: 103 | for oh, ot in object_ids: 104 | # print(example[sh:st+1], example[oh:ot+1]) 105 | # print(np.where(single_head_output[:, sh, oh].cpu().numpy() > 0)) 106 | # print(np.where(single_tail_output[:, st, ot].cpu().numpy() > 0)) 107 | subj = example[sh:st+1] 108 | obj = example[oh:ot+1] 109 | subject.append(subj) 110 | object.append(obj) 111 | 112 | re1 = np.where(single_head_output[:, sh, oh].cpu().numpy() > 0)[0] 113 | re2 = np.where(single_tail_output[:, st, ot].cpu().numpy() > 0)[0] 114 | res = set(re1) & set(re2) 115 | for r in res: 116 | spo.append((subj, id2tag[r], obj)) 117 | 118 | subjects.append(subject) 119 | objects.append(object) 120 | spos.append(spo) 121 | 122 | print("文本:", raw_text) 123 | print('主体:', [list(set(i)) for i in subjects]) 124 | print('客体:', [list(set(i)) for i in objects]) 125 | print('关系:', spos) 126 | print("="*100) 127 | 128 | def main(): 129 | text = "冬十月,天子拜太祖兖州牧。十二月,雍丘溃,超自杀。夷邈三族。邈诣袁术请救,为其众所杀,兖州平,遂东略陈地。" 130 | 131 | bert_dir = "./model_hub/chinese-bert-wwm-ext/" 132 | 133 | # 实体识别相关信息 134 | # ====================================== 135 | ner_path = "./pytorch_GlobalPointer_Ner/checkpoints/bert-1-eff/" 136 | with open(os.path.join(ner_path, "args.json"), "r", encoding="utf-8") as fp: 137 | ner_args = json.load(fp) 138 | ner_args = Dict2Class(ner_args) 139 | ner_args.bert_dir = bert_dir 140 | tokenizer = BertTokenizer.from_pretrained(ner_args.bert_dir) 141 | 142 | ner_model = GlobalPointerNer(ner_args) 143 | ner_model_path = os.path.join(ner_path, "model.pt") 144 | ner_model, device = load_model_and_parallel(ner_model, ner_args.gpu_ids, ner_model_path) 145 | ner_args.data_dir = "./pytorch_GlobalPointer_Ner/data/guwen/" 146 | ner_data_path = os.path.join(ner_args.data_dir, 'mid_data') 147 | label_list = read_json(ner_data_path, 'labels') 148 | ner_tag2id = {} 149 | ner_id2tag = {} 150 | for k, v in enumerate(label_list): 151 | ner_tag2id[v] = k 152 | ner_id2tag[k] = v 153 | # ====================================== 154 | 155 | # 关系抽取相关信息 156 | # ====================================== 157 | re_path = "./pytorch_GlobalPointer_triple_extraction/checkpoints/bert/" 158 | with open(os.path.join(re_path, "args.json"), "r", encoding="utf-8") as fp: 159 | re_args = json.load(fp) 160 | re_args = Dict2Class(re_args) 161 | re_args.bert_dir = bert_dir 162 | re_model = GlobalPointerRe(re_args) 163 | re_model_path = os.path.join(re_path, "model.pt") 164 | re_model, device = load_model_and_parallel(re_model, re_args.gpu_ids, re_model_path) 165 | re_args.data_dir = "./pytorch_GlobalPointer_triple_extraction/data/guwen/" 166 | label_list = read_json(os.path.join(re_args.data_dir, 'mid_data'), 'predicates') 167 | re_tag2id = {} 168 | re_id2tag = {} 169 | for k,v in enumerate(label_list): 170 | re_tag2id[v] = k 171 | re_id2tag[k] = v 172 | # ====================================== 173 | 174 | ner_predict(ner_args, text, ner_model, tokenizer, ner_id2tag, device) 175 | re_predict(re_args, text, re_model, tokenizer, re_id2tag, device) 176 | 177 | 178 | 179 | if __name__ == "__main__": 180 | main() 181 | 182 | -------------------------------------------------------------------------------- /model_hub/chinese-bert-wwm-ext/占位.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/model_hub/chinese-bert-wwm-ext/占位.txt -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/README.md: -------------------------------------------------------------------------------- 1 | # pytorch_GlobalPointer_Ner 2 | 3 | 延申: 4 | - 一种基于TPLinker_plus的命名实体识别:https://github.com/taishan1994/pytorch_TPLinker_Plus_Ner 5 | - 一种one vs rest方法进行命名实体识别:https://github.com/taishan1994/pytorch_OneVersusRest_Ner 6 | - 一种级联Bert用于命名实体识别,解决标签过多问题:https://github.com/taishan1994/pytorch_Cascade_Bert_Ner 7 | - 一种多头选择Bert用于命名实体识别:https://github.com/taishan1994/pytorch_Multi_Head_Selection_Ner 8 | - 中文命名实体识别最新进展:https://github.com/taishan1994/awesome-chinese-ner 9 | - 信息抽取三剑客:实体抽取、关系抽取、事件抽取:https://github.com/taishan1994/chinese_information_extraction 10 | - 一种基于机器阅读理解的命名实体识别:https://github.com/taishan1994/BERT_MRC_NER_chinese 11 | - W2NER:命名实体识别最新sota:https://github.com/taishan1994/W2NER_predict 12 | 13 | **** 14 | 15 | 基于pytorch的GlobalPointer进行中文命名实体识别。 16 | 17 | 模型分别来自于参考中的【1】【2】。这里还是按照之前命名实体识别的相关模板,具体模型的介绍及预备知识请移步参考里面的链接。复现方式: 18 | 19 | - 1、raw_data下新建一个process.py将原始数据处理为mid_data下的数据。 20 | - 2、根据参数运行main.py以进行训练、验证、测试和预测。 21 | 22 | 模型和数据下载地址:链接:https://pan.baidu.com/s/1Gh9UQESQmEXuzyyPUG_FgQ?pwd=1a6s 提取码:1a6s 23 | 24 | # 依赖 25 | 26 | ``` 27 | pytorch==1.6.0 28 | transformers==4.5.0 29 | seqeval 30 | ``` 31 | 32 | # 运行 33 | 34 | ```python 35 | !python main.py \ 36 | --bert_dir="model_hub/chinese-bert-wwm-ext/" \ 37 | --data_dir="./data/cner/" \ 38 | --log_dir="./logs/" \ 39 | --output_dir="./checkpoints/" \ 40 | --num_tags=8 \ 41 | --head_size=64 \ 42 | --seed=123 \ 43 | --gpu_ids="0" \ 44 | --max_seq_len=150 \ 45 | --lr=5e-5 \ 46 | --other_lr=5e-5 \ 47 | --train_batch_size=32 \ 48 | --train_epochs=7 \ 49 | --eval_steps=50 \ 50 | --eval_batch_size=8 \ 51 | --max_grad_norm=1 \ 52 | --warmup_proportion=0.1 \ 53 | --adam_epsilon=1e-8 \ 54 | --weight_decay=0.01 \ 55 | --dropout_prob=0.1 \ 56 | --use_tensorboard="True" \ 57 | --use_efficient_globalpointer="True" 58 | ``` 59 | 60 | ### 结果 61 | 62 | globalpoint2.py也是可以用的,要选择它需要将main.py导入修改为```import globalpoint2```,并在使用模型时改为```globalpoint2.GlobalPointerNer```,模型名字自己设置为bert-2,参数use_efficient_globalpointer没有作用,因为是针对globalpoint.py的。 63 | 64 | ```python 65 | precision:0.9559 recall:0.9565 micro_f1:0.9562 66 | precision recall f1-score support 67 | 68 | TITLE 0.96 0.96 0.96 762 69 | RACE 1.00 0.93 0.97 15 70 | CONT 1.00 1.00 1.00 33 71 | ORG 0.94 0.94 0.94 539 72 | NAME 0.99 1.00 1.00 110 73 | EDU 0.97 0.99 0.98 109 74 | PRO 0.82 1.00 0.90 18 75 | LOC 1.00 1.00 1.00 2 76 | 77 | micro-f1 0.96 0.96 0.96 1588 78 | 79 | 虞兔良先生:1963年12月出生,汉族,中国国籍,无境外永久居留权,浙江绍兴人,中共党员,MBA,经济师。 80 | Load ckpt from ./checkpoints/bert/model.pt 81 | Use single gpu in: ['0'] 82 | {'TITLE': [['中共党员', 41], ['经济师', 50]], 'RACE': [['汉族', 18]], 'CONT': [['中国国籍', 21]], 'NAME': [['虞兔良', 1]], 'EDU': [['MBA', 46]], 'LOC': [['浙江绍兴人', 35]]} 83 | ``` 84 | 85 | 默认使用的是globalpoint.py里面的模型,包含globalpointer和efficient-globalpoint,通过修改use_efficient_globalpointer来指定选择的模型,结果如下: 86 | 87 | ```python 88 | globalpointer: 89 | precision:0.9528 recall:0.9534 micro_f1:0.9531 90 | precision recall f1-score support 91 | 92 | TITLE 0.95 0.95 0.95 762 93 | RACE 1.00 0.93 0.97 15 94 | CONT 1.00 1.00 1.00 33 95 | ORG 0.94 0.94 0.94 539 96 | NAME 0.99 1.00 1.00 110 97 | EDU 0.96 0.98 0.97 109 98 | PRO 0.86 1.00 0.92 18 99 | LOC 1.00 1.00 1.00 2 100 | 101 | micro-f1 0.95 0.95 0.95 1588 102 | 103 | 虞兔良先生:1963年12月出生,汉族,中国国籍,无境外永久居留权,浙江绍兴人,中共党员,MBA,经济师。 104 | {'TITLE': [['中共党员', 41], ['经济师', 50]], 'RACE': [['汉族', 18]], 'CONT': [['中国国籍', 21]], 'NAME': [['虞兔良', 1]], 'EDU': [['MBA', 46]], 'LOC': [['浙江绍兴人', 35]]} 105 | 106 | efficient-globalpoint: 107 | precision:0.9616 recall:0.9616 micro_f1:0.9616 108 | precision recall f1-score support 109 | 110 | TITLE 0.97 0.96 0.97 762 111 | RACE 1.00 0.93 0.97 15 112 | CONT 1.00 1.00 1.00 33 113 | ORG 0.95 0.94 0.94 539 114 | NAME 0.99 1.00 1.00 110 115 | EDU 0.97 0.98 0.98 109 116 | PRO 0.90 1.00 0.95 18 117 | LOC 1.00 1.00 1.00 2 118 | 119 | micro-f1 0.96 0.96 0.96 1588 120 | 121 | 虞兔良先生:1963年12月出生,汉族,中国国籍,无境外永久居留权,浙江绍兴人,中共党员,MBA,经济师。 122 | {'TITLE': [['中共党员', 41], ['经济师', 50]], 'RACE': [['汉族', 18]], 'CONT': [['中国国籍', 21]], 'NAME': [['虞兔良', 1]], 'EDU': [['MBA', 46]], 'LOC': [['浙江绍兴人', 35]]} 123 | ``` 124 | 125 | ### 补充 126 | 127 | 如果效果不好,尝试调小一些学习率。 128 | 129 | # 参考 130 | 131 | >[1]https://github.com/gaohongkui/GlobalPointer_pytorch 132 | > 133 | >[2]https://github.com/Tongjilibo/bert4torch/ 134 | > 135 | >[3][将“softmax+交叉熵”推广到多标签分类问题 - 科学空间|Scientific Spaces (kexue.fm)](https://kexue.fm/archives/7359) 136 | > 137 | >[4][Transformer升级之路:2、博采众长的旋转式位置编码 - 科学空间|Scientific Spaces (kexue.fm)](https://kexue.fm/archives/8265) 138 | > 139 | >[5][GlobalPointer:用统一的方式处理嵌套和非嵌套NER - 科学空间|Scientific Spaces (kexue.fm)](https://kexue.fm/archives/8373) 140 | > 141 | >[6][Efficient GlobalPointer:少点参数,多点效果 - 科学空间|Scientific Spaces (kexue.fm)](https://kexue.fm/archives/8877) 142 | 143 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/checkpoints/bert-1-eff/args.json: -------------------------------------------------------------------------------- 1 | {"output_dir": "./checkpoints/", "bert_dir": "../model_hub/chinese-bert-wwm-ext/", "data_dir": "./data/guwen/", "log_dir": "./logs/", "num_tags": 6, "head_size": 64, "seed": 123, "gpu_ids": "0", "max_seq_len": 256, "eval_batch_size": 16, "eval_steps": 100, "train_epochs": 10, "dropout_prob": 0.3, "lr": 5e-05, "other_lr": 5e-05, "max_grad_norm": 1.0, "warmup_proportion": 0.1, "weight_decay": 0.01, "adam_epsilon": 1e-08, "train_batch_size": 16, "use_tensorboard": "False", "use_efficient_globalpointer": "True"} -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/checkpoints/占位.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_Ner/checkpoints/占位.txt -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/config.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | 4 | class Args: 5 | @staticmethod 6 | def parse(): 7 | parser = argparse.ArgumentParser() 8 | return parser 9 | 10 | @staticmethod 11 | def initialize(parser): 12 | # args for path 13 | parser.add_argument('--output_dir', default='./checkpoints/', 14 | help='the output dir for model checkpoints') 15 | 16 | parser.add_argument('--bert_dir', default='../model_hub/bert-base-chinese/', 17 | help='bert dir for uer') 18 | parser.add_argument('--data_dir', default='./data/cner/', 19 | help='data dir for uer') 20 | parser.add_argument('--log_dir', default='./logs/', 21 | help='log dir for uer') 22 | 23 | # other args 24 | parser.add_argument('--num_tags', default=53, type=int, 25 | help='number of tags') 26 | parser.add_argument('--head_size', default=64, type=int, 27 | help='') 28 | parser.add_argument('--seed', type=int, default=123, help='random seed') 29 | 30 | parser.add_argument('--gpu_ids', type=str, default='0', 31 | help='gpu ids to use, -1 for cpu, "0,1" for multi gpu') 32 | 33 | parser.add_argument('--max_seq_len', default=256, type=int) 34 | 35 | parser.add_argument('--eval_batch_size', default=12, type=int) 36 | parser.add_argument('--eval_steps', default=100, type=int, 37 | help='多少步验证一次') 38 | 39 | # train args 40 | parser.add_argument('--train_epochs', default=15, type=int, 41 | help='Max training epoch') 42 | 43 | parser.add_argument('--dropout_prob', default=0.1, type=float, 44 | help='drop out probability') 45 | 46 | # 2e-5 47 | parser.add_argument('--lr', default=3e-5, type=float, 48 | help='bert学习率') 49 | # 2e-3 50 | parser.add_argument('--other_lr', default=3e-4, type=float, 51 | help='bilstm和多层感知机学习率') 52 | # 0.5 53 | parser.add_argument('--max_grad_norm', default=1, type=float, 54 | help='max grad clip') 55 | 56 | parser.add_argument('--warmup_proportion', default=0.1, type=float) 57 | 58 | parser.add_argument('--weight_decay', default=0.01, type=float) 59 | 60 | parser.add_argument('--adam_epsilon', default=1e-8, type=float) 61 | 62 | parser.add_argument('--train_batch_size', default=32, type=int) 63 | parser.add_argument('--use_tensorboard', default="True") 64 | parser.add_argument('--use_efficient_globalpointer', default="True") 65 | 66 | 67 | 68 | return parser 69 | 70 | def get_parser(self): 71 | parser = self.parse() 72 | parser = self.initialize(parser) 73 | return parser.parse_args() -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/data/cner/mid_data/labels.json: -------------------------------------------------------------------------------- 1 | ["TITLE", "RACE", "CONT", "ORG", "NAME", "EDU", "PRO", "LOC"] -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/data/cner/raw_data/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_Ner/data/cner/raw_data/__init__.py -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/data/cner/raw_data/process.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import json 4 | 5 | def preprocess(input_path, save_path, mode): 6 | if not os.path.exists(save_path): 7 | os.makedirs(save_path) 8 | data_path = os.path.join(save_path, mode + ".json") 9 | labels = set() 10 | result = [] 11 | tmp = {} 12 | tmp['id'] = 0 13 | tmp['text'] = '' 14 | tmp['labels'] = [] 15 | # =======先找出句子和句子中的所有实体和类型======= 16 | with open(input_path,'r',encoding='utf-8') as fp: 17 | lines = fp.readlines() 18 | texts = [] 19 | entities = [] 20 | words = [] 21 | entity_tmp = [] 22 | entities_tmp = [] 23 | for line in lines: 24 | line = line.strip().split(" ") 25 | if len(line) == 2: 26 | word = line[0] 27 | label = line[1] 28 | words.append(word) 29 | 30 | if "B-" in label: 31 | entity_tmp.append(word) 32 | elif "M-" in label: 33 | entity_tmp.append(word) 34 | elif "E-" in label: 35 | entity_tmp.append(word) 36 | if ("".join(entity_tmp), label.split("-")[-1]) not in entities_tmp: 37 | entities_tmp.append(("".join(entity_tmp), label.split("-")[-1])) 38 | labels.add(label.split("-")[-1]) 39 | entity_tmp = [] 40 | 41 | if "S-" in label: 42 | entity_tmp.append(word) 43 | if ("".join(entity_tmp), label.split("-")[-1]) not in entities_tmp: 44 | entities_tmp.append(("".join(entity_tmp), label.split("-")[-1])) 45 | entity_tmp = [] 46 | labels.add(label.split("-")[-1]) 47 | else: 48 | texts.append("".join(words)) 49 | entities.append(entities_tmp) 50 | words = [] 51 | entities_tmp = [] 52 | 53 | # for text,entity in zip(texts, entities): 54 | # print(text, entity) 55 | # print(labels) 56 | # ========================================== 57 | # =======找出句子中实体的位置======= 58 | i = 0 59 | for text,entity in zip(texts, entities): 60 | 61 | if entity: 62 | ltmp = [] 63 | for ent,type in entity: 64 | for span in re.finditer(ent, text): 65 | start = span.start() 66 | end = span.end() 67 | ltmp.append((type, start, end, ent)) 68 | # print(ltmp) 69 | ltmp = sorted(ltmp, key=lambda x:(x[1],x[2])) 70 | tmp['id'] = i 71 | tmp['text'] = text 72 | for j in range(len(ltmp)): 73 | tmp['labels'].append(["T{}".format(str(j)), ltmp[j][0], ltmp[j][1], ltmp[j][2], ltmp[j][3]]) 74 | else: 75 | tmp['id'] = i 76 | tmp['text'] = text 77 | tmp['labels'] = [] 78 | result.append(tmp) 79 | # print(i, text, entity, tmp) 80 | tmp = {} 81 | tmp['id'] = 0 82 | tmp['text'] = '' 83 | tmp['labels'] = [] 84 | i += 1 85 | 86 | with open(data_path,'w', encoding='utf-8') as fp: 87 | fp.write(json.dumps(result, ensure_ascii=False)) 88 | 89 | if mode == "train": 90 | label_path = os.path.join(save_path, "labels.json") 91 | with open(label_path, 'w', encoding='utf-8') as fp: 92 | fp.write(json.dumps(list(labels), ensure_ascii=False)) 93 | 94 | preprocess("train.char.bmes", '../mid_data', "train") 95 | preprocess("dev.char.bmes", '../mid_data', "dev") 96 | preprocess("test.char.bmes", '../mid_data', "test") 97 | 98 | labels_path = os.path.join('../mid_data/labels.json') 99 | with open(labels_path, 'r') as fp: 100 | labels = json.load(fp) 101 | 102 | # tmp_labels = [] 103 | # tmp_labels.append('O') 104 | # tmp_labels.append('B') 105 | # tmp_labels.append('I') 106 | 107 | 108 | # label2id = {} 109 | # for k,v in enumerate(tmp_labels): 110 | # label2id[v] = k 111 | # path = '../mid_data/' 112 | # if not os.path.exists(path): 113 | # os.makedirs(path) 114 | # with open(os.path.join(path, "nor_ent2id.json"),'w') as fp: 115 | # fp.write(json.dumps(label2id, ensure_ascii=False)) 116 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/data/guwen/mid_data/labels.json: -------------------------------------------------------------------------------- 1 | ["BOO", "WAR", "JOB", "LOC", "ORG", "PER"] -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/data/guwen/raw_data/dev.txt: -------------------------------------------------------------------------------- 1 | 又 檄 梁 朝 , 令 送 侯 景 , 初 夜 执 笔 , 三 更 便 成 , 文 过 七 纸 。 文 襄 善 之 。 魏 帝 曾 季 秋 大 射 , 普 令 赋 诗 , 收 诗 末 云 “ 尺 书 征 建 邺 , 折 简 召 长 安 ” 文 襄 壮 之 , 顾 诸 人 曰 “ 在 朝 今 有 魏 收 , 便 是 国 之 光 采 。 雅 俗 文 墨 , 通 达 纵 横 , 我 亦 使 子 才 、 子 升 时 有 所 作 , 至 於 词 气 , 并 不 及 之 。 2 | 吾 或 意 有 所 怀 , 忘 而 不 语 , 语 而 不 尽 , 意 有 未 及 , 收 呈 草 皆 以 周 悉 , 此 亦 难 有 ” 又 敕 兼 主 客 郎 , 接 梁 使 谢 珽 、 徐 陵 。 3 | 侯 景 既 陷 梁 , 梁 鄱 阳 王 范 时 为 合 州 刺 史 , 文 襄 敕 收 以 书 喻 之 。 范 得 书 , 仍 率 部 伍 西 上 , 刺 史 崔 圣 念 入 据 其 城 。 文 襄 崩 , 文 宣 如 晋 阳 , 令 与 黄 门 郎 崔 季 舒 、 高 德 正 、 吏 部 郎 中 尉 瑾 於 北 第 掌 机 密 。 转 秘 书 监 , 兼 著 作 郎 , 又 除 定 州 大 中 正 。 4 | 时 齐 将 受 禅 , 杨 愔 奏 收 置 之 别 馆 , 令 撰 禅 代 诏 册 诸 文 , 遣 徐 之 才 守 门 不 听 出 。 天 保 元 年 , 除 中 书 令 , 仍 兼 著 作 郎 , 封 富 平 县 子 。 二 年 , 诏 撰 魏 史 。 四 年 , 除 魏 尹 , 故 优 以 禄 力 , 专 在 史 阁 , 不 知 郡 事 。 初 , 帝 令 群 臣 各 言 尔 志 , 收 曰 “ 臣 愿 得 直 笔 东 观 , 早 成 《 魏 书 》 ” 故 帝 使 收 专 其 任 。 5 | 又 诏 平 原 王 高 隆 之 总 监 之 , 署 名 而 已 。 帝 敕 收 曰 “ 好 直 笔 , 我 终 不 作 魏 太 武 诛 史 官 ” 始 魏 初 邓 彦 海 撰 《 代 记 》 十 馀 卷 , 其 后 崔 浩 典 史 , 游 雅 、 高 允 、 程 骏 、 李 彪 、 崔 光 、 李 琰 之 徒 世 修 其 业 。 6 | 浩 为 编 年 体 , 彪 始 分 作 纪 、 表 、 志 、 传 , 书 犹 未 出 。 宣 武 时 , 命 邢 峦 追 撰 《 孝 文 起 居 注 》 , 书 至 太 和 十 四 年 , 又 命 崔 鸿 、 王 遵 业 补 续 焉 。 下 讫 孝 明 , 事 甚 委 悉 。 济 阴 王 晖 业 撰 《 辨 宗 室 录 》 三 十 卷 。 7 | 收 於 是 与 通 直 常 侍 房 延 祐 、 司 空 司 马 辛 元 植 、 国 子 博 士 刁 柔 、 裴 昂 之 、 尚 书 郎 高 孝 干 专 总 斟 酌 , 以 成 《 魏 书 》 。 8 | 辨 定 名 称 , 随 条 甄 举 , 又 搜 采 亡 遗 , 缀 续 后 事 , 备 一 代 史 籍 , 表 而 上 闻 之 。 勒 成 一 代 大 典 : 凡 十 二 纪 , 九 十 二 列 传 , 合 一 百 一 十 卷 。 9 | 五 年 三 月 奏 上 之 。 秋 , 除 梁 州 刺 史 。 收 以 志 未 成 , 奏 请 终 业 , 许 之 。 十 一 月 , 复 奏 十 志 : 《 天 象 》 四 卷 , 《 地 形 》 三 卷 , 《 律 历 》 二 卷 , 《 礼 乐 》 四 卷 , 《 食 货 》 一 卷 , 《 刑 罚 》 一 卷 , 《 灵 徵 》 二 卷 , 《 官 氏 》 二 卷 , 《 释 老 》 一 卷 , 凡 二 十 卷 , 续 於 纪 传 , 合 一 百 三 十 卷 , 分 为 十 二 帙 。 10 | 其 史 三 十 五 例 , 二 十 五 序 , 九 十 四 论 , 前 后 二 表 一 启 焉 。 所 引 史 官 , 恐 其 凌 逼 , 唯 取 学 流 先 相 依 附 者 。 11 | 房 延 祐 、 辛 元 植 、 眭 仲 让 虽 夙 涉 朝 位 , 并 非 史 才 。 刁 柔 、 裴 昂 之 以 儒 业 见 知 , 全 不 堪 编 缉 。 高 孝 干 以 左 道 求 进 。 修 史 诸 人 祖 宗 姻 戚 多 被 书 录 , 饰 以 美 言 。 收 性 颇 急 , 不 甚 能 平 , 夙 有 怨 者 , 多 没 其 善 。 每 言 “ 何 物 小 子 , 敢 共 魏 收 作 色 。 12 | 举 之 则 使 上 天 , 按 之 当 使 入 地 ” 初 , 收 在 神 武 时 为 太 常 少 卿 , 修 国 史 , 得 阳 休 之 助 , 因 谢 休 之 曰 “ 无 以 谢 德 , 当 为 卿 作 佳 传 ” 休 之 父 固 , 魏 世 为 北 平 太 守 , 以 贪 虐 为 中 尉 李 平 所 弹 获 罪 , 载 在 《 魏 起 居 注 》 。 13 | 时 论 既 言 收 著 史 不 平 , 文 宣 诏 收 於 尚 书 省 与 诸 家 子 孙 共 加 论 讨 , 前 后 投 诉 百 有 馀 人 , 云 “ 遗 其 家 世 职 位 ” , 或 云 “ 其 家 不 见 记 录 ” , 或 云 “ 妄 有 非 毁 ” 。 收 皆 随 状 答 之 。 范 阳 卢 斐 父 同 附 出 族 祖 玄 传 下 , 顿 丘 李 庶 家 传 称 其 本 是 梁 国 蒙 人 , 斐 、 庶 讥 议 云 “ 史 书 不 直 ” 。 14 | 收 性 急 , 不 胜 其 愤 , 启 诬 其 欲 加 屠 害 。 帝 大 怒 , 亲 自 诘 责 。 斐 曰 “ 臣 父 仕 魏 , 位 至 仪 同 , 功 业 显 著 , 名 闻 天 下 , 与 收 无 亲 , 遂 不 立 传 。 15 | 博 陵 崔 绰 , 位 止 本 郡 功 曹 , 更 无 事 迹 , 是 收 外 亲 , 乃 为 《 传 》 首 ” 收 曰 “ 绰 虽 无 位 , 名 义 可 嘉 , 所 以 合 传 ” 帝 曰 “ 卿 何 由 知 其 好 人 ” 收 曰 “ 高 允 曾 为 绰 赞 , 称 有 道 德 ” 帝 曰 “ 司 空 才 士 , 为 人 作 赞 , 正 应 称 扬 。 亦 如 卿 为 人 作 文 章 , 道 其 好 者 岂 能 皆 实 ” 收 无 以 对 , 战 栗 而 已 。 16 | 但 帝 先 重 收 才 , 不 欲 加 罪 。 时 太 原 王 松 年 亦 谤 史 , 及 斐 、 庶 并 获 罪 , 各 被 鞭 配 甲 坊 , 或 因 以 致 死 , 卢 思 道 亦 抵 罪 。 17 | 然 犹 以 群 口 沸 腾 , 敕 魏 史 且 勿 施 行 , 令 群 官 博 议 , 听 有 家 事 者 入 署 , 不 实 者 陈 牒 。 於 是 众 口 喧 然 , 号 为 “ 秽 史 ” , 投 牒 者 相 次 , 收 无 以 抗 之 。 18 | 时 左 仆 射 杨 愔 、 右 仆 射 高 德 正 二 人 势 倾 朝 野 , 与 收 皆 亲 , 收 遂 为 其 家 并 作 传 。 二 人 不 欲 言 史 不 实 , 抑 塞 诉 辞 , 终 文 宣 世 更 不 重 论 。 又 尚 书 陆 操 尝 谓 愔 曰 “ 魏 收 《 魏 书 》 可 谓 博 物 宏 才 , 有 大 功 於 魏 室 ” 愔 谓 收 曰 “ 此 谓 不 刊 之 书 , 传 之 万 古 。 19 | 但 恨 论 及 诸 家 枝 叶 亲 姻 , 过 为 繁 碎 , 与 旧 史 体 例 不 同 耳 ” 收 曰 “ 往 因 中 原 丧 乱 , 人 士 谱 牒 , 遗 逸 略 尽 , 是 以 具 书 其 支 流 。 20 | 八 年 夏 , 除 太 子 少 傅 、 监 国 史 , 复 参 议 律 令 。 三 台 成 , 文 宣 曰 “ 台 成 须 有 赋 ” 愔 先 以 告 收 , 收 上 《 皇 居 新 殿 台 赋 》 , 其 文 甚 壮 丽 。 21 | 时 所 作 者 , 自 邢 邵 已 下 咸 不 逮 焉 。 收 上 赋 前 数 日 乃 告 邵 。 邵 后 告 人 曰 “ 收 甚 恶 人 , 不 早 言 之 ” 帝 曾 游 东 山 , 敕 收 作 诏 , 宣 扬 威 德 , 譬 喻 关 西 , 俄 顷 而 讫 , 词 理 宏 壮 。 帝 对 百 僚 大 嗟 赏 之 。 仍 兼 太 子 詹 事 。 收 娶 其 舅 女 , 崔 昂 之 妹 , 产 一 女 , 无 子 。 22 | 魏 太 常 刘 芳 孙 女 , 中 书 郎 崔 肇 师 女 , 夫 家 坐 事 , 帝 并 赐 收 为 妻 , 时 人 比 之 贾 充 置 左 右 夫 人 。 然 无 子 。 后 病 甚 , 恐 身 后 嫡 媵 不 平 , 乃 放 二 姬 。 及 疾 瘳 追 忆 , 作 《 怀 离 赋 》 以 申 意 。 文 宣 每 以 酣 宴 之 次 , 云 “ 太 子 性 懦 , 宗 社 事 重 , 终 当 传 位 常 山 ” 收 谓 杨 愔 曰 “ 古 人 云 , 太 子 国 之 根 本 , 不 可 动 摇 。 23 | 至 尊 三 爵 后 , 每 言 传 位 常 山 , 令 臣 下 疑 贰 。 若 实 , 便 须 决 行 。 此 言 非 戏 , 魏 收 既 忝 师 傅 , 正 当 守 之 以 死 , 但 恐 国 家 不 安 ” 愔 以 收 言 白 於 帝 , 自 此 便 止 。 帝 数 宴 喜 , 收 每 预 侍 从 。 24 | 皇 太 子 之 纳 郑 良 娣 也 , 有 司 备 设 牢 馔 , 帝 既 酣 饮 , 起 而 自 毁 覆 之 。 仍 诏 收 曰 “ 知 我 意 不 ” 收 曰 “ 臣 愚 谓 良 娣 既 东 宫 之 妾 , 理 不 须 牢 , 仰 惟 圣 怀 , 缘 此 毁 去 ” 帝 大 笑 , 握 收 手 曰 “ 卿 知 我 意 ” 安 德 王 延 宗 纳 赵 郡 李 祖 收 女 为 妃 , 后 帝 幸 李 宅 宴 , 而 妃 母 宋 氏 荐 二 石 榴 於 帝 前 。 25 | 问 诸 人 莫 知 其 意 , 帝 投 之 。 收 曰 “ 石 榴 房 中 多 子 , 王 新 婚 , 妃 母 欲 子 孙 众 多 ” 帝 大 喜 , 诏 收 “ 卿 还 将 来 ” , 仍 赐 收 美 锦 二 匹 。 十 年 , 除 仪 同 三 司 。 帝 在 宴 席 , 口 敕 以 为 中 书 监 , 命 中 书 郎 李 愔 於 树 下 造 诏 。 愔 以 收 一 代 盛 才 , 难 於 率 尔 , 久 而 未 讫 。 26 | 比 成 , 帝 已 醉 醒 , 遂 不 重 言 , 愔 仍 不 奏 , 事 竟 寝 。 及 帝 崩 於 晋 阳 , 驿 召 收 及 中 山 太 守 阳 休 之 参 议 吉 凶 之 礼 , 并 掌 诏 诰 。 仍 除 侍 中 , 迁 太 常 卿 。 文 宣 谥 及 庙 号 、 陵 名 , 皆 收 议 也 。 及 孝 昭 居 中 宰 事 , 命 收 禁 中 为 诸 诏 文 , 积 日 不 出 。 转 中 书 监 。 皇 建 元 年 , 除 兼 侍 中 、 右 光 禄 大 夫 , 仍 仪 同 、 监 史 。 27 | 收 先 副 王 昕 使 梁 , 不 相 协 睦 。 时 昕 弟 晞 亲 密 。 而 孝 昭 别 令 阳 休 之 兼 中 书 , 在 晋 阳 典 诏 诰 , 收 留 在 邺 。 28 | 盖 晞 所 为 , 收 大 不 平 , 谓 太 子 舍 人 卢 询 祖 曰 “ 若 使 卿 作 文 诰 , 我 亦 不 言 ” 又 除 祖 珽 为 著 作 郎 , 欲 以 代 收 。 29 | 司 空 主 簿 李 翥 , 文 词 士 也 , 闻 而 告 人 曰 “ 诏 诰 悉 归 阳 子 烈 , 著 作 复 遣 祖 孝 徵 , 文 史 顿 失 , 恐 魏 公 发 背 ” 於 时 诏 议 二 王 三 恪 , 收 执 王 肃 、 杜 预 义 , 以 元 、 司 马 氏 为 二 王 , 通 曹 备 三 恪 。 诏 诸 礼 学 之 官 , 皆 执 郑 玄 五 代 之 议 。 30 | 孝 昭 后 姓 元 , 议 恪 不 欲 广 及 , 故 议 从 收 。 又 除 兼 太 子 少 傅 , 解 侍 中 。 帝 以 魏 史 未 行 , 诏 收 更 加 研 审 。 收 奉 诏 , 颇 有 改 正 。 31 | 及 诏 行 魏 史 , 收 以 为 直 置 秘 阁 , 外 人 无 由 得 见 , 於 是 命 送 一 本 付 并 省 , 一 本 付 邺 下 , 任 人 写 之 。 大 宁 元 年 , 加 开 府 。 河 清 二 年 , 兼 右 仆 射 。 32 | 时 武 成 酣 饮 终 日 , 朝 事 专 委 侍 中 高 元 海 。 元 海 凡 庸 , 不 堪 大 任 , 以 收 才 名 振 俗 , 都 官 尚 书 毕 义 云 长 於 断 割 , 乃 虚 心 倚 仗 。 收 畏 避 不 能 匡 救 , 为 议 者 所 讥 。 帝 於 华 林 别 起 玄 洲 苑 , 备 山 水 台 观 之 丽 , 诏 於 阁 上 画 收 , 其 见 重 如 此 。 33 | 始 收 比 温 子 升 、 邢 邵 稍 为 后 进 , 邵 既 被 疏 出 , 子 升 以 罪 幽 死 , 收 遂 大 被 任 用 , 独 步 一 时 。 议 论 更 相 訾 毁 , 各 有 朋 党 。 收 每 议 陋 邢 邵 文 。 邵 又 云 “ 江 南 任 昉 , 文 体 本 疏 , 魏 收 非 直 模 拟 , 亦 大 偷 窃 ” 收 闻 乃 曰 “ 伊 常 於 《 沈 约 集 》 中 作 贼 , 何 意 道 我 偷 任 昉 ” 任 、 沈 俱 有 重 名 , 邢 、 魏 各 有 所 好 。 34 | 武 平 中 , 黄 门 郎 颜 之 推 以 二 公 意 问 仆 射 祖 珽 , 珽 答 曰 “ 见 邢 、 魏 之 臧 否 , 即 是 任 、 沈 之 优 劣 ” 收 以 温 子 升 全 不 作 赋 , 邢 虽 有 一 两 首 , 又 非 所 长 , 常 云 “ 会 须 作 赋 , 始 成 大 才 士 。 唯 以 章 表 碑 志 自 许 , 此 外 更 同 儿 戏 ” 自 武 定 二 年 已 后 , 国 家 大 事 诏 命 , 军 国 文 词 , 皆 收 所 作 。 35 | 每 有 警 急 , 受 诏 立 成 , 或 时 中 使 催 促 , 收 笔 下 有 同 宿 构 , 敏 速 之 工 , 邢 、 温 所 不 逮 , 其 参 议 典 礼 , 与 邢 相 埒 。 36 | 既 而 赵 郡 公 增 年 获 免 , 收 知 而 过 之 , 事 发 除 名 。 其 年 又 以 托 附 陈 使 封 孝 琰 , 牒 令 其 门 客 与 行 , 遇 昆 仑 舶 至 , 得 奇 货 猓 然 褥 表 、 美 玉 盈 尺 等 数 十 件 , 罪 当 流 , 以 赎 论 。 三 年 , 起 除 清 都 尹 。 寻 遣 黄 门 郎 元 文 遥 敕 收 曰 “ 卿 旧 人 , 事 我 家 最 久 , 前 者 之 罪 , 情 在 可 恕 。 37 | 比 令 卿 为 尹 , 非 谓 美 授 , 但 初 起 卿 , 斟 酌 如 此 。 朕 岂 可 用 卿 之 才 而 忘 卿 身 , 待 至 十 月 , 当 还 卿 开 府 ” 天 统 元 年 , 除 左 光 禄 大 夫 。 二 年 , 行 齐 州 刺 史 , 寻 为 真 。 吾 曾 览 管 子 之 书 , 其 言 曰 “ 任 之 重 者 莫 如 身 , 途 之 畏 者 莫 如 口 , 期 之 远 者 莫 如 年 。 38 | 以 重 任 行 畏 途 , 至 远 期 , 惟 君 子 为 能 及 矣 ” 追 而 味 之 , 喟 然 长 息 。 若 夫 岳 立 为 重 , 有 潜 戴 而 不 倾 。 山 藏 称 固 , 亦 趋 负 而 弗 停 。 吕 梁 独 浚 , 能 行 歌 而 匪 惕 。 焦 原 作 险 , 或 跻 踵 而 不 惊 。 九 陔 方 集 , 故 眇 然 而 迅 举 。 五 纪 当 定 , 想 窅 乎 而 上 征 。 苟 任 重 也 有 度 , 则 任 之 而 愈 固 。 39 | 乘 危 也 有 术 , 盖 乘 之 而 靡 恤 。 彼 期 远 而 能 通 , 果 应 之 而 可 必 。 岂 神 理 之 独 尔 , 亦 人 事 其 如 一 。 呜 呼 。 处 天 壤 之 间 , 劳 死 生 之 地 , 攻 之 以 嗜 欲 , 牵 之 以 名 利 , 粱 肉 不 期 而 共 臻 , 珠 玉 无 足 而 俱 致 。 40 | 於 是 乎 骄 奢 仍 作 , 危 亡 旋 至 。 然 则 上 知 大 贤 , 唯 几 唯 哲 , 或 出 或 处 , 不 常 其 节 。 其 舒 也 济 世 成 务 , 其 卷 也 声 销 迹 灭 。 41 | 玉 帛 子 女 , 椒 兰 律 吕 , 谄 谀 无 所 先 。 称 肉 度 骨 , 膏 唇 挑 舌 , 怨 恶 莫 之 前 。 勋 名 共 山 河 同 久 , 志 业 与 金 石 比 坚 。 斯 盖 厚 栋 不 桡 , 游 刃 砉 然 。 逮 於 厥 德 不 常 , 丧 其 金 璞 。 驰 骛 人 世 , 鼓 动 流 俗 。 挟 汤 日 而 谓 寒 , 包 溪 壑 而 未 足 。 源 不 清 而 流 浊 , 表 不 端 而 影 曲 。 嗟 乎 。 胶 漆 讵 坚 , 寒 暑 甚 促 。 42 | 反 利 而 成 害 , 化 荣 而 就 辱 。 欣 戚 更 来 , 得 丧 仍 续 。 至 有 身 御 魑 魅 , 魂 沉 狴 狱 。 讵 非 足 力 不 强 , 迷 在 当 局 。 孰 可 谓 车 戒 前 倾 , 人 师 先 觉 。 闻 诸 君 子 , 雅 道 之 士 , 游 遨 经 术 , 厌 饫 文 史 。 笔 有 奇 锋 , 谈 有 胜 理 。 43 | 孝 悌 之 至 , 神 明 通 矣 。 审 道 而 行 , 量 路 而 止 。 自 我 及 物 , 先 人 后 己 。 情 无 系 於 荣 悴 , 心 靡 滞 於 愠 喜 。 不 养 望 於 丘 壑 , 不 待 价 於 城 市 。 44 | 言 行 相 顾 , 慎 终 犹 始 。 有 一 於 斯 , 郁 为 羽 仪 。 恪 居 展 事 , 知 无 不 为 。 或 左 或 右 , 则 髦 士 攸 宜 。 无 悔 无 吝 , 故 高 而 不 危 。 异 乎 勇 进 忘 退 , 苟 得 患 失 , 射 千 金 之 产 , 邀 万 钟 之 秩 , 投 烈 风 之 门 , 趣 炎 火 之 室 , 载 蹶 而 坠 其 贻 宴 , 或 蹲 乃 丧 其 贞 吉 。 可 不 畏 欤 。 可 不 戒 欤 。 门 有 倚 祸 , 事 不 可 不 密 。 45 | 墙 有 伏 寇 , 言 不 可 而 失 。 宜 谛 其 言 , 宜 端 其 行 。 言 之 不 善 , 行 之 不 正 , 鬼 执 强 梁 , 人 囚 径 廷 。 幽 夺 其 魄 , 明 夭 其 命 。 不 服 非 法 , 不 行 非 道 。 46 | 公 鼎 为 己 信 , 私 玉 非 身 宝 。 过 涅 为 绀 , 逾 蓝 作 青 。 持 绳 视 直 , 置 水 观 平 。 时 然 后 取 , 未 若 无 欲 。 知 止 知 足 , 庶 免 於 辱 。 是 以 为 必 察 其 几 , 举 必 慎 於 微 。 知 几 虑 微 , 斯 亡 则 稀 。 既 察 且 慎 , 福 禄 攸 归 。 47 | 昔 蘧 瑗 识 四 十 九 非 , 颜 子 几 三 月 不 违 。 跬 步 无 已 , 至 於 千 里 。 覆 一 篑 进 , 及 於 万 仞 。 故 云 行 远 自 迩 , 登 高 自 卑 , 可 大 可 久 , 与 世 推 移 。 月 满 如 规 , 后 夜 则 亏 。 槿 荣 於 枝 , 望 暮 而 萎 。 夫 奚 益 而 非 损 , 孰 有 损 而 不 害 。 48 | 益 不 欲 多 , 利 不 欲 大 。 唯 居 德 者 畏 其 甚 , 体 真 者 惧 其 大 。 道 尊 则 群 谤 集 , 任 重 而 众 怨 会 。 其 达 也 则 尼 父 栖 遑 , 其 忠 也 而 周 公 狼 狈 。 49 | 无 曰 人 之 我 狭 , 在 我 不 可 而 覆 。 无 曰 人 之 我 厚 , 在 我 不 可 而 咎 。 如 山 之 大 , 无 不 有 也 。 如 谷 之 虚 , 无 不 受 也 。 能 刚 能 柔 , 重 可 负 也 。 能 信 能 顺 , 险 可 走 也 。 能 知 能 愚 , 期 可 久 也 。 周 庙 之 人 , 三 缄 其 口 。 漏 卮 在 前 , 欹 器 留 后 。 俾 诸 来 裔 , 传 之 坐 右 。 50 | 其 后 群 臣 多 言 魏 史 不 实 , 武 成 复 敕 更 审 , 收 又 回 换 。 遂 为 卢 同 立 传 , 崔 绰 返 更 附 出 。 杨 愔 家 传 , 本 云 “ 有 魏 以 来 一 门 而 已 ” , 至 是 改 此 八 字 。 51 | 又 先 云 “ 弘 农 华 阴 人 ” , 乃 改 “ 自 云 弘 农 ” 以 配 王 慧 龙 自 云 太 原 人 。 此 其 失 也 。 寻 除 开 府 、 中 书 监 。 武 成 崩 , 未 发 丧 。 在 内 诸 公 以 后 主 即 位 有 年 , 疑 於 赦 令 。 诸 公 引 收 访 焉 , 收 固 执 宜 有 恩 泽 , 乃 从 之 。 掌 诏 诰 , 除 尚 书 右 仆 射 , 总 议 监 五 礼 事 , 位 特 进 。 收 奏 请 赵 彦 深 、 和 士 开 、 徐 之 才 共 监 。 52 | 先 以 告 士 开 , 士 开 惊 辞 以 不 学 。 收 曰 “ 天 下 事 皆 由 王 , 五 礼 非 王 不 决 ” 士 开 谢 而 许 之 。 多 引 文 士 令 执 笔 , 儒 者 马 敬 德 、 熊 安 生 、 权 会 实 主 之 。 武 平 三 年 薨 。 赠 司 空 、 尚 书 左 仆 射 , 谥 文 贞 。 有 集 七 十 卷 。 53 | 收 硕 学 大 才 , 然 性 褊 , 不 能 达 命 体 道 。 见 当 途 贵 游 , 每 以 言 色 相 悦 。 然 提 奖 后 辈 , 以 名 行 为 先 , 浮 华 轻 险 之 徒 , 虽 有 才 能 , 弗 重 也 。 54 | 初 , 河 间 邢 子 才 及 季 景 与 收 并 以 文 章 显 , 世 称 大 邢 小 魏 , 言 尤 俊 也 。 收 少 子 才 十 岁 , 子 才 每 曰 “ 佛 助 寮 人 之 伟 ” 后 收 稍 与 子 才 争 名 , 文 宣 贬 子 才 曰 “ 尔 才 不 及 魏 收 ” 收 益 得 志 。 55 | 自 序 云 “ 先 称 温 、 邢 , 后 曰 邢 、 魏 ” 然 收 内 陋 邢 , 心 不 许 也 。 收 既 轻 疾 , 好 声 乐 , 善 胡 舞 。 文 宣 末 , 数 於 东 山 与 诸 优 为 猕 猴 与 狗 斗 , 帝 宠 狎 之 。 56 | 收 外 兄 博 陵 崔 岩 尝 以 双 声 嘲 收 曰 “ 愚 魏 衰 收 ” 收 答 曰 “ 颜 岩 腥 瘦 , 是 谁 所 生 , 羊 颐 狗 颊 , 头 团 鼻 平 , 饭 房 笭 笼 , 著 孔 嘲 玎 ” 其 辩 捷 不 拘 若 是 。 既 缘 史 笔 , 多 憾 於 人 。 齐 亡 之 岁 , 收 冢 被 发 , 弃 其 骨 於 外 。 先 养 弟 子 仁 表 为 嗣 , 位 至 尚 书 膳 部 郎 中 。 隋 开 皇 中 , 卒 於 温 县 令 。 57 | 卷 三 十 八 · 列 传 第 三 十 辛 术 , 字 怀 哲 , 少 明 敏 , 有 识 度 。 解 褐 司 空 胄 曹 参 军 , 与 仆 射 高 隆 之 共 典 营 构 邺 都 宫 室 , 术 有 思 理 , 百 工 克 济 。 再 迁 尚 书 右 丞 。 出 为 清 河 太 守 , 政 有 能 名 。 追 授 并 州 长 史 , 遭 父 忧 去 职 。 清 河 父 老 数 百 人 诣 阙 请 立 碑 颂 德 。 58 | 文 襄 嗣 事 , 与 尚 书 左 丞 宋 游 道 、 中 书 侍 郎 李 绘 等 并 追 诣 晋 阳 , 俱 为 上 客 。 累 迁 散 骑 常 侍 。 武 定 八 年 , 侯 景 叛 , 除 东 南 道 行 台 尚 书 , 封 江 夏 县 男 , 与 高 岳 等 破 侯 景 , 擒 萧 明 。 迁 东 徐 州 刺 史 , 为 淮 南 经 略 使 。 59 | 齐 天 保 元 年 , 侯 景 征 江 西 租 税 , 术 率 诸 军 渡 淮 断 之 , 烧 其 稻 数 百 万 石 。 还 镇 下 邳 , 人 随 术 北 渡 淮 者 三 千 馀 家 。 东 徐 州 刺 史 郭 志 杀 郡 守 。 60 | 文 宣 闻 之 , 敕 术 自 今 所 统 十 馀 州 地 诸 有 犯 法 者 , 刺 史 先 启 听 报 , 以 下 先 断 后 表 闻 。 齐 代 行 台 兼 总 人 事 , 自 术 始 也 。 61 | 安 州 刺 史 、 临 清 太 守 、 盱 眙 蕲 城 二 镇 将 犯 法 , 术 皆 案 奏 杀 之 。 睢 州 刺 史 及 所 部 郡 守 俱 犯 大 辟 , 朝 廷 以 其 奴 婢 百 口 及 资 财 尽 赐 术 , 三 辞 不 见 许 , 术 乃 送 诣 所 司 , 不 复 以 闻 。 62 | 邢 邵 闻 之 , 遗 术 书 曰 “ 昔 钟 离 意 云 孔 子 忍 渴 於 盗 泉 , 便 以 珠 玑 委 地 , 足 下 今 能 如 此 , 可 谓 异 代 一 时 ” 及 王 僧 辩 破 侯 景 , 术 招 携 安 抚 , 城 镇 相 继 款 附 , 前 后 二 十 馀 州 。 於 是 移 镇 广 陵 。 获 传 国 玺 送 邺 , 文 宣 以 玺 告 於 太 庙 。 63 | 此 玺 即 秦 所 制 , 方 四 寸 , 上 纽 交 盘 龙 , 其 文 曰 “ 受 命 於 天 , 既 寿 永 昌 ” 二 汉 相 传 , 又 传 魏 、 晋 。 怀 帝 败 , 没 於 刘 聪 。 聪 败 , 没 於 石 氏 。 石 氏 败 , 晋 穆 帝 永 和 中 , 濮 阳 太 守 戴 僧 施 得 之 , 遣 督 护 何 融 送 於 建 邺 。 64 | 历 宋 、 齐 、 梁 , 梁 败 , 侯 景 得 之 。 景 败 , 侍 中 赵 思 贤 以 玺 投 景 南 兖 州 刺 史 郭 元 建 , 送 於 术 , 故 术 以 进 焉 。 寻 征 为 殿 中 尚 书 , 领 太 常 卿 , 仍 与 朝 贤 议 定 律 令 。 迁 吏 部 尚 书 , 食 南 兖 州 梁 郡 干 。 迁 邺 以 后 , 大 选 之 职 , 知 名 者 数 四 , 互 有 得 失 , 未 能 尽 美 。 文 襄 帝 少 年 高 朗 , 所 弊 者 疏 。 65 | 袁 叔 德 沉 密 谨 厚 , 所 伤 者 细 。 杨 愔 风 流 辨 给 , 取 士 失 於 浮 华 。 唯 术 性 尚 贞 明 , 取 士 以 才 器 , 循 名 责 实 , 新 旧 参 举 , 管 库 必 擢 , 门 阀 不 遗 。 考 之 前 后 铨 衡 , 在 术 最 为 折 衷 , 甚 为 当 时 所 称 举 。 66 | 天 保 末 , 文 宣 尝 令 术 选 百 员 官 , 参 选 者 二 三 千 人 , 术 题 目 士 子 , 人 无 谤 讟 , 其 所 旌 擢 , 后 亦 皆 致 通 显 。 术 清 俭 , 寡 嗜 欲 。 勤 於 所 职 , 未 尝 暂 懈 。 临 军 以 威 严 , 牧 人 有 惠 政 。 少 爱 文 史 , 晚 更 修 学 , 虽 在 戎 旅 , 手 不 释 卷 。 67 | 及 定 淮 南 , 凡 诸 资 物 一 毫 无 犯 , 唯 大 收 典 籍 , 多 是 宋 、 齐 、 梁 时 佳 本 , 鸠 集 万 馀 卷 , 并 顾 陆 之 徒 名 画 、 二 王 已 下 法 书 数 亦 不 少 , 俱 不 上 王 府 , 唯 入 私 门 。 及 还 朝 , 颇 以 馈 遗 权 要 , 物 议 以 此 少 之 。 十 年 卒 , 年 六 十 。 68 | 皇 建 二 年 , 赠 开 府 仪 同 三 司 、 中 书 监 、 青 州 刺 史 。 子 阁 卿 , 尚 书 郎 。 阁 卿 弟 衡 卿 , 有 识 学 , 开 府 参 军 事 。 隋 大 业 初 , 卒 於 太 常 丞 。 元 文 遥 , 字 德 远 , 河 南 洛 阳 人 , 魏 昭 成 皇 帝 六 世 孙 也 。 五 世 祖 常 山 王 遵 。 父 晞 , 有 孝 行 , 父 卒 , 庐 於 墓 侧 而 终 。 69 | 文 遥 贵 , 赠 特 进 、 开 府 仪 同 三 司 、 中 书 监 , 谥 曰 孝 。 70 | 文 遥 敏 慧 夙 成 , 济 阴 王 晖 业 每 云 “ 此 子 王 佐 才 也 ” 晖 业 尝 大 会 宾 客 , 有 人 将 《 何 逊 集 》 初 入 洛 , 诸 贤 皆 赞 赏 之 。 河 间 邢 邵 试 命 文 遥 , “ 诵 之 几 遍 可 得 ” 文 遥 一 览 便 诵 , 时 年 十 馀 岁 。 起 家 员 外 散 骑 常 侍 。 71 | 遭 父 丧 , 服 阕 , 除 太 尉 东 閤 祭 酒 。 以 天 下 方 乱 , 遂 解 官 侍 养 , 隐 於 林 虑 山 。 武 定 中 , 文 襄 征 为 大 将 军 府 功 曹 。 齐 受 禅 , 於 登 坛 所 受 中 书 舍 人 , 宣 传 文 武 号 令 。 72 | 杨 遵 彦 每 云 “ 堪 解 穰 侯 印 者 , 必 在 斯 人 ” 后 忽 被 中 旨 幽 执 , 竟 不 知 所 由 。 如 此 积 年 。 文 宣 后 自 幸 禁 狱 , 执 手 愧 谢 , 亲 解 所 著 金 带 及 御 服 赐 之 , 即 日 起 为 尚 书 祠 部 郎 中 。 孝 昭 摄 政 , 除 大 丞 相 府 功 曹 参 军 , 典 机 密 。 73 | 及 践 祚 , 除 中 书 侍 郎 , 封 永 乐 县 伯 , 参 军 国 大 事 。 及 帝 大 渐 , 与 平 秦 王 归 彦 、 赵 郡 王 睿 等 同 受 顾 托 , 迎 立 武 成 。 即 位 , 任 遇 转 隆 , 历 给 事 黄 门 侍 郎 、 散 骑 常 侍 、 侍 中 、 中 书 监 。 天 统 二 年 , 诏 特 赐 姓 高 氏 , 籍 属 宗 正 , 子 弟 依 例 岁 时 入 朝 。 再 迁 尚 书 左 仆 射 , 进 封 宁 都 郡 公 、 侍 中 。 74 | 文 遥 历 事 三 主 , 明 达 世 务 , 每 临 轩 , 多 命 宣 敕 , 号 令 文 武 , 声 韵 高 朗 , 发 吐 无 滞 。 然 探 测 上 旨 , 时 有 委 巷 之 言 , 故 不 为 知 音 所 重 。 75 | 齐 因 魏 朝 , 宰 县 多 用 厮 滥 , 至 於 士 流 耻 居 百 里 。 文 遥 以 县 令 为 字 人 之 切 , 遂 请 革 选 。 於 是 密 令 搜 扬 贵 游 子 弟 , 发 敕 用 之 。 犹 恐 其 披 诉 , 总 召 集 神 武 门 , 令 赵 郡 王 睿 宣 旨 唱 名 , 厚 加 慰 喻 。 士 人 为 县 , 自 此 始 也 。 76 | 既 与 赵 彦 深 、 和 士 开 同 被 任 遇 , 虽 不 如 彦 深 清 贞 守 道 , 又 不 为 士 开 贪 淫 乱 政 , 在 於 季 、 孟 之 间 。 然 性 和 厚 , 与 物 无 竞 , 故 时 论 不 在 彦 深 之 下 。 77 | 初 , 文 遥 自 洛 迁 邺 , 惟 有 地 十 顷 , 家 贫 , 所 资 衣 食 而 已 。 魏 之 将 季 , 宗 姓 被 侮 , 有 人 冒 相 侵 夺 , 文 遥 即 以 与 之 。 及 贵 , 此 人 尚 在 , 乃 将 家 逃 窜 。 文 遥 大 惊 , 追 加 慰 抚 , 还 以 与 之 。 彼 人 愧 而 不 受 , 彼 此 俱 让 , 遂 为 闲 田 。 78 | 至 后 主 嗣 位 , 赵 郡 王 睿 、 娄 定 远 等 谋 出 和 士 开 , 文 遥 亦 参 其 议 。 睿 见 杀 , 文 遥 由 是 出 为 西 兖 州 刺 史 。 诣 士 开 别 , 士 开 曰 “ 处 得 言 地 , 使 元 家 儿 作 令 仆 , 深 愧 朝 廷 ” 既 言 而 悔 , 仍 执 手 慰 勉 之 。 79 | 犹 虑 文 遥 自 疑 , 用 其 子 行 恭 为 尚 书 郎 , 以 慰 其 心 。 士 开 死 , 自 东 徐 州 刺 史 征 入 朝 , 竟 不 用 , 卒 。 80 | 行 恭 美 姿 貌 , 有 父 风 , 兼 俊 才 , 位 中 书 舍 人 , 待 诏 文 林 馆 。 齐 亡 , 阳 休 之 等 十 八 人 同 入 关 , 稍 迁 司 勋 下 大 夫 。 隋 开 皇 中 , 位 尚 书 郎 , 坐 事 徙 瓜 州 而 卒 。 行 恭 少 颇 骄 恣 , 文 遥 令 与 范 阳 卢 思 道 交 游 。 81 | 文 遥 尝 谓 思 道 云 “ 小 儿 比 日 微 有 所 知 , 是 大 弟 之 力 , 然 白 掷 剧 饮 , 甚 得 师 风 ” 思 道 答 云 “ 郎 辞 情 俊 迈 , 自 是 克 荷 堂 构 , 而 白 掷 剧 饮 , 亦 天 性 所 得 ” 行 恭 弟 行 如 , 亦 聪 慧 早 成 , 武 平 末 , 任 著 作 佐 郎 。 赵 彦 深 , 自 云 南 阳 宛 人 , 汉 太 傅 憙 之 后 。 82 | 高 祖 父 难 , 为 清 河 太 守 , 有 惠 政 , 遂 家 焉 , 清 河 后 改 为 平 原 , 故 为 平 原 人 也 。 本 名 隐 , 避 齐 庙 讳 , 改 以 字 行 。 父 奉 伯 , 仕 魏 位 中 书 舍 人 、 行 洛 阳 令 。 彦 深 贵 , 赠 司 空 。 彦 深 幼 孤 贫 , 事 母 甚 孝 。 年 十 岁 , 曾 候 司 徒 崔 光 。 83 | 光 谓 宾 客 曰 “ 古 人 观 眸 子 以 知 人 , 此 人 当 必 远 至 ” 性 聪 敏 , 善 书 计 , 安 闲 乐 道 , 不 杂 交 游 , 为 雅 论 所 归 服 。 84 | 昧 爽 辄 自 扫 门 外 , 不 使 人 见 , 率 以 为 常 。 初 为 尚 书 令 司 马 子 如 贱 客 , 供 写 书 。 子 如 善 其 无 误 , 欲 将 入 观 省 舍 。 隐 靴 无 毡 , 衣 帽 穿 弊 , 子 如 给 之 。 85 | 用 为 书 令 史 , 月 馀 , 补 正 令 史 。 神 武 在 晋 阳 , 索 二 史 , 子 如 举 彦 深 。 后 拜 子 如 开 府 参 军 , 超 拜 水 部 郎 。 及 文 襄 为 尚 书 令 摄 选 , 沙 汰 诸 曹 郎 , 隐 以 地 寒 被 出 为 沧 州 别 驾 , 辞 不 行 。 86 | 子 如 言 於 神 武 , 征 补 大 丞 相 功 曹 参 军 , 专 掌 机 密 , 文 翰 多 出 其 手 , 称 为 敏 给 。 及 神 武 崩 , 秘 丧 事 , 文 襄 虑 河 南 有 变 , 仍 自 巡 抚 , 乃 委 彦 深 后 事 , 转 大 行 台 都 官 郎 中 。 临 发 , 握 手 泣 曰 “ 以 母 弟 相 托 , 幸 得 此 心 ” 既 而 内 外 宁 静 , 彦 深 之 力 。 及 还 发 丧 , 深 加 褒 美 , 乃 披 郡 县 簿 为 选 , 封 安 国 县 伯 。 87 | 从 征 颍 川 , 时 引 水 灌 城 , 城 雉 将 没 , 西 魏 将 王 思 政 犹 欲 死 战 。 文 襄 令 彦 深 单 身 入 城 告 喻 , 即 日 降 之 , 便 手 牵 思 政 出 城 。 先 是 , 文 襄 谓 彦 深 曰 “ 吾 昨 夜 梦 猎 , 遇 一 群 豕 , 吾 射 尽 获 之 , 独 一 大 豕 不 可 得 。 88 | 文 宣 嗣 位 , 仍 典 机 密 , 进 爵 为 侯 。 天 保 初 , 累 迁 秘 书 监 。 以 为 忠 谨 , 每 郊 庙 , 必 令 兼 太 仆 卿 , 执 御 陪 乘 。 转 大 司 农 。 89 | 帝 或 巡 幸 , 即 辅 赞 太 子 , 知 后 事 。 出 为 东 南 道 行 台 尚 书 、 徐 州 刺 史 , 为 政 尚 恩 信 , 为 吏 人 所 怀 , 多 所 降 下 。 所 营 军 处 , 士 庶 追 思 , 号 赵 行 台 顿 。 文 宣 玺 书 劳 勉 , 征 为 侍 中 , 仍 掌 机 密 。 90 | 河 清 元 年 , 进 爵 安 乐 公 , 累 迁 尚 书 左 仆 射 、 齐 州 大 中 正 、 监 国 史 , 迁 尚 书 令 , 为 特 进 , 封 宜 阳 王 。 武 平 二 年 拜 司 空 , 为 祖 珽 所 间 , 出 为 西 兖 州 刺 史 。 四 年 , 征 为 司 空 , 转 司 徒 。 丁 母 忧 , 寻 起 为 本 官 。 七 年 六 月 暴 疾 薨 , 时 年 七 十 。 彦 深 历 事 累 朝 , 常 参 机 近 , 温 柔 谨 慎 , 喜 怒 不 形 於 色 。 91 | 自 皇 建 以 还 , 礼 遇 稍 重 , 每 有 引 见 , 或 升 御 榻 , 常 呼 官 号 而 不 名 也 。 凡 诸 选 举 , 先 令 铨 定 , 提 奖 人 物 , 皆 行 业 为 先 , 轻 薄 之 徒 , 弗 之 齿 也 。 孝 昭 既 执 朝 权 , 群 臣 密 多 劝 进 , 彦 深 独 不 致 言 。 92 | 孝 昭 尝 谓 王 晞 云 “ 若 言 众 心 皆 谓 天 下 有 归 , 何 不 见 彦 深 有 语 ” 晞 以 告 , 彦 深 不 获 已 , 陈 请 , 其 为 时 重 如 此 。 常 逊 言 恭 己 , 未 尝 以 骄 矜 待 物 , 所 以 或 出 或 处 , 去 而 复 还 。 母 傅 氏 , 雅 有 操 识 。 彦 深 三 岁 , 傅 便 孀 居 , 家 人 欲 以 改 适 , 自 誓 以 死 。 93 | 彦 深 五 岁 , 傅 谓 之 曰 “ 家 贫 儿 小 , 何 以 能 济 ” 彦 深 泣 而 言 曰 “ 若 天 哀 矜 , 儿 大 当 仰 报 ” 傅 感 其 意 , 对 之 流 涕 。 94 | 及 彦 深 拜 太 常 卿 , 还 , 不 脱 朝 服 , 先 入 见 母 , 跪 陈 幼 小 孤 露 , 蒙 训 得 至 於 此 。 母 子 相 泣 久 之 , 然 后 改 服 。 后 为 宜 阳 国 太 妃 。 95 | 彦 深 有 七 子 , 仲 将 知 名 。 仲 将 沉 敏 有 父 风 , 温 良 恭 俭 , 虽 对 妻 子 , 亦 未 尝 怠 慢 , 终 日 俨 然 。 学 涉 群 书 , 善 草 隶 。 虽 与 弟 书 , 书 字 楷 正 , 云 草 不 可 不 解 , 若 施 之 於 人 , 即 似 相 轻 易 , 若 与 当 家 中 卑 幼 , 又 恐 其 疑 所 在 宜 尔 , 是 以 必 须 隶 笔 。 彦 深 乞 转 以 万 年 县 子 授 之 。 位 给 事 黄 门 侍 郎 、 散 骑 常 侍 。 96 | 隋 开 皇 中 , 位 吏 部 郎 , 终 於 安 州 刺 史 。 齐 朝 宰 相 , 善 始 令 终 唯 彦 深 一 人 。 然 讽 朝 廷 以 子 叔 坚 为 中 书 侍 郎 , 颇 招 物 议 。 时 冯 子 琮 子 慈 明 、 祖 珽 子 君 信 并 相 继 居 中 书 , 故 时 语 云 “ 冯 、 祖 及 赵 , 秽 我 凤 池 ” 然 叔 坚 身 材 最 劣 。 97 | 卷 三 十 九 · 列 传 第 三 十 一 崔 季 舒 , 字 叔 正 , 博 陵 安 平 人 。 父 瑜 之 , 魏 鸿 胪 卿 。 季 舒 少 孤 , 性 明 敏 , 涉 猎 经 史 , 长 於 尺 牍 , 有 当 世 才 具 。 98 | 年 十 七 , 为 州 主 簿 , 为 大 将 军 赵 郡 公 琛 所 器 重 , 言 之 於 神 武 。 神 武 亲 简 丞 郎 , 补 季 舒 大 行 台 都 官 郎 中 。 文 襄 辅 政 , 转 大 将 军 中 兵 参 军 , 甚 见 亲 宠 。 以 魏 帝 左 右 , 须 置 腹 心 , 擢 拜 中 书 侍 郎 。 文 襄 为 中 书 监 , 移 门 下 机 事 总 归 中 书 , 又 季 舒 善 音 乐 , 故 内 伎 亦 通 隶 焉 , 内 伎 属 中 书 。 自 季 舒 始 也 。 99 | 文 襄 每 进 书 魏 帝 , 有 所 谏 请 , 或 文 辞 繁 杂 , 季 舒 辄 修 饰 通 之 , 得 申 劝 戒 而 已 。 静 帝 报 答 霸 朝 , 恒 与 季 舒 论 之 , 云 “ 崔 中 书 是 我 奶 母 ” 转 黄 门 侍 郎 , 领 主 衣 都 统 。 虽 迹 在 魏 朝 , 而 心 归 霸 府 , 密 谋 大 计 , 皆 得 预 闻 。 100 | 於 是 宾 客 辐 凑 , 倾 心 接 礼 , 甚 得 名 誉 , 势 倾 崔 暹 。 暹 尝 於 朝 堂 屏 人 拜 之 曰 “ 暹 若 得 仆 射 , 皆 叔 父 之 恩 ” 其 权 重 如 此 。 时 勋 贵 多 不 法 , 文 襄 无 所 纵 舍 , 外 议 以 季 舒 及 崔 暹 等 所 为 , 甚 被 怨 疾 。 101 | 及 文 襄 遇 难 , 文 宣 将 赴 晋 阳 , 黄 门 郎 阳 休 之 劝 季 舒 从 行 , 曰 “ 一 日 不 朝 , 其 间 容 刀 ” 季 舒 性 爱 声 色 , 心 在 闲 放 , 遂 不 请 行 , 欲 恣 其 行 乐 。 102 | 司 马 子 如 缘 宿 憾 , 及 尚 食 典 御 陈 山 提 等 共 列 其 过 状 , 由 是 季 舒 及 暹 各 鞭 二 百 , 徙 北 边 。 天 保 初 , 文 宣 知 其 无 罪 , 追 为 将 作 大 匠 , 再 迁 侍 中 。 103 | 俄 兼 尚 书 左 仆 射 、 仪 同 三 司 , 大 被 恩 遇 。 乾 明 初 , 杨 愔 以 文 宣 遗 旨 , 停 其 仆 射 。 遭 母 丧 解 任 , 起 复 , 除 光 禄 勋 , 兼 中 兵 尚 书 。 出 为 齐 州 刺 史 , 坐 遣 人 渡 淮 互 市 , 亦 有 赃 贿 事 , 为 御 史 所 劾 , 会 赦 不 问 。 武 成 居 藩 , 曾 病 , 文 宣 令 季 舒 疗 病 , 备 尽 心 力 。 104 | 大 宁 初 , 追 还 , 引 入 慰 勉 , 累 拜 度 支 尚 书 、 开 府 仪 同 三 司 。 营 昭 阳 殿 , 敕 令 监 造 。 以 判 事 式 为 胡 长 仁 密 言 其 短 , 出 为 西 兖 州 刺 史 。 105 | 为 进 典 签 於 吏 部 , 被 责 免 官 , 又 以 诣 广 宁 王 宅 , 决 马 鞭 数 十 。 及 武 成 崩 , 不 得 预 於 哭 泣 。 久 之 , 除 胶 州 刺 史 , 迁 侍 中 、 开 府 , 食 新 安 、 河 阴 二 郡 干 。 加 左 光 禄 大 夫 , 待 诏 文 林 馆 , 监 撰 《 御 览 》 。 加 特 进 、 监 国 史 。 季 舒 素 好 图 籍 , 暮 年 转 更 精 勤 , 兼 推 荐 人 士 , 奖 劝 文 学 , 时 议 翕 然 , 远 近 称 美 。 106 | 祖 珽 受 委 , 奏 季 舒 总 监 内 作 。 珽 被 出 , 韩 长 鸾 以 为 珽 党 , 亦 欲 出 之 。 属 车 驾 将 适 晋 阳 , 季 舒 与 张 雕 议 : 以 为 寿 春 被 围 , 大 军 出 拒 , 信 使 往 还 , 须 禀 节 度 。 兼 道 路 小 人 , 或 相 惊 恐 , 云 大 驾 向 并 , 畏 避 南 寇 。 若 不 启 谏 , 必 动 人 情 。 遂 与 从 驾 文 官 连 名 进 谏 。 107 | 时 贵 臣 赵 彦 深 、 唐 邕 、 段 孝 言 等 初 亦 同 心 , 临 时 疑 贰 , 季 舒 与 争 未 决 。 108 | 长 鸾 遂 奏 云 “ 汉 儿 文 官 连 名 总 署 , 声 云 谏 止 向 并 , 其 实 未 必 不 反 , 宜 加 诛 戮 ” 帝 即 召 已 署 表 官 人 集 含 章 殿 , 以 季 舒 、 张 雕 、 刘 逖 、 封 孝 琰 、 裴 泽 、 郭 遵 等 为 首 , 并 斩 之 殿 庭 , 长 鸾 令 弃 其 尸 於 漳 水 。 109 | 自 外 同 署 , 将 加 鞭 挞 , 赵 彦 深 执 谏 获 免 。 季 舒 等 家 属 男 女 徙 北 边 , 妻 女 子 妇 配 奚 官 , 小 男 下 蚕 室 , 没 入 赀 产 。 季 舒 大 好 医 术 , 天 保 中 , 於 徙 所 无 事 , 更 锐 意 研 精 , 遂 为 名 手 , 多 所 全 济 。 虽 位 望 转 高 , 未 曾 懈 怠 , 纵 贫 贱 厮 养 , 亦 为 之 疗 。 庶 子 长 君 , 尚 书 右 外 兵 郎 中 。 次 镜 玄 , 著 作 佐 郎 。 110 | 并 流 於 远 恶 。 未 几 , 季 舒 等 六 人 妻 以 年 老 放 出 。 后 南 安 王 思 好 更 称 朝 廷 罪 恶 , 以 季 舒 等 见 害 为 词 , 悉 召 六 人 兄 弟 子 侄 随 军 趣 晋 阳 。 事 败 , 长 君 等 并 从 戮 , 六 人 妻 又 追 入 官 。 111 | 周 武 帝 灭 齐 , 诏 斛 律 光 与 季 舒 等 六 人 同 被 优 赠 , 季 舒 赠 开 府 仪 同 大 将 军 、 定 州 刺 史 云 。 祖 珽 , 字 孝 征 , 范 阳 遒 人 也 。 父 莹 , 魏 护 军 将 军 。 112 | 珽 神 情 机 警 , 词 藻 遒 逸 , 少 驰 令 誉 , 为 世 所 推 。 起 家 秘 书 郎 , 对 策 高 第 , 为 尚 书 仪 曹 郎 中 , 典 仪 注 。 113 | 尝 为 冀 州 刺 史 万 俟 受 洛 制 《 清 德 颂 》 , 其 文 典 丽 , 由 是 神 武 闻 之 。 时 文 宣 为 并 州 刺 史 , 署 珽 开 府 仓 曹 参 军 。 神 武 口 授 珽 三 十 六 事 , 出 而 疏 之 , 一 无 遗 失 , 大 为 僚 类 所 赏 。 114 | 时 神 武 送 魏 兰 陵 公 主 出 塞 嫁 蠕 蠕 , 魏 收 赋 《 出 塞 》 及 《 公 主 远 嫁 诗 》 二 首 , 珽 皆 和 之 , 大 为 时 人 传 咏 。 珽 性 疏 率 , 不 能 廉 慎 守 道 。 仓 曹 虽 云 州 局 , 乃 受 山 东 课 输 , 由 此 大 有 受 纳 , 丰 於 财 产 。 115 | 又 自 解 弹 琵 琶 , 能 为 新 曲 , 招 城 市 年 少 歌 舞 为 娱 , 游 集 诸 倡 家 。 与 陈 元 康 、 穆 子 容 、 任 胄 、 元 士 亮 等 为 声 色 之 游 。 诸 人 尝 就 珽 宿 , 出 山 东 大 文 绫 并 连 珠 孔 雀 罗 等 百 馀 匹 , 令 诸 妪 掷 樗 蒲 赌 之 , 以 为 戏 乐 。 参 军 元 景 献 , 故 尚 书 令 元 世 隽 子 也 , 其 妻 司 马 庆 云 女 , 是 魏 孝 静 帝 姑 博 陵 长 公 主 所 生 。 116 | 珽 忽 迎 景 献 妻 赴 席 , 与 诸 人 递 寝 , 亦 以 货 物 所 致 。 其 豪 纵 淫 逸 如 此 。 常 云 “ 丈 夫 一 生 不 负 身 ” 已 , 文 宣 罢 州 , 珽 例 应 随 府 , 规 为 仓 局 之 间 , 致 请 於 陈 元 康 , 元 康 为 白 , 由 是 还 任 仓 曹 。 珽 又 委 体 附 参 军 事 摄 典 签 陆 子 先 , 并 为 画 计 , 请 粮 之 际 , 令 子 先 宣 教 , 出 仓 粟 十 车 , 为 僚 官 捉 送 。 117 | 神 武 亲 问 之 , 珽 自 言 不 受 署 , 归 罪 子 先 , 神 武 信 而 释 之 。 珽 出 而 言 曰 “ 此 丞 相 天 缘 明 鉴 , 然 实 孝 征 所 为 ” 性 不 羁 放 纵 , 曾 至 胶 州 刺 史 司 马 世 云 家 饮 酒 , 遂 藏 铜 叠 二 面 。 厨 人 请 搜 诸 客 , 果 於 珽 怀 中 得 之 , 见 者 以 为 深 耻 。 所 乘 老 马 , 常 称 骝 驹 。 又 与 寡 妇 王 氏 奸 通 , 每 人 前 相 闻 往 复 。 118 | 裴 让 之 与 珽 早 狎 , 於 众 中 嘲 珽 曰 “ 卿 那 得 如 此 诡 异 , 老 马 十 岁 , 犹 号 骝 驹 。 一 妻 耳 顺 , 尚 称 娘 子 ” 於 时 喧 然 传 之 。 后 为 神 武 中 外 府 功 曹 , 神 武 宴 僚 属 , 於 坐 失 金 叵 罗 , 窦 泰 令 饮 酒 者 皆 脱 帽 , 於 珽 髻 上 得 之 , 神 武 不 能 罪 也 。 后 为 秘 书 丞 , 领 舍 人 , 事 文 襄 。 州 客 至 , 请 卖 《 华 林 遍 略 》 。 119 | 文 襄 多 集 书 人 , 一 日 一 夜 写 毕 , 退 其 本 曰 “ 不 须 也 ” 珽 以 《 遍 略 》 数 帙 质 钱 樗 蒲 , 文 襄 杖 之 四 十 。 又 与 令 史 李 双 、 仓 督 成 祖 等 作 晋 州 启 , 请 粟 三 千 石 , 代 功 曹 参 军 赵 彦 深 宣 神 武 教 , 给 城 局 参 军 。 120 | 事 过 典 签 高 景 略 , 疑 其 定 不 实 , 密 以 问 彦 深 , 彦 深 答 都 无 此 事 , 遂 被 推 检 , 珽 即 引 伏 。 神 武 大 怒 , 决 鞭 二 百 , 配 甲 坊 , 加 钳 , 其 谷 倍 征 。 121 | 未 及 科 , 会 并 州 定 国 寺 新 成 , 神 武 谓 陈 元 康 、 温 子 升 曰 “ 昔 作 《 芒 山 寺 碑 》 文 , 时 称 妙 绝 , 今 《 定 国 寺 碑 》 当 使 谁 作 词 也 ” 元 康 因 荐 珽 才 学 , 并 解 鲜 卑 语 。 乃 给 笔 札 , 就 禁 所 具 草 。 二 日 内 成 , 其 文 甚 丽 。 122 | 神 武 以 其 工 而 且 速 , 特 恕 不 问 , 然 犹 免 官 , 散 参 相 府 。 文 襄 嗣 事 , 以 为 功 曹 参 军 。 123 | 及 文 襄 遇 害 , 元 康 被 伤 创 重 , 倩 珽 作 书 属 家 累 事 , 并 云 “ 祖 喜 边 有 少 许 物 , 宜 早 索 取 ” 珽 乃 不 通 此 书 , 唤 祖 喜 私 问 , 得 金 二 十 五 铤 , 唯 与 喜 二 铤 , 馀 尽 自 入 己 。 盗 元 康 家 书 数 千 卷 。 祖 喜 怀 恨 , 遂 告 元 康 二 弟 叔 谌 、 季 璩 等 。 叔 谌 以 语 杨 愔 , 愔 嚬 眉 答 曰 “ 恐 不 益 亡 者 ” 因 此 得 停 。 124 | 文 宣 作 相 , 珽 拟 补 令 史 十 馀 人 , 皆 有 受 纳 , 据 法 处 绞 , 上 寻 舍 之 。 又 盗 官 《 遍 略 》 一 部 。 事 发 , 文 宣 付 从 事 中 郎 王 士 雅 推 检 , 并 书 与 平 阳 公 淹 , 令 录 珽 付 禁 , 勿 令 越 逸 。 淹 遣 田 曹 参 军 孙 子 宽 往 唤 , 珽 受 命 , 便 尔 私 逃 。 125 | 黄 门 郎 高 德 正 副 留 台 事 , 谋 云 “ 珽 自 知 有 犯 , 惊 窜 是 常 , 但 宣 一 命 向 秘 书 , 称 奉 并 州 约 束 须 《 五 经 》 三 部 , 仰 丞 亲 检 校 催 遣 , 如 此 则 珽 意 安 , 夜 当 还 宅 , 然 后 掩 取 ” 珽 果 如 德 正 图 , 遂 还 宅 。 薄 晚 , 就 家 掩 之 , 缚 珽 送 廷 尉 。 据 犯 枉 法 处 绞 刑 。 126 | 文 宣 以 珽 伏 事 先 世 , 讽 所 司 命 特 宽 其 罚 , 遂 奏 免 死 除 名 。 天 保 元 年 , 复 被 召 从 驾 , 依 除 免 例 , 参 於 晋 阳 。 珽 天 性 聪 明 , 事 无 难 学 , 凡 诸 伎 艺 , 莫 不 措 怀 , 文 章 之 外 , 又 善 音 律 , 解 四 夷 语 及 阴 阳 占 候 , 医 药 之 术 尤 是 所 长 。 文 宣 帝 虽 嫌 其 数 犯 宪 , 而 爱 其 才 伎 , 令 直 中 书 省 , 掌 诏 诰 。 127 | 珽 通 密 状 , 列 中 书 侍 郎 陆 元 规 , 敕 令 裴 英 推 问 , 元 规 以 应 对 忤 旨 , 被 配 甲 坊 。 除 珽 尚 药 丞 , 寻 迁 典 御 。 又 奏 造 胡 桃 油 , 复 为 割 藏 免 官 。 文 宣 每 见 之 , 常 呼 为 贼 。 文 宣 崩 , 普 选 劳 旧 , 除 为 章 武 太 守 。 会 杨 愔 等 诛 , 不 之 官 , 授 著 作 郎 。 数 上 密 启 , 为 孝 昭 所 忿 , 敕 中 书 门 下 二 省 断 珽 奏 事 。 128 | 珽 善 为 胡 桃 油 以 涂 画 , 乃 进 之 长 广 王 , 因 言 “ 殿 下 有 非 常 骨 法 , 孝 征 梦 殿 下 乘 龙 上 天 ” 。 王 谓 曰 “ 若 然 , 当 使 兄 大 富 贵 ” 及 即 位 , 是 为 武 成 皇 帝 , 擢 拜 中 书 侍 郎 。 帝 於 后 园 使 珽 弹 琵 琶 , 和 士 开 胡 舞 , 各 赏 物 百 段 。 士 开 忌 之 , 出 为 安 德 太 守 , 转 齐 郡 太 守 , 以 母 老 乞 还 侍 养 , 诏 许 之 。 129 | 会 江 南 使 人 来 聘 , 为 中 劳 使 。 寻 为 太 常 少 卿 、 散 骑 常 侍 、 假 仪 同 三 司 , 掌 诏 诰 。 130 | 初 , 珽 於 乾 明 、 皇 建 之 时 , 知 武 成 阴 有 大 志 , 遂 深 自 结 纳 , 曲 相 祗 奉 。 武 成 於 天 保 世 频 被 责 , 心 常 衔 之 。 珽 至 是 希 旨 , 上 书 请 追 尊 太 祖 献 武 皇 帝 为 神 武 , 高 祖 文 宣 皇 帝 改 为 威 宗 景 烈 皇 帝 , 以 悦 武 成 , 从 之 。 131 | 时 皇 后 爱 少 子 东 平 王 俨 , 愿 以 为 嗣 , 武 成 以 后 主 体 正 居 长 , 难 於 移 易 。 132 | 珽 私 於 士 开 曰 “ 君 之 宠 幸 , 振 古 无 二 , 宫 车 一 日 晚 驾 , 欲 何 以 克 终 ” 士 开 因 求 策 焉 。 珽 曰 “ 宜 说 主 上 , 云 襄 、 宣 、 昭 帝 子 俱 不 得 立 , 今 宜 命 皇 太 子 早 践 大 位 , 以 定 君 臣 。 若 事 成 , 中 宫 少 主 皆 德 君 , 此 万 全 计 也 。 133 | 君 此 且 微 说 , 令 主 上 粗 解 , 珽 当 自 外 上 表 论 之 ” 士 开 许 诺 。 因 有 彗 星 出 , 太 史 奏 云 除 旧 布 新 之 徵 。 珽 於 是 上 书 , 言 “ 陛 下 虽 为 天 子 , 未 是 极 贵 。 按 《 春 秋 元 命 苞 》 云 : 乙 酉 之 岁 , 除 旧 革 政 。 134 | 今 年 太 岁 乙 酉 , 宜 传 位 东 宫 , 令 君 臣 之 分 早 定 , 且 以 上 应 天 道 ” 并 上 魏 献 文 禅 子 故 事 。 帝 从 之 。 由 是 拜 秘 书 监 , 加 仪 同 三 司 , 大 被 亲 宠 。 既 见 重 二 宫 , 遂 志 於 宰 相 。 先 与 黄 门 侍 郎 刘 逖 友 善 , 乃 疏 侍 中 尚 书 令 赵 彦 深 、 侍 中 左 仆 射 元 文 遥 、 侍 中 和 士 开 罪 状 , 令 逖 奏 之 。 135 | 逖 惧 不 敢 通 , 其 事 颇 泄 , 彦 深 等 先 诣 帝 自 陈 。 136 | 帝 大 怒 , 执 珽 诘 曰 “ 何 故 毁 我 士 开 ” 珽 因 厉 声 曰 “ 臣 由 士 开 得 进 , 本 无 欲 毁 之 意 , 陛 下 今 既 问 臣 , 臣 不 敢 不 以 实 对 。 士 开 、 文 遥 、 彦 深 等 专 弄 威 权 , 控 制 朝 廷 , 与 吏 部 尚 书 尉 瑾 内 外 交 通 , 共 为 表 里 , 卖 官 鬻 狱 , 政 以 贿 成 , 天 下 歌 谣 。 若 为 有 识 所 知 , 安 可 闻 於 四 裔 。 137 | 陛 下 不 以 为 意 , 臣 恐 大 齐 之 业 隳 矣 ” 帝 曰 “ 尔 乃 诽 谤 我 ” 珽 曰 “ 不 敢 诽 谤 , 陛 下 取 人 女 ” 帝 曰 “ 我 以 其 俭 饿 , 故 收 养 之 ” 珽 曰 “ 何 不 开 仓 赈 给 , 乃 买 取 将 入 后 宫 乎 ” 帝 益 怒 , 以 刀 环 筑 口 , 鞭 杖 乱 下 , 将 扑 杀 之 。 大 呼 曰 “ 不 杀 臣 , 陛 下 得 名 , 杀 臣 , 臣 得 名 。 138 | 若 欲 得 名 , 莫 杀 臣 , 为 陛 下 合 金 丹 ” 遂 少 获 宽 放 。 珽 又 曰 “ 陛 下 有 一 范 增 不 能 用 , 知 可 如 何 ” 帝 又 怒 曰 “ 尔 自 作 范 增 , 以 我 为 项 羽 邪 ” 珽 曰 “ 项 羽 人 身 亦 何 由 可 及 , 但 天 命 不 至 耳 。 项 羽 布 衣 , 率 乌 合 众 , 五 年 而 成 霸 王 业 。 陛 下 藉 父 兄 资 , 财 得 至 此 , 臣 以 项 羽 未 易 可 轻 。 139 | 臣 何 止 方 於 范 增 , 纵 张 良 亦 不 能 及 。 张 良 身 傅 太 子 , 犹 因 四 皓 , 方 定 汉 嗣 。 臣 位 非 辅 弼 , 疏 外 之 人 , 竭 力 尽 忠 , 劝 陛 下 禅 位 , 使 陛 下 尊 为 太 上 , 子 居 宸 扆 , 於 己 及 子 , 俱 保 休 祚 。 蕞 尔 张 良 , 何 足 可 数 ” 帝 愈 恚 , 令 以 土 塞 其 口 , 珽 且 吐 且 言 , 无 所 屈 挠 。 乃 鞭 二 百 , 配 甲 坊 , 寻 徙 於 光 州 。 140 | 刺 史 李 祖 勋 遇 之 甚 厚 。 别 驾 张 奉 礼 希 大 臣 意 , 上 言 “ 珽 虽 为 流 囚 , 常 与 刺 史 对 坐 ” 敕 报 曰 “ 牢 掌 ” 奉 礼 曰 “ 牢 者 , 地 牢 也 ” 乃 为 深 坑 , 置 诸 内 , 苦 加 防 禁 , 桎 梏 不 离 其 身 , 家 人 亲 戚 不 得 临 视 。 141 | 夜 中 以 芜 菁 子 烛 熏 眼 , 因 此 失 明 。 武 成 崩 , 后 主 忆 之 , 就 除 海 州 刺 史 。 是 时 陆 令 萱 外 干 朝 政 , 其 子 穆 提 婆 爱 幸 。 142 | 珽 乃 遗 陆 媪 弟 悉 达 书 曰 “ 赵 彦 深 心 腹 深 沉 , 欲 行 伊 、 霍 事 , 仪 同 姊 弟 岂 得 平 安 , 何 不 早 用 智 士 耶 ” 和 士 开 亦 以 珽 能 决 大 事 , 欲 以 为 谋 主 , 故 弃 除 旧 怨 , 虚 心 待 之 。 143 | 与 陆 媪 言 於 帝 曰 “ 襄 、 宣 、 昭 三 帝 , 其 子 皆 不 得 立 , 今 至 尊 犹 在 帝 位 者 , 实 由 祖 孝 征 。 此 人 有 大 功 , 宜 报 重 恩 。 144 | 孝 征 心 行 虽 薄 , 奇 略 出 人 , 缓 急 真 可 凭 仗 。 且 其 双 盲 , 必 无 反 意 , 请 唤 取 问 其 谋 计 ” 从 之 , 入 为 银 青 光 禄 大 夫 、 秘 书 监 , 加 开 府 仪 同 三 司 。 和 士 开 死 后 , 仍 说 陆 媪 出 彦 深 , 以 珽 为 侍 中 。 在 晋 阳 , 通 密 启 请 诛 琅 邪 王 。 其 计 既 行 , 渐 被 任 遇 。 145 | 又 太 后 之 被 幽 也 , 珽 欲 以 陆 媪 为 太 后 , 撰 魏 帝 皇 太 后 故 事 , 为 太 姬 言 之 。 146 | 谓 人 曰 “ 太 姬 虽 云 妇 人 , 实 是 雄 杰 , 女 娲 已 来 无 有 也 ” 太 姬 亦 称 珽 为 国 师 、 国 宝 。 由 是 拜 尚 书 左 仆 射 , 监 国 史 , 加 特 进 , 入 文 林 馆 , 总 监 撰 书 , 封 燕 郡 公 , 食 太 原 郡 干 , 给 兵 七 十 人 。 所 住 宅 在 义 井 坊 , 旁 拓 邻 居 , 大 事 修 筑 , 陆 媪 自 往 案 行 。 势 倾 朝 野 。 147 | 斛 律 光 甚 恶 之 , 遥 见 窃 骂 云 “ 多 事 乞 索 小 人 , 欲 行 何 计 数 ” 常 谓 诸 将 云 “ 边 境 消 息 , 处 分 兵 马 , 赵 令 尝 与 吾 等 参 论 之 。 148 | 盲 人 掌 机 密 来 , 全 不 共 我 辈 语 , 止 恐 误 他 国 家 事 ” 又 珽 颇 闻 其 言 , 因 其 女 皇 后 无 宠 , 以 谣 言 闻 上 曰 “ 百 升 飞 上 天 , 明 月 照 长 安 ” 令 其 妻 兄 郑 道 盖 奏 之 。 帝 问 珽 , 珽 证 实 。 149 | 又 说 谣 云 “ 高 山 崩 , 槲 树 举 , 盲 老 翁 背 上 下 大 斧 , 多 事 老 母 不 得 语 ” 珽 并 云 “ 盲 老 翁 是 臣 ” , 云 与 国 同 忧 戚 , 劝 上 行 , 语 “ 其 多 事 老 母 , 似 道 女 侍 中 陆 氏 ” 。 帝 以 问 韩 长 鸾 、 穆 提 婆 , 并 令 高 元 海 、 段 士 良 密 议 之 , 众 人 未 从 。 因 光 府 参 军 封 士 让 启 告 光 反 , 遂 灭 其 族 。 150 | 珽 又 附 陆 媪 , 求 为 领 军 , 后 主 许 之 。 诏 须 覆 奏 , 取 侍 中 斛 律 孝 卿 署 名 。 151 | 孝 卿 密 告 高 元 海 , 元 海 语 侯 吕 芬 、 穆 提 婆 云 “ 孝 征 汉 儿 , 两 眼 又 不 见 物 , 岂 合 作 领 军 也 ” 明 旦 面 奏 , 具 陈 珽 不 合 之 状 , 并 书 珽 与 广 宁 王 孝 珩 交 结 , 无 大 臣 体 。 珽 亦 求 面 见 , 帝 令 引 入 。 珽 自 分 疏 , 并 云 与 元 海 素 相 嫌 , 必 是 元 海 谮 臣 。 152 | 帝 弱 颜 不 能 讳 , 曰 “ 然 ” 珽 列 元 海 共 司 农 卿 尹 子 华 、 太 府 少 卿 李 叔 元 、 平 准 令 张 叔 略 等 结 朋 树 党 。 153 | 遂 除 子 华 仁 州 刺 史 , 叔 元 襄 城 郡 太 守 , 叔 略 南 营 州 录 事 参 军 。 陆 媪 又 唱 和 之 , 复 除 元 海 郑 州 刺 史 。 珽 自 是 专 主 机 衡 , 总 知 骑 兵 、 外 兵 事 。 内 外 亲 戚 , 皆 得 显 位 。 后 主 亦 令 中 要 数 人 扶 侍 出 入 , 著 纱 帽 直 至 永 巷 , 出 万 春 门 向 圣 寿 堂 , 每 同 御 榻 论 决 政 事 , 委 任 之 重 , 群 臣 莫 比 。 154 | 自 和 士 开 执 事 以 来 , 政 体 隳 坏 , 珽 推 崇 高 望 , 官 人 称 职 , 内 外 称 美 。 复 欲 增 损 政 务 , 沙 汰 人 物 。 始 奏 罢 京 畿 府 , 并 於 领 军 , 事 连 百 姓 , 皆 归 郡 县 。 155 | 宿 卫 都 督 等 号 位 从 旧 官 名 , 文 武 章 服 并 依 故 事 。 又 欲 黜 诸 阉 竖 及 群 小 辈 , 推 诚 朝 廷 , 为 致 治 之 方 。 陆 媪 、 穆 提 婆 议 颇 同 异 。 珽 乃 讽 御 史 中 丞 丽 伯 侓 令 劾 主 书 王 子 冲 纳 贿 , 知 其 事 连 穆 提 婆 , 欲 使 赃 罪 相 及 , 望 因 此 坐 , 并 及 陆 媪 。 156 | 犹 恐 后 主 溺 於 近 习 , 欲 因 后 党 为 援 , 请 以 皇 后 兄 胡 君 瑜 为 侍 中 、 中 领 军 , 又 征 君 瑜 兄 梁 州 刺 史 君 璧 , 欲 以 为 御 史 中 丞 。 陆 媪 闻 而 怀 怒 , 百 方 排 毁 , 即 出 君 瑜 为 金 紫 光 禄 大 夫 , 解 中 领 军 , 君 璧 还 镇 梁 州 。 157 | 皇 后 之 废 , 颇 亦 由 此 。 王 子 冲 释 而 不 问 。 珽 日 益 以 疏 。 又 诸 宦 者 更 共 谮 毁 之 , 无 所 不 至 。 后 主 问 诸 太 姬 , 悯 默 不 对 , 及 三 问 , 乃 下 床 拜 曰 “ 老 婢 合 死 , 本 见 和 士 开 道 孝 征 多 才 博 学 , 言 为 善 人 , 故 举 之 。 158 | 比 来 看 之 , 极 是 罪 过 , 人 实 难 知 。 老 婢 合 死 ” 后 主 令 韩 长 鸾 检 案 , 得 其 诈 出 敕 受 赐 十 馀 事 , 以 前 与 其 重 誓 不 杀 , 遂 解 珽 侍 中 、 仆 射 , 出 为 北 徐 州 刺 史 。 珽 求 见 后 主 , 韩 长 鸾 积 嫌 於 珽 , 遣 人 推 出 柏 阁 。 珽 固 求 面 见 , 坐 不 肯 行 。 长 鸾 乃 令 军 士 牵 曳 而 出 , 立 珽 於 朝 堂 , 大 加 诮 责 。 159 | 上 道 后 , 令 追 还 , 解 其 开 府 仪 同 、 郡 公 , 直 为 刺 史 。 至 州 , 会 有 陈 寇 , 百 姓 多 反 。 160 | 珽 不 关 城 门 , 守 埤 者 皆 令 下 城 静 坐 , 街 巷 禁 断 行 人 , 鸡 犬 不 听 鸣 吠 。 贼 无 所 闻 见 , 不 测 所 以 , 疑 惑 人 走 城 空 , 不 设 警 备 。 161 | 珽 忽 然 令 大 叫 , 鼓 噪 聒 天 , 贼 大 惊 , 登 时 走 散 。 后 复 结 阵 向 城 , 珽 乘 马 自 出 , 令 录 事 参 军 王 君 植 率 兵 马 , 仍 亲 临 战 。 贼 先 闻 其 盲 , 谓 为 不 能 拒 抗 , 忽 见 亲 在 戎 行 , 弯 弧 纵 镝 , 相 与 惊 怪 , 畏 之 而 罢 。 时 穆 提 婆 憾 之 不 已 , 欲 令 城 陷 没 贼 , 虽 知 危 急 , 不 遣 救 援 。 162 | 珽 且 战 且 守 十 馀 日 , 贼 竟 奔 走 , 城 卒 保 全 。 卒 於 州 。 子 君 信 , 涉 猎 书 史 , 多 诸 杂 艺 。 位 兼 通 直 散 骑 常 侍 、 聘 陈 使 副 、 中 书 郎 。 珽 出 , 亦 见 废 免 。 163 | 君 信 弟 君 彦 , 容 貌 短 小 , 言 辞 涩 讷 , 少 有 才 学 。 隋 大 业 中 , 位 至 东 平 郡 书 佐 。 郡 陷 翟 让 , 因 为 李 密 所 得 , 密 甚 礼 之 , 署 为 记 室 , 军 书 羽 檄 皆 成 其 手 。 及 密 败 , 为 王 世 充 所 杀 。 珽 弟 孝 隐 , 有 文 学 , 早 知 名 。 词 章 虽 不 逮 兄 , 亦 机 警 有 辩 , 兼 解 音 律 。 魏 末 为 散 骑 常 侍 、 迎 梁 使 。 164 | 时 徐 君 房 、 庾 信 来 聘 , 名 誉 甚 高 , 魏 朝 闻 而 重 之 , 接 对 者 多 取 一 时 之 秀 , 卢 元 景 之 徒 并 降 阶 摄 职 , 更 递 司 宾 。 孝 隐 处 其 中 , 物 议 称 美 。 孝 隐 从 父 弟 茂 , 颇 有 辞 情 , 然 好 酒 性 率 , 不 为 时 重 。 165 | 大 宁 中 , 以 经 学 为 本 乡 所 荐 , 除 给 事 , 以 疾 辞 , 仍 不 复 仕 。 珽 受 任 寄 , 故 令 呼 茂 , 茂 不 获 已 , 暂 来 就 之 。 珽 欲 为 奏 官 , 茂 乃 逃 去 。 166 | 珽 族 弟 崇 儒 , 涉 学 有 辞 藻 , 少 以 干 局 知 名 。 武 平 末 , 司 州 别 驾 、 通 直 常 侍 。 入 周 , 为 容 昌 郡 太 守 。 隋 开 皇 初 , 终 宕 州 长 史 。 167 | 卷 四 十 · 列 传 第 三 十 二 尉 瑾 , 字 安 仁 。 父 庆 宾 , 为 魏 肆 州 刺 史 。 瑾 少 而 敏 悟 , 好 学 慕 善 。 稍 迁 直 后 。 司 马 子 如 执 政 , 瑾 取 其 外 生 皮 氏 女 , 由 此 擢 拜 中 书 舍 人 。 既 是 子 如 姻 戚 , 数 往 参 诣 , 因 与 先 达 名 辈 微 相 款 狎 。 168 | 世 宗 入 朝 , 因 命 瑾 在 邺 北 宫 共 高 德 正 典 机 密 。 肃 宗 辅 政 , 累 迁 吏 部 尚 书 。 世 祖 践 祚 , 赵 彦 深 本 子 如 宾 僚 , 元 文 遥 、 和 士 开 并 帝 乡 故 旧 , 共 相 荐 达 , 任 遇 弥 重 。 又 吏 部 铨 衡 所 归 , 事 多 秘 密 , 由 是 朝 之 几 事 , 颇 亦 预 闻 。 169 | 寻 兼 右 仆 射 , 摄 选 , 未 几 即 真 。 病 卒 , 世 祖 方 在 三 台 饮 酒 , 文 遥 奏 闻 , 遂 命 彻 乐 罢 饮 。 瑾 外 虽 通 显 , 内 阙 风 训 , 闺 门 秽 杂 , 为 世 所 鄙 。 170 | 然 亦 能 折 节 下 士 , 意 在 引 接 名 流 , 但 不 别 之 。 及 官 高 任 重 , 便 大 躁 急 , 省 内 郎 中 将 论 事 者 逆 即 瞋 詈 , 不 可 谘 承 。 既 居 大 选 , 弥 自 骄 狠 。 子 德 载 嗣 。 冯 子 琮 , 信 都 人 , 北 燕 主 冯 跋 之 后 也 。 父 灵 绍 , 度 支 郎 中 。 171 | 子 琮 性 聪 敏 , 涉 猎 书 传 。 为 肃 宗 除 领 军 府 法 曹 , 典 机 密 , 摄 库 部 。 肃 宗 曾 阅 簿 领 , 试 令 口 陈 , 子 琮 暗 对 , 无 有 遗 失 。 子 琮 妻 , 胡 皇 后 妹 也 。 迁 殿 中 郎 , 加 东 宫 管 记 。 又 奉 别 诏 , 令 共 胡 长 粲 辅 导 太 子 , 转 庶 子 。 天 统 元 年 , 世 祖 禅 位 后 主 。 172 | 世 祖 御 正 殿 , 谓 子 琮 曰 “ 少 君 左 右 宜 得 正 人 , 以 卿 心 存 正 直 , 今 以 后 事 相 委 ” 除 给 事 黄 门 侍 郎 , 领 主 衣 都 统 。 世 祖 在 晋 阳 , 既 居 旧 殿 , 少 帝 未 有 别 所 , 诏 子 琮 监 造 大 明 宫 。 宫 成 , 世 祖 亲 自 巡 幸 , 怪 其 不 甚 宏 丽 。 173 | 子 琮 对 曰 “ 至 尊 幼 年 , 纂 承 大 业 , 欲 令 敦 行 节 俭 , 以 示 万 邦 。 兼 此 北 连 天 阙 , 不 宜 过 复 崇 峻 ” 世 祖 称 善 。 及 世 祖 崩 , 仆 射 和 士 开 先 恒 侍 疾 , 秘 丧 三 日 不 发 。 子 琮 问 士 开 不 发 丧 之 意 。 174 | 士 开 引 神 武 、 文 襄 初 崩 并 秘 丧 不 举 , 至 尊 年 少 , 恐 王 公 有 贰 心 , 意 欲 普 追 集 凉 风 堂 , 然 后 与 公 详 议 。 175 | 时 太 尉 录 尚 书 事 赵 郡 王 睿 先 恒 居 内 , 预 帷 幄 之 谋 , 子 琮 素 知 士 开 忌 睿 及 领 军 临 淮 王 娄 定 远 , 恐 其 矫 遗 诏 出 睿 外 任 , 夺 定 远 禁 卫 之 权 , 因 答 云 “ 大 行 , 神 武 之 子 , 今 上 又 是 先 皇 传 位 , 群 臣 富 贵 者 皆 是 至 尊 父 子 之 恩 , 但 令 在 内 贵 臣 一 无 改 易 , 王 公 已 下 必 无 异 望 。 世 异 事 殊 , 不 得 与 霸 朝 相 比 。 176 | 且 公 出 宫 门 已 经 数 日 , 升 遐 之 事 , 行 路 皆 传 , 久 而 不 举 , 恐 有 他 变 ” 於 是 乃 发 丧 。 元 文 遥 以 子 琮 太 后 妹 夫 , 恐 其 奖 成 太 后 干 政 , 说 赵 郡 王 及 士 开 出 之 , 拜 郑 州 刺 史 , 即 令 之 任 。 177 | 子 琮 除 州 , 非 后 主 本 意 , 中 旨 殷 勤 , 特 给 后 部 鼓 吹 , 加 兵 五 十 人 , 并 听 将 物 度 关 。 178 | 至 州 未 几 , 太 后 为 齐 安 王 纳 子 琮 长 女 为 妃 , 子 琮 因 请 假 赴 邺 , 遂 授 吏 部 尚 书 。 其 妻 恃 亲 放 纵 , 请 谒 公 行 , 贿 货 填 积 。 179 | 守 宰 除 授 , 先 定 钱 帛 多 少 , 然 后 奏 闻 , 其 所 通 致 , 事 无 不 允 , 子 琮 亦 不 禁 制 。 俄 迁 尚 书 右 仆 射 , 仍 摄 选 。 和 士 开 居 要 日 久 , 子 琮 旧 所 附 托 , 卑 辞 曲 躬 , 事 事 谘 禀 。 士 开 弟 休 与 卢 氏 婚 , 子 琮 检 校 趋 走 , 与 士 开 府 僚 不 异 。 180 | 是 时 内 官 除 授 多 由 士 开 奏 拟 , 子 琮 既 恃 内 戚 , 兼 带 选 曹 , 自 擅 权 宠 , 颇 生 间 隙 。 琅 邪 王 俨 杀 士 开 , 子 琮 与 其 事 , 就 内 省 绞 杀 之 。 子 琮 微 有 识 鉴 , 及 位 望 转 隆 , 宿 心 顿 改 。 擢 引 非 类 , 以 为 深 交 。 纵 其 子 弟 , 官 位 不 依 伦 次 。 181 | 又 专 营 婚 媾 , 历 选 上 门 , 例 以 官 爵 许 之 , 旬 日 便 验 。 子 慈 正 。 赫 连 子 悦 , 字 士 欣 , 勃 勃 之 后 也 。 魏 永 安 初 , 以 军 功 为 济 州 别 驾 。 182 | 及 高 祖 起 义 , 侯 景 为 刺 史 , 景 本 尔 朱 心 腹 , 子 悦 劝 景 起 义 , 景 从 之 。 除 林 虑 守 。 世 宗 往 晋 阳 , 路 由 是 郡 , 因 问 所 不 便 。 183 | 悦 答 云 “ 临 水 、 武 安 二 县 去 郡 遥 远 , 山 岭 重 叠 , 车 步 艰 难 , 若 东 属 魏 郡 , 则 地 平 路 近 ” 世 宗 笑 曰 “ 卿 徒 知 便 民 , 不 觉 损 干 ” 子 悦 答 云 “ 所 言 因 民 疾 苦 , 不 敢 以 私 润 负 心 ” 世 宗 云 “ 卿 能 如 此 , 甚 善 甚 善 ” 仍 敕 依 事 施 行 。 在 郡 满 , 更 征 为 临 漳 令 。 184 | 后 除 郑 州 刺 史 , 於 时 新 经 河 清 大 水 , 民 多 逃 散 , 子 悦 亲 加 恤 隐 , 户 口 益 增 , 治 为 天 下 之 最 。 入 为 都 官 尚 书 , 郑 州 民 八 百 馀 请 立 碑 颂 德 , 有 诏 许 焉 。 185 | 后 以 本 官 兼 吏 部 。 子 悦 在 官 , 唯 以 清 勤 自 守 , 既 无 学 术 , 又 阙 风 仪 , 人 伦 清 鉴 , 去 之 弥 远 , 一 旦 居 铨 衡 之 首 , 大 招 物 议 。 由 是 除 太 常 卿 , 卒 。 唐 邕 , 字 道 和 , 太 原 晋 阳 人 , 其 先 自 晋 昌 徙 焉 。 父 灵 芝 , 魏 寿 阳 令 。 186 | 邕 少 明 敏 , 有 治 世 才 具 。 太 昌 初 , 或 荐 於 高 祖 , 命 其 直 外 兵 曹 , 典 执 文 帐 。 邕 善 书 计 , 强 记 默 识 , 以 干 济 见 知 , 擢 为 世 宗 大 将 军 府 参 军 。 及 世 宗 崩 , 事 出 仓 卒 , 显 祖 部 分 将 士 , 镇 压 四 方 , 夜 中 召 邕 支 配 , 造 次 便 了 , 显 祖 甚 重 之 。 显 祖 频 年 出 塞 , 邕 必 陪 从 , 专 掌 兵 机 。 187 | 识 悟 闲 明 , 承 受 敏 速 , 自 督 将 以 还 , 军 吏 以 上 , 劳 效 由 绪 , 无 不 谙 练 , 每 有 顾 问 , 占 对 如 响 。 或 於 御 前 简 阅 , 虽 三 五 千 人 , 邕 多 不 执 文 簿 , 暗 唱 官 位 姓 名 , 未 常 谬 误 。 七 年 , 於 羊 汾 堤 讲 武 , 令 邕 总 为 诸 军 节 度 。 事 毕 , 仍 监 宴 射 之 礼 。 188 | 是 日 , 显 祖 亲 执 邕 手 , 引 至 太 后 前 , 坐 於 丞 相 斛 律 金 之 上 , 启 太 后 云 “ 唐 邕 强 干 , 一 人 当 千 ” 仍 别 赐 锦 彩 钱 帛 。 189 | 邕 非 唯 强 济 明 辨 , 然 亦 善 揣 上 意 , 进 取 多 途 , 是 以 恩 宠 日 隆 , 委 任 弥 重 。 190 | 显 祖 又 尝 对 邕 白 太 后 云 “ 唐 邕 分 明 强 记 , 每 有 军 机 大 事 , 手 作 文 书 , 口 且 处 分 , 耳 又 听 受 , 实 是 异 人 ” 一 日 之 中 , 六 度 赐 物 。 又 尝 解 所 服 青 鼠 皮 裘 赐 邕 , 云 “ 朕 意 在 车 马 衣 裘 与 卿 共 弊 ” 十 年 , 从 幸 晋 阳 , 除 兼 给 事 黄 门 侍 郎 , 领 中 书 舍 人 。 191 | 显 祖 尝 登 童 子 佛 寺 , 望 并 州 城 曰 “ 此 是 何 等 城 ” 或 曰 “ 此 是 金 城 汤 池 , 天 府 之 国 ” 帝 云 “ 我 谓 唐 邕 是 金 城 , 此 非 金 城 也 ” 其 见 重 如 此 。 192 | 其 后 语 邕 曰 “ 卿 劬 劳 既 久 , 欲 除 卿 作 州 , 频 敕 杨 遵 彦 更 求 一 人 堪 代 卿 者 。 遵 彦 云 比 遍 访 文 武 , 如 卿 之 徒 实 不 可 得 , 所 以 遂 停 此 意 。 193 | 卿 宜 勉 之 ” 显 祖 或 时 切 责 侍 臣 不 称 旨 者 “ 观 卿 等 举 措 , 不 中 与 唐 邕 作 奴 ” 其 见 赏 遇 多 此 类 。 肃 宗 作 相 , 除 黄 门 侍 郎 。 194 | 於 华 林 园 射 , 特 赐 金 带 宝 器 服 玩 杂 物 五 百 种 。 天 统 初 , 除 侍 中 、 并 州 大 中 正 , 又 拜 护 军 , 馀 如 故 。 195 | 邕 以 军 民 教 习 田 猎 , 依 令 十 二 月 , 月 别 三 围 , 以 为 人 马 疲 敝 , 奏 请 每 月 两 围 。 世 祖 从 之 。 后 出 为 赵 州 刺 史 , 馀 官 如 故 。 世 祖 谓 邕 曰 “ 朝 臣 未 有 带 侍 中 、 护 军 、 中 正 作 州 者 , 以 卿 故 有 此 举 , 放 卿 百 馀 日 休 息 , 至 秋 间 当 即 追 卿 ” 迁 右 仆 射 , 又 迁 尚 书 令 , 封 晋 昌 王 , 录 尚 书 事 。 196 | 属 周 师 来 寇 , 丞 相 高 阿 那 肱 率 兵 赴 援 , 邕 配 割 不 甚 从 允 , 因 此 有 隙 。 肱 谮 之 , 遣 侍 中 斛 律 孝 卿 宣 旨 责 让 , 留 身 禁 止 , 寻 释 之 。 车 驾 将 幸 晋 阳 , 敕 孝 卿 总 知 骑 兵 度 支 , 事 多 自 决 , 不 相 询 禀 。 邕 自 恃 从 霸 朝 以 来 常 典 枢 要 , 历 事 六 帝 , 恩 遇 甚 重 , 一 旦 为 孝 卿 所 轻 , 负 气 郁 怏 , 形 於 辞 色 。 197 | 帝 平 阳 败 后 , 狼 狈 还 邺 都 。 邕 惧 那 肱 谮 之 , 恨 斛 律 孝 卿 轻 己 , 遂 留 晋 阳 , 与 莫 多 娄 敬 显 等 崇 树 安 德 王 为 帝 。 信 宿 城 陷 , 邕 遂 降 周 , 依 例 授 仪 同 大 将 军 。 卒 於 凤 州 刺 史 。 邕 性 识 明 敏 , 通 解 时 事 , 齐 氏 一 代 , 典 执 兵 机 。 198 | 凡 是 九 州 军 士 、 四 方 勇 募 , 强 弱 多 少 , 番 代 往 还 , 及 器 械 精 粗 、 粮 储 虚 实 , 精 心 勤 事 , 莫 不 谙 知 。 自 大 宁 以 来 , 奢 侈 糜 费 , 比 及 武 平 之 末 , 府 藏 渐 虚 。 邕 度 支 取 舍 , 大 有 裨 益 。 199 | 然 既 被 任 遇 , 意 气 渐 高 , 其 未 经 府 寺 陈 诉 , 越 览 词 牒 , 条 数 甚 多 , 俱 为 宪 台 及 左 丞 弹 纠 , 并 御 注 放 免 。 200 | 司 空 从 事 中 郎 封 长 业 、 太 尉 记 室 参 军 平 涛 并 为 征 官 钱 违 限 , 邕 各 杖 背 二 十 。 齐 时 宰 相 未 有 挝 挞 朝 士 者 , 至 是 甚 骇 物 听 。 邕 三 子 。 201 | 长 子 君 明 , 开 府 仪 同 三 司 。 开 皇 初 , 卒 於 应 州 刺 史 。 次 子 君 彻 , 中 书 舍 人 , 隋 顺 、 戎 二 州 刺 史 , 大 业 中 , 卒 於 武 贲 郎 将 。 少 子 君 德 , 以 邕 降 周 伏 法 。 齐 朝 因 高 祖 作 相 , 丞 相 府 外 兵 曹 、 骑 兵 曹 分 掌 兵 马 。 及 天 保 受 禅 , 诸 司 监 咸 归 尚 书 , 唯 此 二 曹 不 废 , 令 唐 邕 、 白 建 主 治 , 谓 之 外 兵 省 、 骑 兵 省 。 202 | 其 后 邕 、 建 位 望 转 隆 , 各 为 省 主 , 令 中 书 舍 人 分 判 二 省 事 , 故 世 称 唐 、 白 云 。 白 建 , 字 彦 举 , 太 原 阳 邑 人 也 。 初 入 大 丞 相 府 骑 兵 曹 , 典 执 文 帐 , 明 解 书 计 , 为 同 局 所 推 。 天 保 十 年 , 兼 中 书 舍 人 。 203 | 肃 宗 辅 政 , 除 大 丞 相 骑 兵 参 军 。 河 清 三 年 , 突 厥 入 境 , 代 、 忻 二 牧 悉 是 细 马 , 合 数 万 匹 , 在 五 台 山 北 柏 谷 中 避 贼 。 204 | 贼 退 后 , 敕 建 就 彼 检 校 , 续 使 人 诣 建 间 领 马 , 送 定 州 付 民 养 饲 。 建 以 马 久 不 得 食 , 瘦 弱 , 远 送 恐 多 死 损 , 遂 违 敕 以 便 宜 从 事 , 随 近 散 付 军 人 。 205 | 启 知 , 敕 许 焉 。 戎 乘 无 损 , 建 有 力 焉 。 武 平 末 , 历 特 进 、 侍 中 、 中 书 令 。 建 虽 无 他 才 , 勤 於 在 公 。 属 王 业 始 基 , 戎 寄 为 重 , 建 与 唐 邕 俱 以 典 执 兵 马 致 位 卿 相 。 晋 阳 , 国 之 下 都 , 每 年 临 幸 , 征 诏 差 科 , 责 成 州 郡 。 本 藩 僚 佐 爰 及 守 宰 , 谘 承 陈 请 , 趋 走 无 暇 。 206 | 诸 子 幼 稚 , 俱 为 州 郡 主 簿 , 新 君 选 补 , 必 先 召 辟 。 男 婚 女 嫁 , 皆 得 胜 流 。 当 世 以 为 荣 宠 之 极 。 武 平 七 年 卒 。 卷 四 十 一 · 列 传 第 三 十 三 暴 显 , 字 思 祖 , 魏 郡 斥 邱 人 也 。 祖 喟 , 魏 琅 邪 太 守 、 朔 州 刺 史 , 因 家 边 朔 。 207 | 父 诞 , 魏 恒 州 刺 史 、 左 卫 将 军 , 乐 安 公 。 显 幼 时 , 见 一 沙 门 指 之 曰 “ 此 郎 子 有 好 相 表 , 大 必 为 良 将 , 贵 极 人 臣 ” 语 终 失 僧 , 莫 知 所 去 。 显 少 经 军 旅 , 善 於 骑 射 , 曾 从 魏 孝 庄 帝 出 猎 , 一 日 之 中 , 手 获 禽 兽 七 十 三 。 孝 昌 二 年 , 除 羽 林 监 。 中 兴 元 年 , 除 襄 威 将 军 、 晋 州 车 骑 府 长 史 。 208 | 后 从 高 祖 於 信 都 举 义 , 授 中 坚 将 军 、 散 骑 侍 郎 、 帐 内 大 都 督 , 加 安 东 将 军 、 银 青 光 禄 大 夫 , 屯 留 县 开 国 侯 。 天 平 二 年 , 除 渤 海 郡 守 。 209 | 元 象 元 年 , 除 云 州 大 中 正 , 兼 武 卫 将 军 , 加 镇 东 将 军 。 二 年 , 除 北 徐 州 刺 史 、 当 州 大 都 督 。 从 高 祖 与 西 师 战 於 邙 山 , 高 祖 令 显 守 河 桥 镇 , 据 中 潬 城 。 武 定 二 年 , 除 征 南 将 军 、 广 州 刺 史 。 侯 景 反 於 河 南 , 为 景 所 攻 , 显 率 左 右 二 十 馀 骑 突 出 贼 营 , 拔 难 归 国 。 210 | 时 高 岳 、 慕 容 绍 宗 等 讨 景 , 即 配 显 士 马 , 随 岳 等 破 景 於 涡 阳 。 武 定 六 年 , 拜 太 府 卿 。 从 世 宗 平 王 思 政 於 颍 川 , 授 颍 州 刺 史 。 七 年 , 转 郑 州 刺 史 。 211 | 八 年 , 加 骠 骑 将 军 , 进 侯 为 公 , 通 前 食 邑 一 千 三 百 户 。 天 保 元 年 , 加 卫 大 将 军 , 刺 史 如 故 。 三 年 , 与 清 河 王 高 岳 袭 历 阳 , 取 之 。 为 赃 货 , 解 郑 州 , 大 理 禁 止 。 212 | 处 断 未 讫 , 为 合 肥 被 围 , 遣 与 步 汗 萨 、 慕 容 俨 等 同 攻 梁 北 徐 州 。 擒 刺 史 王 强 。 与 梁 秦 州 刺 史 严 超 达 战 於 泾 城 , 破 之 。 五 年 , 授 仪 同 三 司 。 其 年 , 又 与 高 岳 南 临 汉 水 , 攻 下 梁 西 楚 州 , 获 刺 史 许 法 光 。 213 | 於 时 梁 将 萧 循 与 侯 瑱 等 围 慕 容 俨 於 郢 州 , 复 以 显 为 水 军 大 都 督 , 从 摄 口 入 江 救 之 。 师 还 , 加 开 府 仪 同 三 司 , 赏 帛 五 百 匹 。 十 年 , 食 幽 州 范 阳 郡 干 。 乾 明 元 年 , 除 车 骑 大 将 军 。 皇 建 元 年 , 转 封 乐 安 郡 开 国 公 。 214 | 二 年 , 除 赵 州 刺 史 。 河 清 元 年 , 迁 洛 州 刺 史 。 二 年 , 复 除 朔 州 刺 史 , 秩 满 归 。 天 统 元 年 , 加 特 进 、 骠 骑 大 将 军 , 封 定 阳 王 。 四 年 卒 , 年 六 十 六 。 皮 景 和 , 琅 邪 下 邳 人 也 。 父 庆 宾 , 魏 淮 南 王 开 府 中 兵 参 军 事 。 正 光 中 , 因 使 怀 朔 , 遇 世 乱 , 因 家 广 宁 之 石 门 县 。 景 和 少 通 敏 , 善 骑 射 。 215 | 初 以 亲 信 事 高 祖 , 后 补 亲 信 副 都 督 。 武 定 二 年 , 征 步 落 稽 。 世 宗 疑 贼 有 伏 兵 , 令 景 和 将 五 六 骑 深 入 一 谷 中 , 值 贼 百 馀 人 , 便 共 格 战 , 景 和 射 数 十 人 , 莫 不 应 弦 而 倒 。 高 祖 尝 令 景 和 射 一 野 豕 , 一 箭 而 获 之 , 深 见 嗟 赏 , 除 库 直 正 都 督 。 天 保 初 , 授 假 节 、 通 州 刺 史 , 封 永 宁 县 开 国 子 。 216 | 后 从 袭 库 莫 奚 , 加 左 右 大 都 督 。 又 从 度 黄 龙 , 征 契 丹 , 定 稽 胡 。 寻 从 讨 茹 茹 主 庵 罗 辰 於 陉 北 , 又 从 平 茹 茹 馀 烬 。 景 和 趫 捷 , 有 武 用 , 每 有 战 功 。 十 年 , 食 安 乐 郡 干 。 乾 明 元 年 , 除 武 卫 将 军 , 兼 给 事 黄 门 侍 郎 。 217 | 肃 宗 作 相 , 以 本 官 摄 大 丞 相 府 从 事 中 郎 。 大 宁 元 年 , 除 仪 同 三 司 、 散 骑 常 侍 、 武 卫 大 将 军 , 寻 加 开 府 。 二 年 , 出 为 梁 州 刺 史 。 218 | 三 年 , 突 厥 围 逼 晋 阳 , 令 景 和 驰 驿 赴 京 , 督 领 后 军 赴 并 州 , 未 到 间 , 贼 已 退 。 仍 除 领 左 右 大 将 军 , 食 齐 郡 干 , 又 除 并 省 五 兵 尚 书 。 219 | 天 统 元 年 , 迁 殿 中 尚 书 。 二 年 , 除 侍 中 。 景 和 於 武 职 之 中 , 兼 长 吏 事 , 又 性 识 均 平 , 故 频 有 美 授 。 周 通 好 之 后 , 冠 盖 往 来 , 常 令 景 和 对 接 , 每 与 使 人 同 射 , 百 发 百 中 , 甚 见 推 重 。 武 平 中 , 诏 狱 多 令 中 黄 门 等 监 治 , 恒 令 景 和 按 覆 , 据 理 执 正 , 由 是 过 无 枉 滥 。 220 | 后 除 特 进 、 中 领 军 , 封 广 汉 郡 开 国 公 。 又 随 斛 律 光 率 众 西 讨 , 克 姚 襄 、 白 亭 二 城 , 别 封 永 宁 郡 开 国 公 。 又 除 领 军 将 军 。 又 从 军 拔 宜 阳 城 , 封 开 封 郡 开 国 公 。 琅 邪 王 之 杀 和 士 开 也 , 兵 指 西 阙 , 内 外 惶 惑 , 莫 知 所 为 。 221 | 景 和 请 后 主 出 千 秋 门 自 号 令 。 事 平 , 除 尚 书 右 仆 射 、 赵 州 刺 史 。 寻 迁 河 南 行 台 尚 书 右 仆 射 、 洛 州 刺 史 。 陈 将 吴 明 彻 寇 淮 南 , 令 景 和 率 众 拒 之 , 除 领 军 大 将 军 , 封 文 城 郡 王 , 转 食 高 阳 郡 干 。 军 至 柤 口 , 值 土 人 陈 暄 等 作 乱 , 景 和 平 之 。 222 | 又 有 阳 平 人 郑 子 饶 , 诈 依 佛 道 , 设 斋 会 , 用 米 面 不 多 , 供 赡 甚 广 , 密 从 地 藏 渐 出 饼 饭 , 愚 人 以 为 神 力 , 见 信 於 魏 、 卫 之 间 。 将 为 逆 乱 , 谋 泄 , 掩 讨 漏 逸 。 223 | 乃 潜 渡 河 , 聚 众 数 千 , 自 号 长 乐 王 , 已 破 乘 氏 县 , 又 欲 袭 西 兖 州 城 。 景 和 自 南 兖 州 遣 骑 数 百 击 破 之 , 斩 首 二 千 馀 级 , 生 擒 子 饶 , 送 京 师 烹 之 。 224 | 及 吴 明 彻 围 寿 阳 , 敕 令 景 和 与 贺 拔 伏 恩 等 赴 救 。 景 和 以 尉 破 胡 军 始 丧 败 , 怯 懦 不 敢 进 , 顿 兵 淮 口 , 频 有 敕 使 催 促 , 然 始 渡 淮 。 225 | 属 寿 阳 已 陷 , 狼 狈 北 还 , 器 械 军 资 , 大 致 遗 失 。 陈 将 萧 摩 诃 率 步 骑 於 淮 北 仓 陵 城 截 之 , 景 和 得 整 旅 逆 战 , 摩 诃 退 归 。 是 时 拒 吴 明 彻 者 多 致 倾 覆 , 唯 景 和 全 军 而 还 , 由 是 获 赏 , 除 尚 书 令 , 别 封 西 河 郡 开 国 公 , 赐 钱 二 十 万 , 酒 米 十 车 。 时 陈 人 声 将 渡 淮 , 令 景 和 停 军 西 兖 州 , 为 拒 守 节 度 。 226 | 武 平 六 年 病 卒 , 年 五 十 五 。 赠 侍 中 、 使 持 节 、 都 督 定 恒 朔 幽 定 平 六 州 诸 军 事 、 太 尉 公 、 录 尚 书 事 、 定 州 刺 史 。 长 子 信 , 机 悟 有 风 神 , 微 涉 书 传 。 武 平 末 , 开 府 仪 同 三 司 、 武 卫 将 军 , 於 勋 贵 子 弟 之 中 , 称 其 识 鉴 。 227 | 於 并 州 降 周 军 , 授 上 开 府 、 军 正 大 夫 。 隋 开 皇 中 , 卒 於 洮 州 刺 史 。 少 子 宿 达 , 武 平 末 太 子 斋 帅 , 有 才 藻 检 行 。 开 皇 中 , 通 事 舍 人 。 228 | 丁 母 忧 , 起 复 , 将 赴 京 , 辞 灵 恸 哭 而 绝 , 久 而 获 苏 , 不 能 下 食 , 三 日 致 死 。 鲜 於 世 荣 , 渔 阳 人 也 。 父 宝 业 , 怀 朔 镇 将 , 武 平 初 , 赠 仪 同 三 司 、 祠 部 尚 书 、 朔 州 刺 史 。 世 荣 少 而 沉 敏 , 有 器 干 。 兴 和 二 年 , 为 高 祖 亲 信 副 都 督 , 稍 迁 平 西 将 军 、 赐 爵 石 门 县 子 。 后 频 从 显 祖 讨 茹 茹 , 破 稽 胡 。 229 | 又 从 高 岳 平 郢 州 , 除 持 节 、 河 州 刺 史 , 食 朝 歌 县 干 。 寻 为 肃 宗 丞 相 府 谘 议 参 军 。 皇 建 中 , 除 仪 同 三 司 、 武 卫 将 军 。 天 统 二 年 , 加 开 府 , 又 除 郑 州 刺 史 。 武 平 中 , 以 平 信 州 贼 , 除 领 军 将 军 , 转 食 上 党 郡 干 。 230 | 从 平 高 思 好 , 封 义 阳 王 。 七 年 , 后 主 幸 晋 阳 , 令 世 荣 以 本 官 判 尚 书 右 仆 射 事 , 贰 北 平 王 北 宫 留 后 。 寻 有 敕 令 与 吏 部 尚 书 袁 聿 修 在 尚 书 省 检 试 举 人 。 为 乘 马 至 云 龙 门 外 入 省 北 门 , 为 宪 司 举 奏 免 官 。 231 | 后 主 围 平 阳 , 除 世 荣 领 军 将 军 。 周 师 将 入 邺 , 除 领 军 大 将 军 、 太 子 太 傅 , 於 城 西 拒 战 , 败 被 擒 , 为 周 武 所 杀 。 232 | 世 荣 虽 武 人 无 文 艺 , 以 朝 危 政 乱 , 每 窃 叹 之 。 见 征 税 无 厌 , 赐 与 过 度 , 发 言 叹 惜 。 子 子 贞 , 武 平 末 假 仪 同 三 司 。 綦 连 猛 , 字 武 儿 , 代 人 也 。 其 先 姬 姓 , 六 国 末 , 避 乱 出 塞 , 保 祁 连 山 , 因 以 山 为 姓 , 北 人 语 讹 , 故 曰 綦 连 氏 。 父 元 成 , 燕 郡 太 守 。 猛 少 有 志 气 , 便 习 弓 马 。 233 | 永 安 三 年 , 尔 朱 荣 征 为 亲 信 。 至 洛 阳 , 荣 被 害 , 即 从 尔 朱 世 隆 出 奔 建 州 , 仍 从 尔 朱 兆 入 洛 。 其 年 , 又 从 兆 讨 纥 豆 陵 步 藩 , 补 都 督 。 普 泰 元 年 , 加 征 虏 将 军 、 中 散 大 夫 。 234 | 猛 父 母 兄 弟 皆 在 山 东 , 尔 朱 京 缠 欲 投 高 祖 , 谓 猛 曰 “ 王 以 尔 父 兄 皆 在 山 东 , 每 怀 不 信 , 尔 若 不 走 , 今 夜 必 当 杀 尔 , 可 走 去 ” 猛 以 素 蒙 兆 恩 , 拒 而 不 从 。 京 缠 曰 “ 我 今 亦 欲 去 , 尔 从 我 不 ” 猛 又 不 从 。 京 缠 乃 举 槊 曰 “ 尔 不 从 , 我 必 刺 尔 ” 猛 乃 从 之 。 去 城 五 十 馀 里 , 即 背 京 缠 复 归 尔 朱 。 235 | 及 兆 败 , 乃 归 高 祖 。 高 祖 问 曰 “ 尔 朱 京 缠 将 尔 投 我 , 尔 中 路 背 去 何 也 ” 猛 乃 具 陈 服 事 之 理 , 不 可 贰 心 。 高 祖 曰 “ 尔 莫 惧 , 服 事 人 法 须 如 此 ” 遂 补 都 督 。 步 落 稽 等 起 逆 , 在 覆 釜 山 , 使 猛 讨 之 , 大 捷 , 特 被 赏 赉 。 元 象 元 年 , 从 高 祖 向 河 阳 , 与 周 文 帝 战 於 邙 山 。 二 年 , 除 平 东 将 军 、 中 散 大 夫 。 236 | 其 年 , 又 转 中 外 府 帐 内 都 督 , 赏 邙 山 之 功 , 封 广 兴 县 开 国 君 。 五 年 , 梁 使 来 聘 , 云 有 武 艺 , 求 访 北 人 , 欲 与 相 角 。 世 宗 遣 猛 就 馆 接 之 , 双 带 两 鞬 , 左 右 驰 射 。 兼 共 试 力 , 挽 强 , 梁 人 引 弓 两 张 , 力 皆 三 石 , 猛 遂 并 取 四 张 , 叠 而 挽 之 , 过 度 。 梁 人 嗟 服 之 。 237 | 其 年 , 除 抚 军 将 军 , 别 封 石 城 县 开 国 子 , 食 肆 州 平 寇 县 干 。 天 保 元 年 , 除 都 督 、 东 秦 州 刺 史 , 别 封 雍 州 京 兆 郡 覆 城 县 开 国 男 。 从 显 祖 讨 契 丹 , 大 获 户 口 。 又 随 斛 律 敦 北 征 茹 茹 , 敦 令 猛 轻 将 百 骑 深 入 觇 候 。 还 至 白 道 , 与 军 相 会 , 因 此 追 蹑 , 遂 大 破 之 。 赉 帛 三 百 段 。 238 | 七 年 , 除 武 卫 将 军 、 仪 同 三 司 。 九 年 , 转 武 卫 大 将 军 。 239 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/data/guwen/raw_data/process.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | all_labels = set() 4 | 5 | 6 | def process_data(source, target, mode): 7 | with open(source, "r", encoding="utf-8") as fp: 8 | data = fp.read().strip().split("\n") 9 | with open(target, "r", encoding="utf-8") as fp: 10 | labels = fp.read().strip().split("\n") 11 | res = [] 12 | text_id = 0 13 | for s, t in zip(data, labels): 14 | text = s.split(" ") 15 | label = t.split(" ") 16 | assert len(text) == len(label) 17 | length = len(text) 18 | ent_id = 0 19 | tmp = {} 20 | text = "".join(text) 21 | tmp["id"] = text_id 22 | tmp["text"] = text 23 | tmp["labels"] = [] 24 | for i in range(length): 25 | if 'B-' in label[i]: 26 | j = i + 1 27 | ent_type = label[i].split("-")[-1] 28 | all_labels.add(ent_type) 29 | if j == length: 30 | ent_des = [str(ent_id), ent_type, i, i + 1, text[i:i + 1]] 31 | tmp["labels"].append(ent_des) 32 | ent_id += 1 33 | else: 34 | while j <= length - 1 and "I-" in label[j]: 35 | j += 1 36 | ent_des = [str(ent_id), ent_type, i, j, text[i:j]] 37 | tmp["labels"].append(ent_des) 38 | ent_id += 1 39 | i += 1 40 | res.append(tmp) 41 | 42 | with open("../mid_data/{}.json".format(mode), "w", encoding="utf-8") as fp: 43 | json.dump(res, fp, ensure_ascii=False) 44 | 45 | 46 | process_data("source.txt", "target.txt", mode="train") 47 | process_data("dev.txt", "dev-label.txt", mode="dev") 48 | process_data("test1.txt", "testtgt.txt", mode="test") 49 | 50 | with open("../mid_data/labels.json", "w", encoding="utf-8") as fp: 51 | json.dump(list(all_labels), fp, ensure_ascii=False) 52 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/data/guwen/raw_data/test1.txt: -------------------------------------------------------------------------------- 1 | 澄 乃 教 延 遇 告 变 , 言 崧 与 其 甥 王 凝 谋 因 山 陵 放 火 焚 京 师 , 又 以 蜡 丸 书 通 守 贞 。 逢 吉 遣 人 召 崧 至 第 , 从 容 告 之 , 崧 知 不 免 , 乃 以 幼 女 托 逢 吉 。 逢 吉 送 崧 侍 卫 狱 。 崧 出 乘 马 , 从 者 去 , 无 一 人 , 崧 恚 曰 “ 自 古 岂 有 不 死 之 人 , 然 亦 岂 有 不 亡 之 国 乎 ” 乃 自 诬 伏 , 族 诛 。 2 | 崧 素 与 翰 林 学 士 徐 台 符 相 善 , 后 周 太 祖 入 立 , 台 符 告 宰 相 冯 道 , 请 诛 葛 延 遇 , 道 以 延 遇 数 经 赦 宥 , 难 之 。 枢 密 使 王 峻 闻 之 , 多 台 符 有 义 , 乃 奏 诛 延 遇 。 ○ 李 鏻 李 鏻 , 唐 宗 室 子 也 。 其 伯 父 阳 事 唐 , 咸 通 间 为 给 事 中 。 3 | 鏻 少 举 进 士 , 累 不 中 , 客 河 朔 间 , 自 称 清 海 军 掌 书 记 , 谒 定 州 王 处 直 , 处 直 不 为 礼 。 4 | 乃 易 其 绿 衣 , 更 为 绯 衣 , 谒 常 山 李 弘 规 , 弘 规 进 之 赵 王 王 镕 , 镕 留 为 从 事 。 其 后 张 文 礼 弑 镕 自 立 , 遣 鏻 聘 唐 庄 宗 于 太 原 。 5 | 鏻 为 人 利 口 敢 言 , 乃 阴 为 庄 宗 画 文 礼 可 破 之 策 。 后 文 礼 败 , 庄 宗 以 鏻 为 支 使 。 庄 宗 即 位 , 拜 鏻 宗 正 卿 , 以 李 琼 为 少 卿 。 6 | 献 祖 、 懿 祖 墓 在 赵 州 昭 庆 县 , 唐 国 初 建 , 鏻 、 琼 上 言 “ 献 祖 宣 皇 帝 建 初 陵 , 懿 祖 光 皇 帝 启 运 陵 , 请 置 台 令 ” 县 中 无 赖 子 自 称 宗 子 者 百 馀 人 , 宗 正 无 谱 牒 , 莫 能 考 按 。 7 | 有 民 诣 寺 自 言 世 为 丹 阳 竟 陵 台 令 , 厚 赂 宗 正 吏 , 鏻 、 琼 不 复 详 考 , 遂 补 为 令 。 民 即 持 绛 幡 招 置 部 曲 , 侵 夺 民 田 百 馀 顷 , 以 谓 陵 园 壖 地 。 民 诉 于 官 , 不 能 决 , 以 闻 。 庄 宗 下 公 卿 博 士 , 问 故 唐 诸 帝 陵 寝 所 在 。 8 | 公 卿 博 士 言 “ 丹 阳 在 今 润 州 , 而 竟 陵 非 唐 事 。 鏻 不 学 无 知 , 不 足 以 备 九 卿 ” 坐 贬 司 农 少 卿 , 出 为 河 中 节 度 副 使 。 明 宗 即 位 , 以 鏻 故 人 , 召 还 , 累 迁 户 部 尚 书 。 鏻 意 颇 希 大 用 , 尝 谓 冯 道 、 赵 凤 曰 “ 唐 家 故 事 , 宗 室 皆 为 宰 相 。 9 | 今 天 祚 中 兴 , 宜 按 旧 典 , 鏻 虽 不 才 , 尝 事 庄 宗 霸 府 , 识 今 天 子 于 藩 邸 , 论 才 较 业 , 何 后 众 人 。 而 久 置 班 行 , 于 诸 君 安 乎 ” 道 等 恶 其 言 。 10 | 后 杨 溥 谍 者 见 鏻 言 事 , 鏻 谓 安 重 诲 曰 “ 杨 溥 欲 归 国 久 矣 , 若 朝 廷 遣 使 谕 之 , 可 以 召 也 ” 重 诲 信 之 , 以 玉 带 与 谍 者 使 为 信 , 久 而 无 效 , 由 是 贬 鏻 兖 州 行 军 司 马 。 11 | 鏻 与 废 帝 有 旧 , 愍 帝 时 , 为 兵 部 尚 书 , 奉 使 湖 南 , 闻 废 帝 立 , 喜 , 以 谓 必 用 己 为 相 。 还 过 荆 南 , 谓 高 从 诲 曰 “ 士 固 有 否 泰 , 吾 不 为 时 用 久 矣 。 12 | 今 新 天 子 即 位 , 我 将 用 矣 ” 乃 就 从 诲 求 宝 货 入 献 以 为 贺 , 从 诲 与 马 红 装 拂 二 、 猓 犭 然 皮 一 , 因 为 鏻 置 酒 , 问 其 副 使 马 承 翰 “ 今 朝 廷 之 臣 , 孰 有 公 辅 之 望 ” 承 翰 曰 “ 尚 书 崔 居 俭 、 左 丞 姚 顗 , 其 次 太 常 卢 文 纪 也 ” 从 诲 笑 顾 左 右 , 取 进 奏 官 报 状 示 鏻 顗 与 文 纪 皆 拜 平 章 事 矣 。 鏻 惭 失 色 。 13 | 还 , 遂 献 其 皮 、 拂 , 废 帝 终 不 用 。 初 , 李 愚 自 太 常 卿 作 相 , 而 卢 文 纪 代 之 , 及 文 纪 作 相 , 鏻 乃 求 为 太 常 卿 。 14 | 及 拜 命 , 中 谢 曰 “ 臣 叨 入 相 之 资 ” 朝 士 传 以 为 笑 。 鏻 事 晋 累 迁 太 子 太 保 。 汉 高 祖 即 位 , 拜 鏻 司 徒 , 居 数 月 卒 , 年 八 十 八 , 赠 太 傅 。 ○ 贾 纬 贾 纬 , 镇 州 获 鹿 人 也 。 少 举 进 士 不 中 , 州 辟 参 军 。 15 | 唐 天 成 中 , 范 延 光 镇 成 德 , 辟 赵 州 军 事 判 官 , 迁 石 邑 令 。 纬 长 于 史 学 。 唐 自 武 宗 已 后 无 实 录 , 史 官 之 职 废 , 纬 采 次 传 闻 , 为 《 唐 年 补 录 》 六 十 五 卷 。 16 | 当 唐 之 末 , 王 室 微 弱 , 诸 侯 强 盛 , 征 伐 擅 出 , 天 下 多 事 , 故 纬 所 论 次 多 所 阙 误 。 而 丧 乱 之 际 , 事 迹 粗 存 , 亦 有 补 于 史 氏 。 晋 天 福 中 , 为 太 常 博 士 , 非 其 好 也 , 数 求 为 史 职 , 改 屯 田 员 外 郎 、 起 居 郎 、 史 馆 修 撰 , 与 修 《 唐 书 》 。 丁 内 艰 , 服 除 , 知 制 诰 。 17 | 累 迁 中 书 舍 人 、 谏 议 大 夫 、 给 事 中 , 复 为 修 撰 。 汉 隐 帝 时 , 诏 与 王 伸 、 窦 俨 等 同 修 晋 高 祖 、 出 帝 、 汉 高 祖 实 录 。 初 , 桑 维 翰 为 相 , 常 恶 纬 为 人 , 待 之 甚 薄 。 纬 为 维 翰 传 , 言 “ 继 翰 死 , 有 银 八 千 铤 ” 翰 林 学 士 徐 台 符 以 为 不 可 , 数 以 非 纬 , 纬 不 得 已 , 更 为 数 千 铤 。 18 | 广 顺 元 年 , 实 录 成 , 纬 求 迁 官 不 得 , 由 是 怨 望 。 19 | 是 时 , 宰 相 王 峻 监 修 国 史 , 纬 书 日 历 , 多 言 当 时 大 臣 过 失 , 峻 见 之 , 怒 曰 “ 贾 给 事 子 弟 仕 宦 亦 要 门 阀 , 奈 何 历 诋 当 朝 之 士 , 使 其 子 孙 何 以 仕 进 ” 言 之 太 祖 , 贬 平 卢 军 行 军 司 马 。 明 年 卒 于 青 州 。 ○ 段 希 尧 段 希 尧 , 河 内 人 也 。 晋 高 祖 为 河 东 节 度 使 , 以 希 尧 为 判 官 。 20 | 高 祖 军 屯 忻 州 , 军 中 有 拥 高 祖 呼 万 岁 者 , 高 祖 惶 惑 , 不 知 所 为 。 希 尧 劝 高 祖 斩 其 乱 首 , 乃 止 。 高 祖 将 举 兵 太 原 , 与 其 宾 佐 谋 , 希 尧 以 为 不 可 , 高 祖 虽 不 听 , 然 重 其 为 人 , 不 责 之 也 。 高 祖 入 立 , 希 尧 比 诸 将 吏 , 恩 泽 最 薄 。 21 | 久 之 , 稍 迁 谏 议 大 夫 , 使 于 吴 越 。 是 时 , 江 、 淮 不 通 , 凡 使 吴 越 者 皆 泛 海 , 而 多 风 波 之 患 。 22 | 希 尧 过 海 , 遭 大 风 , 左 右 皆 恐 惧 , 希 尧 曰 “ 吾 平 生 不 欺 , 汝 等 恃 吾 , 可 无 恐 也 ” 已 而 风 亦 止 。 历 莱 、 怀 、 棣 三 州 刺 史 。 出 帝 时 , 为 吏 部 侍 郎 , 判 东 、 西 铨 事 , 累 迁 礼 部 尚 书 。 卒 , 年 七 十 九 , 赠 太 子 少 保 。 23 | ○ 张 允 张 允 , 镇 州 人 也 。 少 事 镇 州 为 张 文 礼 参 军 。 唐 庄 宗 讨 张 文 礼 , 允 脱 身 降 , 庄 宗 系 之 狱 , 文 礼 败 , 乃 出 之 为 魏 州 功 曹 。 赵 在 礼 辟 节 度 推 官 , 历 沧 、 兖 二 镇 掌 书 记 。 入 为 监 察 御 史 , 累 迁 水 部 员 外 郎 , 知 制 诰 。 废 帝 皇 子 重 美 为 河 南 尹 , 掌 六 军 , 以 允 刚 介 , 乃 拜 允 给 事 中 , 为 六 军 判 官 。 24 | 罢 , 迁 左 散 骑 常 侍 。 晋 高 祖 即 位 , 屡 赦 天 下 , 允 为 《 驳 赦 论 》 以 献 曰 “ 管 子 曰 : 凡 赦 者 小 利 而 大 害 , 久 而 不 胜 其 祸 。 无 赦 者 小 害 而 大 利 , 久 而 不 胜 其 福 。 又 汉 之 吴 汉 疾 笃 , 帝 问 汉 所 欲 言 。 汉 曰 : 惟 愿 陛 下 无 赦 尔 。 25 | 盖 行 赦 不 以 为 恩 , 不 行 赦 不 以 为 无 恩 , 罚 有 罪 故 也 。 自 古 皆 以 水 旱 则 降 德 音 而 宥 过 , 开 狴 牢 而 出 囚 , 冀 感 天 心 以 救 其 灾 者 , 非 也 。 假 有 二 人 之 讼 者 , 一 有 罪 而 一 无 罪 , 若 有 罪 者 见 舍 , 则 无 罪 者 衔 冤 。 此 乃 致 灾 之 道 , 非 救 灾 之 术 也 。 26 | 至 使 小 人 遇 天 灾 , 则 皆 喜 而 相 劝 以 为 恶 , 曰 : 国 将 赦 矣 , 必 舍 我 以 救 灾 。 如 此 , 则 是 教 民 为 恶 也 。 夫 天 之 为 道 , 福 善 而 祸 淫 。 27 | 若 舍 恶 人 而 变 灾 为 福 , 则 是 天 又 喜 人 为 恶 也 。 凡 天 之 降 灾 , 所 以 警 戒 人 主 节 嗜 欲 , 务 勤 俭 , 恤 鳏 寡 , 正 刑 罚 而 已 ” 是 时 , 晋 高 祖 方 好 臣 下 有 言 , 览 之 大 喜 。 28 | 允 事 汉 为 吏 部 侍 郎 , 隐 帝 诛 戮 大 臣 , 京 师 皆 恐 , 允 常 退 朝 不 敢 还 家 , 止 于 相 国 寺 。 周 太 祖 以 兵 入 京 师 , 允 匿 于 佛 殿 承 尘 , 坠 而 卒 , 年 六 十 五 。 ○ 王 松 王 松 , 父 徽 , 为 唐 僖 宗 宰 相 。 29 | 松 举 进 士 , 后 唐 时 , 历 刑 部 郎 中 , 唐 末 , 从 事 方 镇 。 晋 高 祖 镇 太 原 , 辟 松 节 度 判 官 。 晋 高 祖 即 位 , 拜 右 谏 议 大 夫 , 累 拜 工 部 尚 书 。 出 帝 北 迁 , 萧 翰 立 许 王 从 益 于 京 师 , 以 松 为 左 丞 相 。 汉 高 祖 入 洛 , 先 遣 人 驰 诏 东 京 百 官 尝 授 伪 命 者 皆 焚 之 , 使 勿 自 疑 , 由 是 御 史 台 悉 敛 百 官 伪 敕 焚 之 。 30 | 松 以 手 指 其 胸 , 引 郭 子 仪 自 诮 , 以 语 人 曰 “ 此 乃 二 十 四 考 中 书 令 也 ” 闻 者 笑 之 。 后 松 子 仁 宝 为 李 守 贞 河 中 支 使 , 守 贞 反 , 松 以 子 故 上 书 自 陈 , 高 祖 怜 之 , 但 使 解 职 而 已 。 松 有 田 城 东 , 岁 时 往 来 京 师 , 以 疾 卒 。 ○ 裴 皞 裴 皞 , 字 司 东 , 河 东 人 也 。 31 | 裴 氏 自 晋 、 魏 以 来 , 世 为 名 族 , 居 燕 者 号 “ 东 眷 ” , 居 凉 者 号 “ 西 眷 ” , 居 河 东 者 号 “ 中 眷 ” 。 皞 出 于 名 家 , 而 容 止 端 秀 , 性 刚 急 , 直 而 无 隐 。 少 好 学 , 唐 光 化 中 举 进 士 , 拜 校 书 郎 、 拾 遗 、 补 阙 。 事 梁 为 翰 林 学 士 、 中 书 舍 人 。 事 后 唐 为 礼 部 侍 郎 。 皞 喜 论 议 , 每 陈 朝 廷 阙 失 , 多 斥 权 臣 。 32 | 改 太 子 宾 客 , 以 老 拜 兵 部 尚 书 致 仕 。 晋 高 祖 起 为 工 部 尚 书 , 复 以 老 告 , 拜 右 仆 射 致 仕 。 卒 , 年 八 十 五 , 赠 太 子 太 保 。 皞 以 文 学 在 朝 廷 久 , 宰 相 马 胤 孙 、 桑 维 翰 , 皆 皞 礼 部 所 放 进 士 也 。 33 | 后 胤 孙 知 举 , 放 榜 , 引 新 进 士 诣 皞 , 皞 喜 作 诗 曰 “ 门 生 门 下 见 门 生 ” 世 传 以 为 荣 。 维 翰 已 作 相 , 尝 过 皞 , 皞 不 迎 不 送 。 34 | 人 或 问 之 , 皞 曰 “ 我 见 桑 公 于 中 书 , 庶 寮 也 。 桑 公 见 我 于 私 第 , 门 生 也 。 何 送 迎 之 有 ” 人 亦 以 为 当 。 ○ 王 仁 裕 王 仁 裕 , 字 德 辇 , 天 水 人 也 。 少 不 知 书 , 以 狗 马 弹 射 为 乐 , 年 二 十 五 始 就 学 , 而 为 人 俊 秀 , 以 文 辞 知 名 秦 、 陇 间 。 秦 帅 辟 为 秦 州 节 度 判 官 。 35 | 秦 州 入 于 蜀 , 仁 裕 因 事 蜀 为 中 书 舍 人 、 翰 林 学 士 。 唐 庄 宗 平 蜀 , 仁 裕 事 唐 , 复 为 秦 州 节 度 判 官 。 王 思 同 镇 兴 元 , 辟 为 从 事 。 思 同 留 守 西 京 , 以 为 判 官 。 废 帝 举 兵 凤 翔 , 思 同 战 败 , 废 帝 得 仁 裕 , 闻 其 名 不 杀 , 置 之 军 中 。 36 | 自 废 帝 起 事 , 至 其 入 立 , 驰 檄 诸 镇 , 诏 书 、 告 命 皆 仁 裕 为 之 。 久 之 , 以 都 官 郎 中 充 翰 林 学 士 。 晋 高 祖 入 立 , 罢 职 为 郎 中 , 历 司 封 左 司 郎 中 、 谏 议 大 夫 。 汉 高 祖 时 , 复 为 翰 林 学 士 承 旨 , 累 迁 户 部 尚 书 , 罢 为 兵 部 尚 书 、 太 子 少 保 。 显 德 三 年 卒 , 年 七 十 七 , 赠 太 子 少 师 。 37 | 仁 裕 性 晓 音 律 , 晋 高 祖 初 定 雅 乐 , 宴 群 臣 于 永 福 殿 , 奏 黄 钟 , 仁 裕 闻 之 曰 “ 音 不 纯 肃 而 无 和 声 , 当 有 争 者 起 于 禁 中 ” 已 而 两 军 校 斗 升 龙 门 外 , 声 闻 于 内 , 人 以 为 神 。 喜 为 诗 。 其 少 也 , 尝 梦 剖 其 肠 胃 , 以 西 江 水 涤 之 , 顾 见 江 中 沙 石 皆 为 篆 籀 之 文 , 由 是 文 思 益 进 。 38 | 乃 集 其 平 生 所 作 诗 万 馀 首 为 百 卷 , 号 《 西 江 集 》 。 仁 裕 与 和 凝 于 五 代 时 皆 以 文 章 知 名 , 又 尝 知 贡 举 , 仁 裕 门 生 王 溥 、 凝 门 生 范 质 , 皆 至 宰 相 , 时 称 其 得 人 。 ○ 裴 羽 裴 羽 , 字 用 化 , 其 父 贽 , 相 唐 僖 宗 , 官 至 司 空 。 39 | 羽 以 一 品 子 为 河 南 寿 安 尉 。 事 梁 为 御 史 台 主 簿 , 改 监 察 御 史 。 唐 明 宗 时 , 为 吏 部 郎 中 , 与 右 散 骑 常 侍 陆 崇 使 于 闽 , 为 海 风 所 飘 至 钱 塘 。 40 | 是 时 , 吴 越 王 钱 镠 与 安 重 诲 有 隙 , 唐 方 绝 镠 朝 贡 , 羽 等 被 留 经 岁 , 而 崇 以 疾 卒 。 后 镠 遣 羽 还 , 羽 求 载 崇 尸 与 俱 归 。 镠 初 不 许 , 羽 以 语 感 动 镠 , 镠 恻 然 许 之 , 因 附 羽 表 自 归 。 明 宗 得 镠 表 大 喜 , 由 是 吴 越 复 通 于 中 国 。 41 | 羽 护 崇 丧 至 京 师 , 及 其 橐 装 还 其 家 , 士 人 皆 多 羽 之 义 。 羽 , 周 太 祖 时 为 左 散 骑 常 侍 , 卒 , 赠 户 部 尚 书 。 ○ 王 延 王 延 , 字 世 美 , 郑 州 长 丰 人 也 。 少 好 学 , 尝 以 赋 谒 梁 相 李 琪 , 琪 为 之 称 誉 , 荐 为 即 墨 县 令 。 冯 道 作 相 , 与 延 故 人 , 召 拜 左 补 阙 。 迁 水 部 员 外 郎 , 知 制 诰 。 拜 中 书 舍 人 , 权 知 贡 举 。 42 | 吏 部 尚 书 卢 文 纪 与 故 相 崔 协 有 隙 。 是 时 , 协 子 颀 方 举 进 士 , 文 纪 谓 延 曰 “ 吾 尝 誉 子 于 朝 , 贡 举 选 士 , 当 求 实 效 , 无 以 虚 名 取 人 。 昔 有 越 人 善 泅 , 生 子 方 晬 , 其 母 浮 之 水 上 。 人 怪 而 问 之 , 则 曰 : 其 父 善 泅 , 子 必 能 之 。 43 | 若 是 可 乎 ” 延 退 而 笑 曰 “ 卢 公 之 言 , 为 崔 协 也 , 恨 其 父 遂 及 其 子 邪 ” 明 年 , 选 颀 甲 科 , 人 皆 称 其 公 。 累 迁 刑 部 尚 书 , 以 太 子 少 保 致 仕 。 卒 , 年 七 十 三 。 延 为 人 重 然 诺 , 与 其 弟 规 相 友 爱 , 五 代 之 际 , 称 其 家 法 焉 。 ○ 马 重 绩 马 重 绩 , 字 洞 微 , 其 先 出 于 北 狄 , 而 世 事 军 中 。 44 | 重 绩 少 学 数 术 , 明 太 一 、 五 纪 、 八 象 、 《 三 统 大 历 》 , 居 于 太 原 。 唐 庄 宗 镇 太 原 , 每 用 兵 征 伐 , 必 以 问 之 , 重 绩 所 言 无 不 中 , 拜 大 理 司 直 。 明 宗 时 , 废 不 用 。 晋 高 祖 以 太 原 拒 命 , 废 帝 遣 兵 围 之 , 势 甚 危 急 , 命 重 绩 筮 之 , 遇 《 同 人 》 , 曰 “ 天 火 之 象 , 乾 建 而 离 明 。 45 | 健 者 君 之 德 也 , 明 者 南 面 而 向 之 , 所 以 治 天 下 也 。 同 人 者 人 所 同 也 , 必 有 同 我 者 焉 。 《 易 》 曰 : 战 乎 乾 。 乾 , 西 北 也 。 又 曰 : 相 见 乎 离 。 离 , 南 方 也 。 其 同 我 者 自 北 而 南 乎 。 乾 , 西 北 也 , 战 而 胜 , 其 九 月 十 月 之 交 乎 ” 是 岁 九 月 , 契 丹 助 晋 击 败 唐 军 , 晋 遂 有 天 下 。 46 | 拜 重 绩 太 子 右 赞 善 大 夫 , 迁 司 天 监 。 明 年 , 张 从 宾 反 , 命 重 绩 筮 之 , 遇 《 随 》 , 曰 “ 南 瞻 析 木 , 木 不 自 续 , 虚 而 动 之 , 动 随 其 覆 。 岁 将 秋 矣 , 无 能 为 也 ” 七 月 而 从 宾 败 。 高 祖 大 喜 , 赐 以 良 马 、 器 币 。 天 福 三 年 , 重 绩 上 言 “ 历 象 , 王 者 所 以 正 一 气 之 元 , 宣 万 邦 之 命 。 47 | 而 古 今 所 纪 , 考 审 多 差 , 《 宣 明 》 气 朔 正 而 星 度 不 验 , 《 崇 玄 》 五 星 得 而 岁 差 一 日 , 以 《 宣 明 》 之 气 朔 , 合 《 崇 玄 》 之 五 星 , 二 历 相 参 , 然 后 符 合 。 自 前 世 诸 历 , 皆 起 天 正 十 一 月 为 岁 首 , 用 太 古 甲 子 为 上 元 , 积 岁 愈 多 , 差 阔 愈 甚 。 48 | 臣 辄 合 二 历 , 创 为 新 法 , 以 唐 天 宝 十 四 载 乙 未 为 上 元 , 雨 水 正 月 中 气 为 气 首 ” 诏 下 司 天 监 赵 仁 锜 、 张 文 皓 等 考 覈 得 失 。 仁 锜 等 言 “ 明 年 庚 子 正 月 朔 , 用 重 绩 历 考 之 , 皆 合 无 舛 ” 乃 下 诏 班 行 之 , 号 《 调 元 历 》 。 49 | 行 之 数 岁 辄 差 , 遂 不 用 。 重 绩 又 言 “ 漏 刻 之 法 , 以 中 星 考 昼 夜 为 一 百 刻 , 八 刻 六 十 分 刻 之 二 十 为 一 时 , 时 以 四 刻 十 分 为 正 , 此 自 古 所 用 也 。 今 失 其 传 , 以 午 正 为 时 始 , 下 侵 未 四 刻 十 分 而 为 午 。 由 是 昼 夜 昏 晓 , 皆 失 其 正 , 请 依 古 改 正 ” 从 之 。 重 绩 卒 年 六 十 四 。 50 | ○ 赵 延 义 赵 延 义 , 字 子 英 , 秦 州 人 也 。 曾 祖 省 躬 通 数 术 , 避 乱 于 蜀 。 父 温 珪 , 事 蜀 王 建 为 司 天 监 , 每 为 建 占 吉 凶 , 小 不 中 , 辄 加 诘 责 。 温 珪 临 卒 , 戒 其 子 孙 曰 “ 数 术 , 吾 世 业 , 然 吾 仕 乱 国 , 得 罪 而 几 死 者 数 矣 。 子 孙 能 以 佗 道 仕 进 者 , 不 必 为 也 ” 然 延 义 少 亦 以 此 仕 蜀 为 司 天 监 。 51 | 蜀 亡 , 仕 唐 为 星 官 。 延 义 兼 通 三 式 , 颇 善 相 人 。 契 丹 灭 晋 , 延 义 随 虏 至 镇 州 。 李 筠 、 白 再 荣 谋 逐 麻 答 归 汉 , 犹 豫 未 决 , 延 义 假 述 数 术 赞 成 之 。 52 | 周 太 祖 自 魏 以 兵 入 京 师 , 太 祖 召 延 义 问 “ 汉 祚 短 促 者 , 天 数 邪 ” 延 义 言 “ 王 者 抚 天 下 , 当 以 仁 恩 德 泽 , 而 汉 法 深 酷 , 刑 罚 枉 滥 , 天 下 称 冤 , 此 其 所 以 亡 也 ” 是 时 , 太 祖 方 以 兵 围 苏 逢 吉 、 刘 铢 第 , 欲 诛 其 族 , 闻 延 义 言 悚 然 , 因 贷 其 族 , 二 家 获 全 。 延 义 事 周 为 太 府 卿 、 判 司 天 监 , 以 疾 卒 。 53 | 卷 三 十 二 · 列 传 第 二 十 四 陆 法 和 , 不 知 何 许 人 也 。 隐 於 江 陵 百 里 洲 , 衣 食 居 处 , 一 与 苦 行 沙 门 同 。 耆 老 自 幼 见 之 , 容 色 常 不 定 , 人 莫 能 测 也 。 54 | 或 谓 自 出 嵩 高 , 遍 游 遐 迩 。 既 入 荆 州 汶 阳 郡 高 安 县 之 紫 石 山 , 无 故 舍 所 居 山 。 俄 有 蛮 贼 文 道 期 之 乱 , 时 人 以 为 预 见 萌 兆 。 及 侯 景 始 告 降 於 梁 , 法 和 谓 南 郡 朱 元 英 曰 “ 贫 道 共 檀 越 击 侯 景 去 ” 元 英 曰 “ 侯 景 为 国 立 效 , 师 云 击 之 , 何 也 。 55 | 法 和 曰 “ 正 自 如 此 ” 及 景 渡 江 , 法 和 时 在 青 溪 山 , 元 英 往 问 曰 “ 景 今 围 城 , 其 事 云 何 ” 法 和 曰 “ 凡 人 取 果 , 宜 待 熟 时 , 不 撩 自 落 。 56 | 檀 越 但 待 侯 景 熟 , 何 劳 问 也 ” 固 问 之 , 乃 曰 “ 亦 克 亦 不 克 ” 景 遣 将 任 约 击 梁 湘 东 王 於 江 陵 , 法 和 乃 诣 湘 东 乞 征 约 , 召 诸 蛮 弟 子 八 百 人 在 江 津 , 二 日 便 发 。 湘 东 遣 胡 僧 祐 领 千 馀 人 与 同 行 。 法 和 登 舰 大 笑 曰 “ 无 量 兵 马 ” 江 陵 多 神 祠 , 人 俗 恒 所 祈 祷 , 自 法 和 军 出 , 无 复 一 验 , 人 以 为 神 皆 从 行 故 也 。 57 | 至 赤 沙 湖 , 与 约 相 对 , 法 和 乘 轻 船 , 不 介 胄 , 沿 流 而 下 , 去 约 军 一 里 乃 还 。 谓 将 士 曰 “ 聊 观 彼 龙 睡 不 动 , 吾 军 之 龙 甚 自 踊 跃 , 即 攻 之 。 58 | 若 得 待 明 日 , 当 不 损 客 主 一 人 而 破 贼 , 然 有 恶 处 ” 遂 纵 火 舫 於 前 , 而 逆 风 不 便 , 法 和 执 白 羽 麾 风 , 风 势 即 返 。 约 众 皆 见 梁 兵 步 於 水 上 , 於 是 大 溃 , 皆 投 水 而 死 。 约 逃 窜 不 知 所 之 。 59 | 法 和 曰 “ 明 日 午 时 当 得 ” 及 期 而 未 得 , 人 问 之 , 法 和 曰 “ 吾 前 於 此 洲 水 干 时 建 一 刹 , 语 檀 越 等 , 此 虽 为 刹 , 实 是 贼 标 , 今 何 不 向 标 下 求 贼 也 ” 如 其 言 , 果 於 水 中 见 约 抱 刹 仰 头 , 裁 出 鼻 , 遂 擒 之 。 60 | 约 言 求 就 师 目 前 死 , 法 和 曰 “ 檀 越 有 相 , 必 不 兵 死 , 且 於 王 有 缘 , 决 无 他 虑 , 王 於 后 当 得 檀 越 力 耳 ” 湘 东 果 释 用 为 郡 守 。 及 魏 围 江 陵 , 约 以 兵 赴 救 , 力 战 焉 。 61 | 法 和 既 平 约 , 往 进 见 王 僧 辩 於 巴 陵 , 谓 曰 “ 贫 道 已 断 侯 景 一 臂 , 其 更 何 能 为 , 檀 越 宜 即 遂 取 ” 乃 请 还 , 谓 湘 东 王 曰 “ 侯 景 自 然 平 矣 , 无 足 可 虑 。 蜀 贼 将 至 , 法 和 请 守 巫 峡 待 之 ” 乃 总 诸 军 而 往 , 亲 运 石 以 填 江 。 62 | 三 日 , 水 遂 分 流 , 横 之 以 铁 锁 。 武 陵 王 纪 果 遣 蜀 兵 来 渡 , 峡 口 势 蹙 , 进 退 不 可 。 王 琳 与 法 和 经 略 , 一 战 而 殄 之 。 军 次 白 帝 , 谓 人 曰 “ 诸 葛 孔 明 可 谓 名 将 , 吾 自 见 之 。 此 城 旁 有 其 埋 弩 箭 镞 一 斛 许 ” 因 插 表 令 掘 之 , 如 其 言 。 63 | 又 尝 至 襄 阳 城 北 大 树 下 , 画 地 方 二 尺 , 令 弟 子 掘 之 , 得 一 龟 , 长 尺 半 , 以 杖 叩 之 曰 “ 汝 欲 出 不 能 得 , 已 数 百 岁 , 不 逢 我 者 , 岂 见 天 日 乎 ” 为 授 三 归 , 龟 乃 入 草 。 64 | 初 , 八 叠 山 多 恶 疾 人 , 法 和 为 采 药 疗 之 , 不 过 三 服 皆 差 , 即 求 为 弟 子 。 山 中 毒 虫 猛 兽 , 法 和 授 其 禁 戒 , 不 复 噬 螫 。 所 泊 江 湖 , 必 於 峰 侧 结 表 , 云 “ 此 处 放 生 ” 渔 者 皆 无 所 得 , 才 有 少 获 , 辄 有 大 风 雷 。 船 人 惧 而 放 之 , 风 雨 乃 定 。 晚 虽 将 兵 , 犹 禁 诸 军 渔 捕 。 65 | 有 窃 违 者 , 中 夜 猛 兽 必 来 欲 噬 之 , 或 亡 其 船 缆 。 有 小 弟 子 戏 截 蛇 头 , 来 诣 法 和 。 法 和 曰 “ 汝 何 意 杀 蛇 ” 因 指 以 示 之 , 弟 子 乃 见 蛇 头 齰 裤 裆 而 不 落 。 法 和 使 忏 悔 , 为 蛇 作 功 德 。 又 有 人 以 牛 试 刀 , 一 下 而 头 断 , 来 诣 法 和 。 66 | 法 和 曰 “ 有 一 断 头 牛 , 就 卿 征 命 殊 急 , 若 不 为 作 功 德 , 一 月 内 报 至 ” 其 人 弗 信 , 少 日 果 死 。 法 和 又 为 人 置 宅 图 墓 , 以 避 祸 求 福 。 67 | 尝 谓 人 曰 “ 勿 系 马 於 碓 ” 其 人 行 过 乡 曲 , 门 侧 有 碓 , 因 系 马 於 其 柱 。 入 门 中 , 忆 法 和 戒 , 走 出 将 解 之 , 马 已 毙 矣 。 68 | 梁 元 帝 以 法 和 为 都 督 、 郢 州 刺 史 , 封 江 乘 县 公 。 法 和 不 称 臣 , 其 启 文 朱 印 名 上 , 自 称 司 徒 。 梁 元 帝 谓 其 仆 射 王 褒 曰 “ 我 未 尝 有 意 用 陆 为 三 公 , 而 自 称 何 也 ” 褒 曰 “ 彼 既 以 道 术 自 命 , 容 是 先 知 ” 梁 元 帝 以 法 和 功 业 稍 重 , 遂 就 加 司 徒 , 都 督 、 刺 史 如 故 。 69 | 部 曲 数 千 人 , 通 呼 为 弟 子 , 唯 以 道 术 为 化 , 不 以 法 狱 加 人 。 又 列 肆 之 内 , 不 立 市 丞 牧 佐 之 法 , 无 人 领 受 , 但 以 空 槛 籥 在 道 间 , 上 开 一 孔 受 钱 。 贾 客 店 人 随 货 多 少 , 计 其 估 限 , 自 委 槛 中 。 行 掌 之 司 , 夕 方 开 取 , 条 其 孔 目 , 输 之 於 库 。 70 | 又 法 和 平 常 言 若 不 出 口 , 时 有 所 论 , 则 雄 辩 无 敌 , 然 犹 带 蛮 音 。 善 为 攻 战 具 。 在 江 夏 , 大 聚 兵 舰 , 欲 袭 襄 阳 而 入 武 关 。 梁 元 帝 使 止 之 , 法 和 曰 “ 法 和 是 求 佛 之 人 , 尚 不 希 释 梵 天 王 坐 处 , 岂 规 王 位 。 71 | 但 於 空 王 佛 所 与 主 上 有 香 火 因 缘 , 见 主 人 应 有 报 至 , 故 求 援 耳 。 今 既 被 疑 , 是 业 定 不 可 改 也 ” 於 是 设 供 食 , 具 大 ボ 薄 饼 。 及 魏 举 兵 , 法 和 自 郢 入 汉 口 , 将 赴 江 陵 。 72 | 梁 元 帝 使 人 逆 之 曰 “ 此 自 能 破 贼 , 但 镇 郢 州 , 不 须 动 也 ” 法 和 乃 还 州 , 垩 其 城 门 , 着 粗 白 布 衫 、 布 裤 、 邪 巾 , 大 绳 束 腰 , 坐 苇 席 , 终 日 乃 脱 之 。 及 闻 梁 元 帝 败 灭 , 复 取 前 凶 服 着 之 , 哭 泣 受 吊 。 梁 人 入 魏 , 果 见 ボ 饼 焉 。 73 | 法 和 始 於 百 里 洲 造 寿 王 寺 , 既 架 佛 殿 , 更 截 梁 柱 , 曰 “ 后 四 十 许 年 佛 法 当 遭 雷 电 , 此 寺 幽 僻 , 可 以 免 难 ” 及 魏 平 荆 州 , 宫 室 焚 烬 , 总 管 欲 发 取 寿 王 佛 殿 , 嫌 其 材 短 , 乃 停 。 后 周 氏 灭 佛 法 , 此 寺 隔 在 陈 境 , 故 不 及 难 。 天 保 六 年 春 , 清 河 王 岳 进 军 临 江 , 法 和 举 州 入 齐 。 74 | 文 宣 以 法 和 为 大 都 督 十 州 诸 军 事 、 太 尉 公 、 西 南 道 大 行 台 , 大 都 督 、 五 州 诸 军 事 、 荆 州 刺 史 、 安 湘 郡 公 宋 莅 为 郢 州 刺 史 , 官 爵 如 故 。 75 | 莅 弟 簉 为 散 骑 常 侍 、 仪 同 三 司 、 湘 州 刺 史 、 义 兴 县 公 。 梁 将 侯 瑱 来 逼 江 夏 , 齐 军 弃 城 而 退 , 法 和 与 宋 莅 兄 弟 入 朝 。 文 宣 闻 其 奇 术 , 虚 心 相 见 , 备 三 公 卤 簿 , 於 城 南 十 二 里 供 帐 以 待 之 。 法 和 遥 见 邺 城 , 下 马 禹 步 。 76 | 辛 术 谓 曰 “ 公 既 万 里 归 诚 , 主 上 虚 心 相 待 , 何 为 作 此 术 ” 法 和 手 持 香 炉 , 步 从 路 车 , 至 於 馆 。 明 日 引 见 , 给 通 幰 油 络 网 车 , 仗 身 百 人 。 77 | 诣 阙 通 名 , 不 称 官 爵 , 不 称 臣 , 但 云 荆 山 居 士 。 文 宣 宴 法 和 及 其 徒 属 於 昭 阳 殿 , 赐 法 和 钱 百 万 、 物 千 段 、 甲 第 一 区 、 田 一 百 顷 、 奴 婢 二 百 人 , 生 资 什 物 称 是 , 宋 莅 千 段 , 其 馀 仪 同 、 刺 史 以 下 各 有 差 。 78 | 法 和 所 得 奴 婢 , 尽 免 之 , 曰 “ 各 随 缘 去 ” 钱 帛 散 施 , 一 日 便 尽 。 以 官 所 赐 宅 营 佛 寺 , 自 居 一 房 , 与 凡 人 无 异 。 三 年 间 再 为 太 尉 , 世 犹 谓 之 居 士 。 无 疾 而 告 弟 子 死 期 , 至 时 , 烧 香 礼 佛 , 坐 绳 床 而 终 。 79 | 浴 讫 将 敛 , 尸 小 , 缩 止 三 尺 许 。 文 宣 令 开 棺 视 之 , 空 棺 而 已 。 法 和 书 其 所 居 壁 而 涂 之 , 及 剥 落 , 有 文 曰 “ 十 年 天 子 为 尚 可 , 百 日 天 子 急 如 火 , 周 年 天 子 递 代 坐 ” 又 曰 “ 一 母 生 三 天 , 两 天 共 五 年 ” 说 者 以 为 娄 太 后 生 三 天 子 , 自 孝 昭 即 位 , 至 武 成 传 位 后 主 , 共 五 年 焉 。 80 | 法 和 在 荆 郢 , 有 少 姬 , 年 可 二 十 馀 , 自 称 越 姥 , 身 披 法 服 , 不 嫁 , 恒 随 法 和 东 西 。 或 与 其 私 通 十 有 馀 年 。 今 者 赐 弃 , 别 更 他 淫 。 有 司 考 验 并 实 。 越 姥 因 尔 改 适 , 生 子 数 人 。 王 琳 , 字 子 珩 , 会 稽 山 阴 人 也 。 父 显 嗣 , 梁 湘 东 王 国 常 侍 。 81 | 琳 本 兵 家 , 元 帝 居 藩 , 琳 姊 妹 并 入 后 庭 见 幸 , 琳 由 此 未 弱 冠 得 在 左 右 。 少 好 武 , 遂 为 将 帅 。 太 清 二 年 , 侯 景 渡 江 , 遣 琳 献 米 万 石 。 82 | 未 至 , 都 城 陷 , 乃 中 江 沉 米 , 轻 舸 还 荆 州 。 稍 迁 岳 阳 内 史 , 以 军 功 封 建 宁 县 侯 。 侯 景 遣 将 宋 子 仙 据 郢 州 , 琳 攻 克 之 , 擒 子 仙 。 又 随 王 僧 辩 破 景 。 83 | 后 拜 湘 州 刺 史 。 琳 果 劲 绝 人 , 又 能 倾 身 下 士 , 所 得 赏 物 , 不 以 入 家 。 麾 下 万 人 , 多 是 江 淮 群 盗 。 平 景 之 勋 , 与 杜 龛 俱 为 第 一 , 恃 宠 纵 暴 於 建 业 。 王 僧 辩 禁 之 不 可 , 惧 将 为 乱 , 启 请 诛 之 。 84 | 琳 亦 疑 祸 , 令 长 史 陆 纳 率 部 曲 前 赴 湘 州 , 身 径 上 江 陵 。 将 行 , 谓 纳 等 曰 “ 吾 若 不 返 , 子 将 安 之 ” 咸 曰 “ 请 死 相 报 ” 泣 而 别 。 及 至 , 帝 以 下 吏 , 而 廷 尉 卿 黄 罗 汉 、 太 府 卿 张 载 宣 喻 琳 军 。 陆 纳 等 及 军 人 并 哭 对 使 者 , 莫 肯 受 命 , 乃 执 黄 罗 汉 , 杀 张 载 。 85 | 载 性 深 刻 , 为 帝 所 信 , 荆 州 疾 之 如 仇 , 故 纳 等 因 人 之 欲 , 抽 肠 系 马 脚 , 使 绕 而 走 , 肠 尽 气 绝 , 又 脔 割 备 五 刑 而 斩 之 。 梁 元 遣 王 僧 辩 讨 纳 , 纳 等 败 走 长 沙 。 是 时 湘 州 未 平 , 武 陵 王 兵 又 甚 盛 , 江 陵 公 私 恐 惧 , 人 有 异 图 。 纳 启 申 琳 罪 , 请 复 本 位 , 永 为 奴 婢 。 梁 元 乃 锁 琳 送 长 沙 。 86 | 时 纳 兵 出 方 战 , 会 琳 至 , 僧 辩 升 诸 楼 车 以 示 之 。 纳 等 投 戈 俱 拜 , 举 军 皆 哭 , 曰 “ 乞 王 郎 入 城 , 即 出 ” 及 放 琳 入 , 纳 等 乃 降 , 湘 州 平 。 仍 复 本 位 , 使 琳 拒 萧 纪 。 纪 平 , 授 衡 州 刺 史 。 梁 元 性 多 忌 , 以 琳 所 部 甚 众 , 又 得 众 心 , 故 出 之 岭 外 , 又 受 都 督 、 广 州 刺 史 。 87 | 其 友 主 书 李 膺 , 帝 所 任 遇 , 琳 告 之 曰 “ 琳 蒙 拔 擢 , 常 欲 毕 命 以 报 国 恩 。 今 天 下 未 平 , 迁 琳 岭 外 , 如 有 万 一 不 虞 , 安 得 琳 力 。 忖 官 正 疑 琳 耳 。 88 | 琳 分 望 有 限 , 可 得 与 官 争 为 帝 乎 。 何 不 以 琳 为 雍 州 刺 史 , 使 镇 武 宁 , 琳 自 放 兵 作 田 , 为 国 御 捍 。 若 警 急 , 动 静 相 知 。 89 | 孰 若 远 弃 岭 南 , 相 去 万 里 , 一 日 有 变 , 将 欲 如 何 。 琳 非 愿 长 坐 荆 南 , 正 以 国 计 如 此 耳 ” 膺 然 其 言 , 不 敢 启 , 故 遂 率 其 众 镇 岭 南 。 梁 元 为 魏 围 逼 , 乃 征 琳 赴 援 , 除 湘 州 刺 史 。 琳 师 次 长 沙 , 知 魏 平 江 陵 , 已 立 梁 王 詧 , 乃 为 梁 元 举 哀 , 三 军 缟 素 。 遣 别 将 侯 平 率 舟 师 攻 梁 。 90 | 琳 屯 兵 长 沙 , 传 檄 诸 方 , 为 进 趋 之 计 。 时 长 沙 藩 王 萧 韶 及 上 游 诸 将 推 琳 主 盟 。 侯 平 虽 不 能 渡 江 , 频 破 梁 军 , 又 以 琳 兵 威 不 接 , 翻 更 不 受 指 麾 。 琳 遣 将 讨 之 , 不 克 , 又 师 老 兵 疲 不 能 进 。 乃 遣 使 奉 表 诣 齐 , 并 献 驯 象 。 又 使 献 款 於 魏 , 求 其 妻 子 。 亦 称 臣 於 梁 。 91 | 陈 霸 先 既 杀 王 僧 辩 , 推 立 敬 帝 , 以 侍 中 司 空 征 。 琳 不 从 命 , 乃 大 营 楼 舰 , 将 图 义 举 。 琳 将 帅 各 乘 一 舰 , 每 行 , 战 舰 以 千 数 , 以 “ 野 猪 ” 为 名 。 陈 武 帝 遣 将 侯 安 都 、 周 文 育 等 诛 琳 , 仍 受 梁 禅 。 92 | 安 都 叹 曰 “ 我 其 败 乎 , 师 无 名 矣 ” 逆 战 於 沌 口 , 琳 乘 平 肩 舆 , 执 钺 而 麾 之 , 禽 安 都 、 文 育 , 其 馀 无 所 漏 。 唯 以 周 铁 虎 一 人 背 恩 , 斩 之 。 锁 安 都 、 文 育 置 琳 所 坐 舰 中 , 令 一 阉 竖 监 守 之 。 93 | 琳 乃 移 湘 州 军 府 就 郢 城 , 带 甲 十 万 , 练 兵 於 白 水 浦 。 琳 巡 军 而 言 曰 “ 可 以 为 勤 王 之 师 矣 , 温 太 真 何 人 哉 ” 江 南 渠 帅 熊 昙 朗 、 周 迪 怀 贰 , 琳 遣 李 孝 钦 、 樊 猛 与 余 孝 顷 同 讨 之 。 三 将 军 败 , 并 为 敌 所 囚 。 安 都 、 文 育 等 尽 逃 还 建 业 。 94 | 初 , 魏 克 江 陵 之 时 , 永 嘉 王 庄 年 甫 七 岁 , 逃 匿 人 家 , 后 琳 迎 还 湘 中 , 卫 送 东 下 。 及 敬 帝 立 , 出 质 於 齐 , 请 纳 庄 为 梁 主 。 95 | 文 宣 遣 兵 援 送 , 仍 遣 兼 中 书 令 李 騊 駼 册 拜 琳 为 梁 丞 相 、 都 督 中 外 诸 军 、 录 尚 书 事 。 舍 人 辛 悫 、 游 诠 之 等 赍 玺 书 江 表 宣 劳 , 自 琳 以 下 皆 有 颁 赐 。 96 | 琳 乃 遣 兄 子 叔 宝 率 所 部 十 州 刺 史 子 弟 赴 邺 , 奉 庄 纂 梁 祚 於 郢 州 。 庄 授 琳 侍 中 、 使 持 节 、 大 将 军 、 中 书 监 , 改 封 安 城 郡 公 , 其 馀 并 依 齐 朝 前 命 。 97 | 及 陈 霸 先 即 位 , 琳 乃 辅 庄 次 於 濡 须 口 。 齐 遣 扬 州 道 行 台 慕 容 俨 率 众 临 江 , 为 其 声 援 。 陈 遣 安 州 刺 史 吴 明 彻 江 中 夜 上 , 将 袭 湓 城 。 琳 遣 巴 陵 太 守 任 忠 大 败 之 , 明 彻 仅 以 身 免 。 琳 兵 因 东 下 , 陈 遣 司 空 侯 安 都 等 拒 之 。 侯 瑱 等 以 琳 军 方 盛 , 引 军 入 芜 湖 避 之 。 时 西 南 风 忽 至 , 琳 谓 得 天 道 , 将 直 取 扬 州 。 98 | 侯 瑱 等 徐 出 芜 湖 , 蹑 其 后 。 比 及 兵 交 , 西 南 风 翻 为 瑱 用 。 琳 兵 放 火 燧 以 掷 船 者 , 皆 反 烧 其 船 。 琳 船 舰 溃 乱 , 兵 士 投 水 死 十 二 三 , 其 馀 皆 弃 船 上 岸 , 为 陈 军 所 杀 殆 尽 。 99 | 初 琳 命 左 长 史 袁 泌 、 御 史 中 丞 刘 仲 威 同 典 兵 侍 卫 庄 , 及 军 败 , 泌 遂 降 陈 , 仲 威 以 庄 投 历 阳 。 琳 寻 与 庄 同 降 邺 都 。 孝 昭 帝 遣 琳 出 合 肥 , 鸠 集 义 故 , 更 图 进 取 。 琳 乃 缮 舰 , 分 遣 招 募 , 淮 南 伧 楚 , 皆 愿 戮 力 。 陈 合 州 刺 史 裴 景 晖 , 琳 兄 珉 之 婿 也 , 请 以 私 属 导 引 齐 师 。 100 | 孝 昭 委 琳 与 行 台 左 丞 卢 潜 率 兵 应 赴 , 沉 吟 不 决 。 景 晖 惧 事 泄 , 挺 身 归 齐 。 101 | 孝 昭 赐 琳 玺 书 , 令 镇 寿 阳 , 其 部 下 将 帅 悉 听 以 行 , 乃 除 琳 骠 骑 大 将 军 、 开 府 仪 同 三 司 、 扬 州 刺 史 , 封 会 稽 郡 公 , 又 增 兵 秩 , 兼 给 铙 吹 。 琳 水 陆 戒 严 , 将 观 衅 而 动 。 属 陈 氏 结 好 於 齐 , 使 琳 更 听 后 图 。 琳 在 寿 阳 , 与 行 台 尚 书 卢 潜 不 协 , 更 相 是 非 , 被 召 还 邺 , 武 成 弘 而 不 问 。 102 | 除 沧 州 刺 史 , 后 以 琳 为 特 进 、 侍 中 。 所 居 屋 脊 无 故 剥 破 , 出 赤 蛆 数 升 , 落 地 化 为 血 , 蠕 蠕 而 动 。 又 有 龙 出 於 门 外 之 地 , 云 雾 起 , 昼 晦 。 103 | 会 陈 将 吴 明 彻 来 寇 , 帝 敕 领 军 将 军 尉 破 胡 等 出 援 秦 州 , 令 琳 共 为 经 略 。 104 | 琳 谓 所 亲 曰 “ 今 太 岁 在 东 南 , 岁 星 居 斗 牛 分 , 太 白 已 高 , 皆 利 为 客 , 我 将 有 丧 ” 又 谓 破 胡 曰 “ 吴 兵 甚 锐 , 宜 长 策 制 之 , 慎 勿 轻 斗 ” 破 胡 不 从 , 遂 战 , 军 大 败 , 琳 单 马 突 围 , 仅 而 获 免 。 105 | 还 至 彭 城 , 帝 令 便 赴 寿 阳 , 并 许 召 募 。 又 进 封 琳 巴 陵 郡 王 。 陈 将 吴 明 彻 进 兵 围 之 , 堰 淝 水 灌 城 , 而 皮 景 和 等 屯 於 淮 西 , 竟 不 赴 救 。 明 彻 昼 夜 攻 击 , 城 内 水 气 转 侵 , 人 皆 患 肿 , 死 病 相 枕 。 106 | 从 七 月 至 十 月 , 城 陷 被 执 , 百 姓 泣 而 从 之 。 吴 明 彻 恐 其 为 变 , 杀 之 城 东 北 二 十 里 , 时 年 四 十 八 , 哭 者 声 如 雷 。 有 一 叟 以 酒 脯 来 酹 , 尽 哀 , 收 其 血 , 怀 之 而 去 。 传 首 建 康 , 悬 之 於 市 。 { 窃 以 朝 市 迁 贸 , 传 骨 梗 之 风 , 历 运 推 移 , 表 忠 贞 之 迹 。 故 典 午 将 灭 , 徐 广 为 晋 家 遗 老 。 107 | 当 涂 已 谢 , 马 孚 称 魏 室 忠 臣 。 用 能 播 美 於 前 书 , 垂 名 於 后 世 。 108 | 梁 故 建 宁 公 琳 , 洛 滨 馀 胄 , 沂 川 旧 族 , 立 功 代 邸 , 效 绩 中 朝 , 当 离 乱 之 辰 , 总 方 伯 之 任 。 尔 乃 轻 躬 殉 主 , 以 身 许 国 , 实 追 踪 於 往 彦 , 信 踵 武 於 前 修 。 而 天 厌 梁 德 , 上 思 匡 继 , 徒 蕴 包 胥 之 念 , 终 遘 苌 弘 之 眚 。 洎 王 业 光 启 , 鼎 祚 有 归 , 於 是 远 迹 山 东 , 寄 命 河 北 。 109 | 虽 轻 旅 臣 之 叹 , 犹 怀 客 卿 之 礼 , 感 兹 知 己 , 忘 此 捐 躯 。 至 使 身 没 九 泉 , 头 行 万 里 。 诚 复 马 革 裹 尸 , 遂 其 生 平 之 志 。 原 野 暴 骸 , 会 彼 人 臣 之 节 。 110 | 然 身 首 异 处 , 有 足 悲 者 。 封 树 靡 卜 , 良 可 怆 焉 。 玚 早 簉 末 席 , 降 薛 君 之 吐 握 , 荷 魏 公 之 知 遇 。 是 用 沾 巾 雨 袂 , 痛 可 识 之 颜 。 回 肠 疾 首 , 切 犹 生 之 面 。 伏 惟 圣 恩 博 厚 , 明 诏 爰 发 , 赦 王 经 之 哭 , 许 田 横 之 葬 , 玚 虽 刍 贱 , 窃 亦 有 心 。 琳 经 莅 寿 阳 , 颇 存 遗 爱 。 曾 游 江 右 , 非 无 馀 德 。 111 | 比 肩 东 閤 之 吏 , 继 踵 西 园 之 宾 , 愿 归 彼 境 , 还 修 窀 穸 。 庶 孤 坟 既 筑 , 或 飞 衔 土 之 燕 。 丰 碑 式 树 , 时 留 堕 泪 之 人 。 近 故 旧 王 绾 等 已 有 论 牒 , 仰 蒙 制 议 , 不 遂 所 陈 。 昔 廉 公 告 逝 , 即 淝 川 而 建 茔 域 。 孙 叔 云 亡 , 仍 芍 陂 而 植 楸 槚 。 由 此 言 之 , 抑 有 其 例 。 不 使 寿 春 城 下 , 唯 传 报 葛 之 人 。 112 | 沧 洲 岛 上 , 独 有 悲 田 之 客 。 昧 死 陈 祈 , 伏 待 刑 宪 。 陵 嘉 其 志 节 。 又 明 彻 亦 数 梦 琳 求 首 , 并 为 启 陈 主 而 许 之 。 113 | 仍 与 开 府 仪 同 主 簿 刘 韶 慧 等 持 其 首 还 於 淮 南 , 权 瘗 八 公 山 侧 , 义 故 会 葬 者 数 千 人 。 玚 等 乃 间 道 北 归 , 别 议 迎 接 。 寻 有 扬 州 人 茅 知 胜 等 五 人 密 送 葬 柩 达 於 邺 。 赠 十 五 州 诸 军 事 、 扬 州 刺 史 、 侍 中 、 特 进 、 开 府 、 录 尚 书 事 , 谥 曰 忠 武 王 , 葬 给 辒 辌 车 。 琳 体 貌 闲 雅 , 立 发 委 地 , 喜 怒 不 形 於 色 。 114 | 虽 无 学 业 , 而 强 记 内 敏 , 军 府 佐 吏 千 数 , 皆 识 其 姓 名 。 刑 罚 不 滥 , 轻 财 爱 士 , 得 将 卒 之 心 。 少 任 将 帅 , 屡 经 丧 乱 , 雅 有 忠 义 之 节 。 虽 本 图 不 遂 , 邺 人 亦 以 此 重 之 , 待 遇 甚 厚 。 及 败 , 为 陈 军 所 执 , 吴 明 彻 欲 全 之 , 而 其 下 将 领 多 琳 故 吏 , 争 来 致 请 , 并 相 资 给 , 明 彻 由 此 忌 之 , 故 及 於 难 。 115 | 当 时 田 夫 野 老 , 知 与 不 知 , 莫 不 为 之 歔 欷 流 泣 。 观 其 诚 信 感 物 , 虽 李 将 军 之 恂 恂 善 诱 , 殆 无 以 加 焉 。 琳 十 七 子 。 长 子 敬 , 在 齐 袭 王 爵 , 武 平 末 , 通 直 常 侍 。 第 九 子 衍 , 隋 开 皇 中 开 府 仪 同 三 司 , 大 业 初 , 卒 於 渝 州 刺 史 。 卷 三 十 三 · 列 传 第 二 十 五 萧 明 , 兰 陵 人 , 梁 武 帝 长 兄 长 沙 王 懿 之 子 。 116 | 在 其 本 朝 , 甚 为 梁 武 所 亲 爱 。 少 历 显 职 , 封 浈 阳 侯 。 太 清 中 , 以 为 豫 州 刺 史 。 梁 主 既 纳 侯 景 , 诏 明 率 水 陆 诸 军 趋 彭 城 , 大 图 进 取 。 117 | 又 命 兖 州 刺 史 南 康 嗣 王 会 理 总 驭 群 帅 , 指 授 方 略 。 明 渡 淮 未 几 , 官 军 破 之 , 尽 俘 其 众 。 魏 帝 升 门 楼 , 亲 引 见 明 及 诸 将 帅 , 释 其 禁 , 送 於 晋 阳 。 世 宗 礼 明 甚 重 , 谓 之 曰 “ 先 王 与 梁 主 和 好 十 有 馀 年 , 闻 彼 礼 佛 文 , 常 云 奉 为 魏 主 , 并 及 先 王 , 此 甚 是 梁 主 厚 意 。 不 谓 一 朝 失 信 , 致 此 纷 扰 。 118 | 自 出 师 薄 伐 , 无 战 不 克 , 无 城 不 陷 , 今 自 欲 和 , 非 是 力 屈 。 境 上 之 事 , 知 非 梁 主 本 心 , 当 是 侯 景 违 命 扇 动 耳 。 119 | 侯 可 遣 使 谘 论 , 若 犹 存 先 王 分 义 , 重 成 通 和 者 , 吾 不 敢 违 先 王 之 旨 , 侯 及 诸 人 并 即 放 还 ” 於 是 使 人 以 明 书 告 梁 主 , 梁 主 乃 致 书 以 慰 世 宗 。 120 | 天 保 六 年 , 梁 元 为 西 魏 所 灭 , 显 祖 诏 立 明 为 梁 主 , 前 所 获 梁 将 湛 海 珍 等 皆 听 从 明 归 , 令 上 党 王 涣 率 众 以 送 。 121 | 是 时 梁 太 尉 王 僧 辩 、 司 空 陈 霸 先 在 建 邺 , 推 晋 安 王 方 智 为 丞 相 。 显 祖 赐 僧 辩 、 霸 先 玺 书 , 僧 辩 未 奉 诏 。 上 党 王 进 军 , 明 又 与 僧 辩 书 , 往 复 再 三 , 陈 祸 福 , 僧 辩 初 不 纳 。 既 而 上 党 王 破 东 关 , 斩 裴 之 横 , 江 表 危 惧 , 僧 辩 乃 启 上 党 求 纳 明 , 遣 舟 舰 迎 接 。 王 飨 梁 朝 将 士 , 及 与 明 刑 牲 歃 血 , 载 书 而 盟 。 122 | 於 是 梁 舆 东 度 , 齐 师 北 反 。 侍 中 裴 英 起 卫 送 明 入 建 邺 , 遂 称 尊 号 , 改 承 圣 四 年 为 天 成 元 年 , 大 赦 天 下 , 宇 文 黑 獭 、 贼 詧 等 不 在 赦 例 。 以 方 智 为 太 子 , 授 王 僧 辩 大 司 马 。 明 上 表 遣 第 二 息 章 驰 到 京 都 , 拜 谢 宫 阙 。 123 | 冬 , 霸 先 袭 杀 僧 辩 , 复 立 方 智 , 以 明 为 太 傅 、 建 安 王 。 霸 先 奉 表 朝 廷 , 云 僧 辩 阴 谋 篡 逆 , 故 诛 之 。 方 智 请 称 臣 , 永 为 藩 国 , 齐 遣 行 台 司 马 恭 及 梁 人 盟 於 历 阳 。 明 年 , 诏 征 明 。 霸 先 犹 称 藩 , 将 遣 使 送 明 , 会 明 疽 发 背 死 。 124 | 梁 将 王 琳 在 江 上 与 霸 先 相 抗 , 显 祖 遣 兵 纳 梁 永 嘉 王 萧 庄 主 梁 祀 。 125 | 九 年 二 月 , 自 湓 城 济 江 , 三 月 , 即 帝 位 於 郢 州 , 年 号 天 启 , 王 琳 总 其 军 国 , 追 谥 明 曰 闵 皇 帝 。 明 年 , 庄 为 陈 人 所 败 , 遂 入 朝 , 封 为 侯 。 126 | 朝 廷 许 以 兴 复 , 竟 不 果 。 后 主 亡 之 日 , 庄 在 邺 饮 气 而 死 。 萧 祗 , 字 敬 式 , 梁 武 弟 南 平 王 伟 之 子 也 。 少 聪 敏 , 美 容 仪 。 127 | 在 梁 封 定 襄 侯 , 位 东 扬 州 刺 史 。 於 时 江 左 承 平 , 政 宽 人 慢 , 祗 独 莅 以 严 切 , 梁 武 悦 之 。 迁 北 兖 州 刺 史 。 太 清 二 年 , 侯 景 围 建 邺 。 128 | 祗 闻 台 城 失 守 , 遂 来 奔 。 以 武 定 七 年 至 邺 , 文 襄 令 魏 收 、 邢 邵 与 相 接 对 。 历 位 太 子 少 傅 , 领 平 阳 王 师 , 封 清 河 郡 公 。 齐 天 保 初 , 授 右 光 禄 大 夫 , 领 国 子 祭 酒 。 时 梁 元 帝 平 侯 景 , 复 与 齐 通 好 , 文 宣 欲 放 祗 等 还 南 。 俄 而 西 魏 克 江 陵 , 遂 留 邺 都 , 卒 。 赠 中 书 监 、 车 骑 大 将 军 、 扬 州 刺 史 。 129 | 萧 退 , 梁 武 帝 弟 司 空 鄱 阳 王 恢 之 子 也 。 退 在 梁 封 湘 潭 侯 , 位 青 州 刺 史 。 建 邺 陷 , 与 从 兄 祗 俱 入 东 魏 。 齐 天 保 中 , 位 金 紫 光 禄 大 夫 , 卒 。 130 | 子 慨 , 深 沉 有 礼 , 乐 善 好 学 , 攻 草 隶 书 。 南 士 中 称 为 长 者 。 历 著 作 佐 郎 , 待 诏 文 林 馆 , 卒 於 司 徒 从 事 中 郎 。 萧 放 , 字 希 逸 , 随 父 祗 至 邺 。 祗 卒 , 放 居 丧 以 孝 闻 。 所 居 庐 室 前 有 二 慈 乌 来 集 , 各 据 一 树 为 巢 , 自 午 以 前 , 驯 庭 饮 啄 , 午 后 更 不 下 树 , 每 临 时 , 舒 翅 悲 鸣 , 全 似 哀 泣 。 131 | 家 人 伺 之 , 未 常 有 阙 。 时 以 为 至 孝 之 感 。 服 阕 , 袭 爵 。 武 平 中 , 待 诏 文 林 馆 。 132 | 放 性 好 文 咏 , 颇 善 丹 青 , 因 此 在 宫 中 披 览 书 史 及 近 世 诗 赋 , 监 画 工 作 屏 风 等 杂 物 见 知 , 遂 被 眷 待 。 累 迁 太 子 中 庶 子 、 散 骑 常 侍 。 徐 之 才 , 丹 阳 人 也 。 父 雄 , 事 南 齐 , 位 兰 陵 太 守 , 以 医 术 为 江 左 所 称 。 之 才 幼 而 俊 发 , 五 岁 诵 《 孝 经 》 , 八 岁 略 通 义 旨 。 133 | 曾 与 从 兄 康 造 梁 太 子 詹 事 汝 南 周 舍 宅 听 《 老 子 》 。 舍 为 设 食 , 乃 戏 之 曰 “ 徐 郎 不 用 心 思 义 , 而 但 事 食 乎 ” 之 才 答 曰 “ 盖 闻 圣 人 虚 其 心 而 实 其 腹 ” 舍 嗟 赏 之 。 年 十 三 , 召 为 太 学 生 , 粗 通 《 礼 》 、 《 易 》 。 134 | 彭 城 刘 孝 绰 、 河 东 裴 子 野 、 吴 郡 张 嵊 等 每 共 论 《 周 易 》 及 《 丧 服 》 仪 , 酧 应 如 响 。 135 | 咸 共 叹 曰 “ 此 神 童 也 ” 孝 绰 又 云 “ 徐 郎 燕 颔 , 有 班 定 远 之 相 ” 陈 郡 袁 昂 领 丹 阳 尹 , 辟 为 主 簿 , 人 务 事 宜 , 皆 被 顾 访 。 郡 廨 遭 火 , 之 才 起 望 , 夜 中 不 著 衣 , 披 红 服 帕 出 房 , 映 光 为 昂 所 见 。 136 | 功 曹 白 请 免 职 , 昂 重 其 才 术 , 仍 特 原 之 。 豫 章 王 综 出 镇 江 都 , 复 除 豫 章 王 国 左 常 侍 , 又 转 综 镇 北 主 簿 。 及 综 入 魏 , 三 军 散 走 , 之 才 退 至 吕 梁 , 桥 断 路 绝 , 遂 为 魏 统 军 石 茂 孙 所 止 。 综 入 魏 旬 月 , 位 至 司 空 。 137 | 魏 听 综 收 敛 僚 属 , 乃 访 之 才 在 彭 泗 , 启 魏 帝 云 “ 之 才 大 善 医 术 , 兼 有 机 辩 ” 诏 征 之 才 。 孝 昌 二 年 , 至 洛 , 敕 居 南 馆 , 礼 遇 甚 优 。 从 祖 謇 子 践 启 求 之 才 还 宅 。 之 才 药 石 多 效 , 又 窥 涉 经 史 , 发 言 辩 捷 , 朝 贤 竞 相 要 引 , 为 之 延 誉 。 武 帝 时 , 封 昌 安 县 侯 。 138 | 天 平 中 , 齐 神 武 征 赴 晋 阳 , 常 在 内 馆 , 礼 遇 稍 厚 。 武 定 四 年 , 自 散 骑 常 侍 转 秘 书 监 。 文 宣 作 相 , 普 加 黜 陟 。 139 | 杨 愔 以 其 南 土 之 人 , 不 堪 典 秘 书 , 转 授 金 紫 光 禄 大 夫 , 以 魏 收 代 领 之 。 之 才 甚 怏 怏 不 平 。 之 才 少 解 天 文 , 兼 图 谶 之 学 , 共 馆 客 宋 景 业 参 校 吉 凶 , 知 午 年 必 有 革 易 , 因 高 德 政 启 之 。 文 宣 闻 而 大 悦 。 时 自 娄 太 后 及 勋 贵 臣 咸 云 关 西 既 是 劲 敌 , 恐 其 有 挟 天 子 令 诸 侯 之 辞 , 不 可 先 行 禅 代 事 。 140 | 之 才 独 云 “ 千 人 逐 兔 , 一 人 得 之 , 诸 人 咸 息 。 须 定 大 业 , 何 容 翻 欲 学 人 ” 又 援 引 证 据 , 备 有 条 目 , 帝 从 之 。 登 祚 后 , 弥 见 亲 密 。 之 才 非 唯 医 术 自 进 , 亦 为 首 唱 禅 代 , 又 戏 谑 滑 稽 , 言 无 不 至 , 於 是 大 被 狎 昵 。 寻 除 侍 中 , 封 池 阳 县 伯 。 141 | 见 文 宣 政 令 转 严 , 求 出 , 除 赵 州 刺 史 , 竟 不 获 述 职 , 犹 为 弄 臣 。 皇 建 二 年 , 除 西 兖 州 刺 史 。 未 之 官 , 武 明 皇 太 后 不 豫 , 之 才 疗 之 , 应 手 便 愈 , 孝 昭 赐 采 帛 千 段 、 锦 四 百 匹 。 之 才 既 善 医 术 , 虽 有 外 授 , 顷 即 征 还 。 既 博 识 多 闻 , 由 是 於 方 术 尤 妙 。 大 宁 二 年 春 , 武 明 太 后 又 病 。 142 | 之 才 弟 之 范 为 尚 药 典 御 , 敕 令 诊 候 。 内 史 皆 令 呼 太 后 为 石 婆 , 盖 有 俗 忌 , 故 改 名 以 厌 制 之 。 143 | 之 范 出 告 之 才 曰 “ 童 谣 云 : 周 里 跂 求 伽 , 豹 祠 嫁 石 婆 , 斩 冢 作 媒 人 , 唯 得 一 量 紫 綖 靴 。 今 太 后 忽 改 名 , 私 所 致 怪 ” 之 才 曰 “ 跂 求 伽 , 胡 言 去 已 。 豹 祠 嫁 石 婆 , 岂 有 好 事 。 斩 冢 作 媒 人 , 但 令 合 葬 自 斩 冢 。 唯 得 紫 綖 靴 者 , 得 至 四 月 , 何 者 。 144 | 紫 之 为 字 此 下 系 , 綖 者 熟 , 当 在 四 月 之 中 ” 之 范 问 靴 是 何 义 。 之 才 曰 “ 靴 者 革 旁 化 , 宁 是 久 物 ” 至 四 月 一 日 , 后 果 崩 。 有 人 患 脚 跟 肿 痛 , 诸 医 莫 能 识 。 之 才 曰 “ 蛤 精 疾 也 , 由 乘 船 入 海 , 垂 脚 水 中 。 疾 者 曰 “ 实 曾 如 此 ” 之 才 为 剖 得 蛤 子 二 , 大 如 榆 荚 。 又 有 以 骨 为 刀 子 靶 者 , 五 色 班 斓 。 145 | 之 才 曰 “ 此 人 瘤 也 ” 问 得 处 , 云 於 古 冢 见 髑 髅 额 骨 长 数 寸 , 试 削 视 , 有 文 理 , 故 用 之 。 其 明 悟 多 通 如 此 。 天 统 四 年 , 累 迁 尚 书 左 仆 射 , 俄 除 兖 州 刺 史 , 特 给 铙 吹 一 部 。 之 才 医 术 最 高 , 偏 被 命 召 。 146 | 武 成 酒 色 过 度 , 怳 惚 不 恒 , 曾 病 发 , 自 云 初 见 空 中 有 五 色 物 , 稍 近 , 变 成 一 美 妇 人 , 去 地 数 丈 , 亭 亭 而 立 。 食 顷 , 变 为 观 世 音 。 之 才 云 “ 此 色 欲 多 , 大 虚 所 致 ” 即 处 汤 方 , 服 一 剂 , 便 觉 稍 远 , 又 服 , 还 变 成 五 色 物 , 数 剂 汤 , 疾 竟 愈 。 147 | 帝 每 发 动 , 蹔 遣 骑 追 之 , 针 药 所 加 , 应 时 必 效 , 故 频 有 端 执 之 举 。 入 秋 , 武 成 小 定 , 更 不 发 动 。 和 士 开 欲 依 次 转 进 , 以 之 才 附 籍 兖 州 , 即 是 本 属 , 遂 奏 附 除 刺 史 , 以 胡 长 仁 为 左 仆 射 , 士 开 为 右 仆 射 。 及 十 月 , 帝 又 病 动 , 语 士 开 云 “ 恨 用 之 才 外 任 , 使 我 辛 苦 ” 其 月 八 日 , 敕 驿 追 之 才 。 148 | 帝 以 十 日 崩 , 之 才 十 一 日 方 到 。 既 无 所 及 , 复 还 赴 州 。 在 职 无 所 侵 暴 , 但 不 甚 闲 法 理 , 颇 亦 疏 慢 , 用 舍 自 由 。 五 年 冬 , 后 主 征 之 才 。 寻 左 仆 射 阙 , 之 才 曰 “ 自 可 复 禹 之 绩 ” 武 平 元 年 , 重 除 尚 书 左 仆 射 。 之 才 於 和 士 开 、 陆 令 萱 母 子 曲 尽 卑 狎 , 二 家 苦 疾 , 救 护 百 端 。 由 是 迁 尚 书 令 , 封 西 阳 郡 王 。 149 | 祖 珽 执 政 , 除 之 才 侍 中 、 太 子 太 师 。 之 才 恨 曰 “ 子 野 沙 汰 我 ” 珽 目 疾 , 故 以 师 旷 比 之 。 之 才 聪 辩 强 识 , 有 兼 人 之 敏 , 尤 好 剧 谈 体 语 , 公 私 言 聚 , 多 相 嘲 戏 。 郑 道 育 常 戏 之 才 为 师 公 。 150 | 之 才 曰 “ 既 为 汝 师 , 又 为 汝 公 , 在 三 之 义 , 顿 居 其 两 ” 又 嘲 王 昕 姓 云 “ 有 言 则 讠 王 , 近 犬 便 狂 , 加 颈 足 而 为 马 , 施 角 尾 而 为 羊 ” 卢 元 明 因 戏 之 才 云 “ 卿 姓 是 未 入 人 。 151 | 名 是 字 之 误 , 之 当 为 乏 也 ” 即 答 云 “ 卿 姓 在 亡 为 虐 , 在 丘 为 虚 , 生 男 则 为 虏 , 养 马 则 为 驴 ” 又 尝 与 朝 士 出 游 , 遥 望 群 犬 竞 走 , 诸 人 试 令 目 之 。 152 | 之 才 即 应 声 云 “ 为 是 宋 鹊 , 为 是 韩 卢 , 为 逐 李 斯 东 走 , 为 负 帝 女 南 徂 ” 李 谐 於 广 坐 , 因 称 其 父 名 曰 “ 卿 嗜 熊 白 生 否 ” 之 才 曰 “ 平 平 耳 ” 又 曰 “ 卿 此 言 於 理 平 否 ” 谐 遽 出 避 之 , 道 逢 其 甥 高 德 正 。 153 | 德 正 曰 “ 舅 颜 色 何 不 悦 ” 谐 告 之 故 。 德 正 径 造 坐 席 , 连 索 熊 白 。 之 才 谓 坐 者 曰 “ 个 人 讳 底 ” 众 莫 知 。 之 才 曰 “ 生 不 为 人 所 知 , 死 不 为 人 所 讳 , 此 何 足 问 ” 唐 邕 、 白 建 方 贵 , 时 人 言 云 “ 并 州 赫 赫 唐 与 白 ” 之 才 蔑 之 。 154 | 元 日 , 对 邕 为 诸 令 史 祝 曰 “ 见 卿 等 位 当 作 唐 、 白 ” 又 以 小 史 好 嚼 笔 , 故 尝 执 管 就 元 文 遥 口 曰 “ 借 君 齿 ” 其 不 逊 如 此 。 历 事 诸 帝 , 以 戏 狎 得 宠 。 武 成 生 齻 牙 , 问 诸 医 。 尚 药 典 御 邓 宣 文 以 实 对 , 武 成 怒 而 挞 之 。 后 以 问 之 才 , 拜 贺 曰 “ 此 是 智 牙 , 生 智 牙 者 聪 明 长 寿 ” 武 成 悦 而 赏 之 。 155 | 为 仆 射 时 , 语 人 曰 “ 我 在 江 东 , 见 徐 勉 作 仆 射 , 朝 士 莫 不 佞 之 。 156 | 今 我 亦 是 徐 仆 射 , 无 一 人 佞 我 , 何 由 可 活 ” 之 才 妻 魏 广 阳 王 妹 , 之 才 从 文 襄 求 得 为 妻 。 和 士 开 知 之 , 乃 淫 其 妻 。 之 才 遇 见 而 避 之 , 退 曰 “ 妨 少 年 戏 笑 ” 其 宽 纵 如 此 。 年 八 十 , 卒 。 赠 司 徒 公 、 录 尚 书 事 , 谥 曰 文 明 。 长 子 林 , 字 少 卿 , 太 尉 司 马 。 157 | 弟 之 范 , 亦 医 术 见 知 , 位 太 常 卿 , 特 听 袭 之 才 爵 西 阳 王 。 入 周 , 授 仪 同 大 将 军 。 开 皇 中 卒 。 卷 三 十 五 · 列 传 第 二 十 七 裴 让 之 , 字 士 礼 。 年 十 六 丧 父 , 殆 不 胜 哀 , 其 母 辛 氏 泣 抚 之 曰 “ 弃 我 灭 性 , 得 为 孝 子 乎 ” 由 是 自 勉 。 158 | 辛 氏 高 明 妇 则 , 又 闲 礼 度 。 夫 丧 , 诸 子 多 幼 弱 , 广 延 师 友 , 或 亲 自 教 授 。 内 外 亲 属 有 吉 凶 礼 制 , 多 取 则 焉 。 让 之 少 好 学 , 有 文 俊 辩 , 早 得 声 誉 。 魏 天 平 中 举 秀 才 , 对 策 高 第 。 累 迁 屯 田 主 客 郎 中 , 省 中 语 曰 “ 能 赋 诗 , 裴 让 之 ” 为 太 原 公 开 府 记 室 。 与 杨 愔 友 善 , 相 遇 则 清 谈 竟 日 。 159 | 愔 每 云 “ 此 人 风 流 警 拔 , 裴 文 季 为 不 亡 矣 ” 梁 使 至 , 帝 令 让 之 摄 主 客 郎 。 第 二 弟 诹 之 奔 关 右 , 兄 弟 五 人 皆 拘 系 。 神 武 问 曰 “ 诹 之 何 在 ” 答 曰 “ 昔 吴 、 蜀 二 国 , 诸 葛 兄 弟 各 得 遂 心 , 况 让 之 老 母 在 , 君 臣 分 定 , 失 忠 与 孝 , 愚 夫 不 为 。 伏 愿 明 公 以 诚 信 待 物 , 若 以 不 信 处 物 , 物 亦 安 能 自 信 。 160 | 以 此 定 霸 , 犹 却 行 而 求 道 耳 ” 神 武 善 其 言 , 兄 弟 俱 释 。 历 文 襄 大 将 军 主 簿 , 兼 中 书 舍 人 , 后 兼 散 骑 常 侍 , 聘 梁 。 文 襄 尝 入 朝 , 让 之 导 引 , 容 仪 蕴 藉 , 文 襄 目 之 曰 “ 士 礼 佳 舍 人 ” 迁 长 兼 中 书 侍 郎 , 领 舍 人 。 齐 受 禅 , 静 帝 逊 居 别 宫 , 与 诸 臣 别 , 让 之 流 涕 歔 欷 。 以 参 掌 仪 注 , 封 宁 都 县 男 。 161 | 帝 欲 以 为 黄 门 郎 , 或 言 其 体 重 , 不 堪 趋 侍 , 乃 除 清 河 太 守 。 至 郡 未 几 , 杨 愔 谓 让 之 诸 弟 曰 “ 我 与 贤 兄 交 款 , 企 闻 善 政 。 适 有 人 从 清 河 来 , 云 奸 吏 敛 迹 , 盗 贼 清 靖 。 期 月 之 期 , 翻 然 更 速 ” 清 河 有 二 豪 吏 田 转 贵 、 孙 舍 兴 久 吏 奸 猾 , 多 有 侵 削 , 因 事 遂 胁 人 取 财 。 计 赃 依 律 不 至 死 。 162 | 让 之 以 其 乱 法 , 杀 之 。 时 清 河 王 岳 为 司 州 牧 , 遣 部 从 事 案 之 。 163 | 侍 中 高 德 政 旧 与 让 之 不 协 , 案 奏 言 “ 当 陛 下 受 禅 之 时 , 让 之 眷 恋 魏 朝 , 呜 咽 流 涕 , 比 为 内 官 , 情 非 所 愿 ” 既 而 杨 愔 请 救 之 , 云 “ 罪 不 合 死 ” 文 宣 大 怒 , 谓 愔 曰 “ 欲 得 与 裴 让 之 同 冢 耶 ” 於 是 无 敢 言 者 。 事 奏 , 竟 赐 死 於 家 。 诹 之 , 字 士 正 , 少 好 儒 学 , 释 褐 太 学 博 士 。 164 | 尝 从 常 景 借 书 百 卷 , 十 许 日 便 返 。 景 疑 其 不 能 读 , 每 卷 策 问 , 应 答 无 遗 。 景 叹 曰 “ 应 奉 五 行 俱 下 , 祢 衡 一 览 便 记 , 今 复 见 之 於 裴 生 矣 ” 杨 愔 阖 门 改 葬 , 托 诹 之 顿 作 十 馀 墓 志 , 文 皆 可 观 。 165 | 让 之 、 诹 之 及 皇 甫 和 弟 亮 并 知 名 於 洛 下 , 时 人 语 曰 “ 诹 胜 於 让 , 和 不 如 亮 ” 司 空 高 乾 致 书 曰 “ 相 屈 为 户 曹 参 军 ” 诹 之 复 书 不 受 署 。 沛 王 开 大 司 马 府 , 辟 为 记 室 。 166 | 迁 邺 后 , 诹 之 留 在 河 南 , 西 魏 领 军 独 孤 信 入 据 金 墉 , 以 诹 之 为 开 府 属 , 号 曰 “ 洛 阳 遗 彦 ” 信 败 , 诹 之 居 南 山 , 洛 州 刺 史 王 元 轨 召 为 中 从 事 。 西 师 忽 至 , 寻 退 , 遂 随 西 师 入 关 。 周 文 帝 以 为 大 行 台 仓 曹 郎 中 , 卒 。 赠 徐 州 刺 史 。 谳 之 , 字 士 平 , 七 岁 便 勤 学 , 早 知 名 。 累 迁 司 徒 主 簿 。 167 | 杨 愔 每 称 叹 云 “ 河 东 士 族 , 京 官 不 少 , 唯 此 家 兄 弟 , 全 无 乡 音 ” 谳 之 虽 年 少 , 不 妄 交 游 , 唯 与 陇 西 辛 术 、 赵 郡 李 绘 、 顿 丘 李 构 、 清 河 崔 瞻 为 忘 年 之 友 。 昭 帝 梓 宫 将 还 邺 , 转 仪 曹 郎 , 尤 悉 历 代 故 事 、 仪 注 , 丧 礼 皆 能 裁 正 。 168 | 为 永 昌 太 守 , 客 旅 过 郡 , 出 私 财 供 给 , 人 间 所 无 , 预 代 下 出 , 为 吏 人 所 怀 。 齐 亡 仕 周 , 卒 伊 川 太 守 。 169 | 皇 甫 和 , 字 长 谐 , 安 定 朝 那 人 , 其 先 因 官 寓 居 汉 中 。 祖 澄 , 南 齐 秦 、 梁 二 州 刺 史 。 父 徽 , 字 子 玄 , 梁 安 定 、 略 阳 二 郡 守 。 魏 正 始 二 年 , 随 其 妻 父 夏 侯 道 迁 入 魏 , 道 迁 别 上 勋 书 , 欲 以 徽 为 元 谋 。 170 | 徽 曰 “ 创 谋 之 始 , 本 不 关 预 , 虽 贪 荣 赏 , 内 愧 於 心 ” 遂 拒 而 不 许 。 梁 州 刺 史 羊 灵 祐 重 其 敦 实 , 表 为 征 虏 府 司 马 , 卒 。 和 十 一 而 孤 , 母 夏 侯 氏 , 才 明 有 礼 则 , 亲 授 以 经 书 。 及 长 , 深 沉 有 雅 量 , 尤 明 礼 仪 , 宗 亲 吉 凶 , 多 相 谘 访 。 卒 於 济 阴 太 守 。 李 构 , 字 祖 基 , 黎 阳 人 。 祖 平 , 魏 尚 书 仆 射 。 171 | 构 少 以 方 正 见 称 , 释 褐 开 府 参 军 , 累 迁 谯 州 刺 史 , 卒 。 构 从 父 弟 庶 , 魏 大 司 农 谐 子 。 方 雅 好 学 , 风 流 规 检 , 甚 有 家 风 。 稍 迁 临 漳 令 。 《 魏 书 》 出 , 庶 与 卢 斐 、 王 松 年 等 讼 其 不 平 , 并 系 狱 。 172 | 魏 收 书 王 慧 龙 自 云 太 原 人 , 又 言 王 琼 不 善 事 。 卢 同 附 《 卢 玄 传 》 。 李 平 为 陈 留 人 , 云 其 家 贫 贱 。 173 | 故 斐 等 致 讼 , 语 杨 愔 云 “ 魏 收 合 诛 ” 愔 党 助 魏 收 , 遂 白 显 祖 罪 斐 等 , 并 髡 头 , 鞭 二 百 。 庶 死 於 临 漳 狱 中 , 庶 兄 岳 痛 之 , 终 身 不 历 临 漳 县 门 。 张 宴 之 , 字 熙 德 。 幼 孤 有 至 性 , 为 母 郑 氏 教 诲 , 动 依 礼 典 。 从 尔 朱 荣 平 元 颢 , 赐 爵 武 成 子 , 累 迁 尚 书 二 千 石 郎 中 。 174 | 高 岳 征 颍 川 , 复 以 为 都 督 中 兵 参 军 兼 记 室 。 宴 之 文 士 , 兼 有 武 干 , 每 与 岳 帷 帐 之 谋 , 又 常 以 短 兵 接 刃 , 亲 获 首 级 , 深 为 岳 所 嗟 赏 。 天 保 初 , 文 宣 为 高 阳 王 纳 宴 之 女 为 妃 , 令 赴 晋 阳 成 礼 。 宴 之 后 园 陪 宴 , 坐 客 皆 赋 诗 。 175 | 宴 之 诗 云 “ 天 下 有 道 , 主 明 臣 直 , 虽 休 勿 休 , 永 贻 世 则 ” 文 宣 笑 曰 “ 得 卿 箴 讽 , 深 以 慰 怀 ” 后 行 北 徐 州 事 , 寻 即 真 , 为 吏 人 所 爱 。 176 | 御 史 崔 子 武 督 察 州 郡 , 至 北 徐 州 , 无 所 案 劾 , 唯 得 百 姓 所 制 《 清 德 颂 》 数 篇 。 乃 叹 曰 “ 本 求 罪 状 , 遂 闻 颂 声 ” 迁 兖 州 刺 史 , 未 拜 , 卒 。 赠 齐 州 刺 史 。 陆 卬 , 字 云 驹 。 177 | 少 机 悟 , 美 风 神 , 好 学 不 倦 , 博 览 群 书 , 五 经 多 通 大 义 。 善 属 文 , 甚 为 河 间 邢 邵 所 赏 。 邵 又 与 卬 父 子 彰 交 游 , 尝 谓 子 彰 曰 “ 吾 以 卿 老 蚌 , 遂 出 明 珠 , 意 欲 为 群 拜 纪 可 乎 ” 由 是 名 誉 日 高 , 儒 雅 搢 绅 , 尤 所 推 许 。 178 | 起 家 员 外 散 骑 侍 郎 , 历 文 襄 大 将 军 主 簿 , 中 书 舍 人 , 兼 中 书 侍 郎 , 以 本 职 兼 太 子 洗 马 。 自 梁 、 魏 通 和 , 岁 有 交 聘 , 卬 每 兼 官 燕 接 。 在 帝 席 赋 诗 , 卬 必 先 成 , 虽 未 能 尽 工 , 以 敏 速 见 美 。 除 中 书 侍 郎 , 修 国 史 。 以 父 忧 去 职 , 居 丧 尽 礼 , 哀 毁 骨 立 。 诏 以 本 官 起 。 179 | 文 襄 时 镇 邺 , 嘉 其 至 行 , 亲 诣 门 以 慰 勉 之 。 卬 母 魏 上 庸 公 主 , 初 封 蓝 田 , 高 明 妇 人 也 , 甚 有 志 操 。 卬 昆 季 六 人 , 并 主 所 生 。 180 | 故 邢 邵 常 谓 人 云 “ 蓝 田 生 玉 , 固 不 虚 矣 ” 主 教 训 诸 子 , 皆 禀 义 方 , 虽 创 巨 痛 深 , 出 於 天 性 , 然 动 依 礼 度 , 亦 母 氏 之 训 焉 。 卬 兄 弟 相 率 庐 於 墓 侧 , 负 土 成 坟 , 朝 廷 深 所 嗟 尚 , 发 诏 褒 扬 , 改 其 所 居 里 为 孝 终 里 。 181 | 服 竟 当 袭 , 不 忍 嗣 侯 。 天 保 初 , 常 山 王 荐 卬 器 干 , 文 宣 面 授 给 事 黄 门 侍 郎 , 迁 吏 部 郎 中 。 上 洛 王 思 宗 为 清 都 尹 , 辟 为 邑 中 正 , 食 贝 丘 县 干 。 遭 母 丧 , 哀 慕 毁 悴 , 殆 不 胜 丧 , 至 沉 笃 , 顿 昧 伏 枕 。 又 感 风 疾 。 182 | 第 五 弟 抟 遇 疾 临 终 , 谓 其 兄 弟 曰 “ 大 兄 尫 病 如 此 , 性 至 慈 爱 , 抟 之 死 日 , 必 不 得 使 大 兄 知 之 , 哭 泣 声 必 不 可 闻 彻 , 致 有 感 恸 ” 家 人 至 於 祖 载 , 方 始 告 之 。 卬 闻 而 悲 痛 , 一 恸 便 绝 , 年 四 十 八 。 卬 自 在 朝 , 笃 慎 固 密 , 不 说 人 短 , 不 伐 己 长 , 言 论 清 远 , 有 人 伦 鉴 裁 , 朝 野 甚 悲 惜 之 。 183 | 赠 卫 将 军 、 青 州 刺 史 , 谥 曰 文 。 所 著 文 章 十 四 卷 , 行 於 世 。 齐 之 郊 庙 诸 歌 , 多 卬 所 制 。 子 乂 嗣 , 袭 爵 始 平 侯 。 王 松 年 , 少 知 名 。 184 | 文 襄 临 并 州 , 辟 为 主 簿 , 累 迁 通 直 散 骑 常 侍 , 副 李 纬 使 梁 。 还 , 历 位 尚 书 郎 中 。 魏 收 撰 《 魏 书 》 成 , 松 年 有 谤 言 , 文 宣 怒 , 禁 止 之 , 仍 加 杖 罚 。 185 | 岁 馀 得 免 , 除 临 漳 令 , 迁 司 马 、 别 驾 、 本 州 大 中 正 。 孝 昭 擢 拜 给 事 黄 门 侍 郎 。 帝 每 赐 坐 , 与 论 政 事 , 甚 善 之 。 186 | 孝 昭 崩 , 松 年 驰 驿 至 邺 都 宣 遗 诏 , 发 言 涕 泗 , 迄 於 宣 罢 , 容 色 无 改 , 辞 吐 谐 韵 。 宣 讫 , 号 恸 自 绝 於 地 , 百 官 莫 不 感 恸 。 187 | 还 晋 阳 , 兼 侍 中 , 护 梓 宫 还 邺 。 诸 旧 臣 避 形 迹 , 无 敢 尽 哀 , 唯 松 年 哭 甚 流 涕 , 朝 士 咸 恐 。 武 成 虽 忿 松 年 恋 旧 情 切 , 亦 雅 重 之 。 以 本 官 加 散 骑 常 侍 , 食 高 邑 县 干 , 参 定 律 令 , 前 后 大 事 多 委 焉 。 兼 御 史 中 丞 。 发 晋 阳 之 邺 , 在 道 遇 疾 卒 。 赠 吏 部 尚 书 、 并 州 刺 史 , 谥 曰 平 。 第 三 子 邵 , 最 知 名 。 188 | 刘 祎 , 字 彦 英 , 彭 城 人 。 父 世 明 , 魏 兖 州 刺 史 。 祎 性 弘 裕 , 有 威 重 , 容 止 可 观 , 虽 昵 友 密 交 , 朝 夕 游 处 , 莫 不 加 敬 。 好 学 , 善 《 三 礼 》 , 吉 凶 仪 制 , 尤 所 留 心 。 魏 孝 昌 中 , 释 巾 太 学 博 士 。 189 | 累 迁 雎 州 刺 史 , 边 人 服 其 威 信 , 甚 得 疆 埸 之 和 。 190 | 世 宗 辅 政 , 降 书 褒 奖 , 云 “ 以 卿 家 世 忠 纯 , 奕 代 冠 冕 , 贤 弟 贤 子 , 并 与 吾 共 事 , 怀 抱 相 托 , 亦 自 依 然 。 宜 勖 心 力 , 以 副 所 委 , 莫 虑 不 富 贵 ” 秩 满 , 径 归 乡 里 侍 父 疾 , 竟 不 入 朝 。 父 丧 , 沉 顿 累 年 , 非 杖 不 起 。 世 宗 致 辟 , 祎 称 疾 不 动 。 五 子 , 璿 、 玘 、 璞 、 瑗 、 瓒 , 并 有 志 节 , 为 世 所 称 。 191 | 卷 三 十 六 · 列 传 第 二 十 八 邢 邵 , 字 子 才 , 河 间 鄚 人 , 魏 太 常 贞 之 后 。 父 虬 , 魏 光 禄 卿 。 邵 小 字 吉 , 少 时 有 避 , 遂 不 行 名 。 年 五 岁 , 魏 吏 部 郎 清 河 崔 亮 见 而 奇 之 , 曰 “ 此 子 后 当 大 成 , 位 望 通 显 ” 十 岁 便 能 属 文 , 雅 有 才 思 , 聪 明 强 记 , 日 诵 万 馀 言 。 192 | 族 兄 峦 , 有 人 伦 鉴 , 谓 子 弟 曰 “ 宗 室 中 有 此 儿 , 非 常 人 也 ” 少 在 洛 阳 , 会 天 下 无 事 , 与 时 名 胜 专 以 山 水 游 宴 为 娱 , 不 暇 勤 业 。 尝 因 霖 雨 , 乃 读 《 汉 书 》 , 五 日 , 略 能 遍 记 之 。 193 | 后 因 饮 谑 倦 , 方 广 寻 经 史 , 五 行 俱 下 , 一 览 便 记 , 无 所 遗 忘 。 文 章 典 丽 , 既 赡 且 速 。 年 未 二 十 , 名 动 衣 冠 。 尝 与 右 北 平 阳 固 、 河 东 裴 伯 茂 、 从 兄 罘 、 河 南 陆 道 晖 等 至 北 海 王 昕 舍 宿 饮 , 相 与 赋 诗 , 凡 数 十 首 , 皆 在 主 人 奴 处 。 旦 日 奴 行 , 诸 人 求 诗 不 得 , 邵 皆 为 诵 之 。 194 | 诸 人 有 不 认 诗 者 , 奴 还 得 本 , 不 误 一 字 。 诸 人 方 之 王 粲 。 吏 部 尚 书 陇 西 李 神 俊 大 相 钦 重 , 引 为 忘 年 之 交 。 释 巾 为 魏 宣 武 挽 郎 , 除 奉 朝 请 , 迁 著 作 佐 郎 。 195 | 深 为 领 军 元 叉 所 礼 , 叉 新 除 尚 书 令 , 神 俊 与 陈 郡 袁 翻 在 席 , 叉 令 邵 作 谢 表 , 须 臾 便 成 , 以 示 诸 宾 。 神 俊 曰 “ 邢 邵 此 表 , 足 使 袁 公 变 色 ” 孝 昌 初 , 与 黄 门 侍 郎 李 琰 之 对 典 朝 仪 。 自 孝 明 之 后 , 文 雅 大 盛 , 邵 雕 虫 之 美 , 独 步 当 时 , 每 一 文 初 出 , 京 师 为 之 纸 贵 , 读 诵 俄 遍 远 近 。 196 | 於 时 袁 翻 与 范 阳 祖 莹 位 望 通 显 , 文 笔 之 美 , 见 称 先 达 , 以 邵 藻 思 华 赡 , 深 共 嫉 之 。 每 洛 中 贵 人 拜 职 , 多 凭 邵 为 谢 表 。 尝 有 一 贵 胜 初 受 官 , 大 集 宾 食 , 翻 与 邵 俱 在 坐 。 翻 意 主 人 托 其 为 让 表 , 遂 命 邵 作 之 。 197 | 翻 甚 不 悦 , 每 告 人 云 “ 邢 家 小 儿 尝 客 作 章 表 , 自 买 黄 纸 , 写 而 送 之 ” 邵 恐 为 翻 所 害 , 乃 辞 以 疾 。 属 尚 书 令 元 罗 出 镇 青 州 , 启 为 府 司 马 。 198 | 遂 在 青 土 , 终 日 酣 赏 , 尽 山 泉 之 致 。 永 安 初 , 累 迁 中 书 侍 郎 , 所 作 诏 诰 , 文 体 宏 丽 。 及 尔 朱 荣 入 洛 , 京 师 扰 乱 , 邵 与 弘 农 杨 愔 避 地 嵩 高 山 。 普 泰 中 , 兼 给 事 黄 门 侍 郎 , 寻 为 散 骑 常 侍 。 太 昌 初 , 敕 令 恒 直 内 省 , 给 御 食 , 令 覆 按 尚 书 门 下 事 , 凡 除 大 官 , 先 问 其 可 否 , 然 后 施 行 。 199 | 除 卫 将 军 、 国 子 祭 酒 。 以 亲 老 还 乡 , 诏 所 在 特 给 兵 力 五 人 , 并 令 岁 一 入 朝 , 以 备 顾 问 。 丁 母 忧 , 哀 毁 过 礼 。 世 室 明 堂 , 显 於 周 、 夏 。 一 黉 两 学 , 盛 自 虞 、 殷 。 所 以 宗 配 上 帝 , 以 著 莫 大 之 严 。 宣 布 下 土 , 以 彰 则 天 之 轨 。 养 黄 发 以 询 哲 言 , 育 青 衿 而 敷 教 典 , 用 能 享 国 长 久 , 风 徽 万 祀 者 也 。 200 | 爰 暨 亡 秦 , 改 革 其 道 , 坑 儒 灭 学 , 以 蔽 黔 黎 。 故 九 服 分 崩 , 祚 终 二 代 。 炎 汉 勃 兴 , 更 修 儒 术 。 故 西 京 有 六 学 之 义 , 东 都 有 三 本 之 盛 。 逮 自 魏 、 晋 , 拨 乱 相 因 , 兵 革 之 中 , 学 校 不 绝 。 201 | 仰 惟 高 祖 孝 文 皇 帝 禀 圣 自 天 , 道 镜 今 古 , 列 校 序 於 乡 党 , 敦 诗 书 於 郡 国 。 但 经 始 事 殷 , 戎 轩 屡 驾 , 未 遑 多 就 , 弓 剑 弗 追 。 世 宗 统 历 , 聿 遵 先 绪 , 永 平 之 中 , 大 兴 板 筑 。 续 以 水 旱 , 戎 马 生 郊 , 虽 逮 为 山 , 还 停 一 篑 。 202 | 而 明 堂 礼 乐 之 本 , 乃 郁 荆 棘 之 林 。 胶 序 德 义 之 基 , 空 盈 牧 竖 之 迹 。 城 隍 严 固 之 重 , 阙 砖 石 之 功 。 墉 构 显 望 之 要 , 少 楼 榭 之 饰 。 加 以 风 雨 稍 侵 , 渐 致 亏 坠 。 非 所 谓 追 隆 堂 构 , 仪 刑 万 国 者 也 。 伏 闻 朝 议 以 高 祖 大 造 区 夏 , 道 侔 姬 文 , 拟 祀 明 堂 , 式 配 上 帝 。 203 | 今 若 基 址 不 修 , 乃 同 丘 畎 , 即 使 高 皇 神 享 , 阙 於 国 阳 , 宗 事 之 典 , 有 声 无 实 。 此 臣 子 所 以 匪 宁 , 亿 兆 所 以 伫 望 也 。 臣 又 闻 官 方 授 能 , 所 以 任 事 , 事 既 任 矣 , 酧 之 以 禄 。 如 此 则 上 无 旷 官 之 讥 , 下 绝 尸 素 之 谤 。 204 | 今 国 子 虽 有 学 官 之 名 , 无 教 授 之 实 , 何 异 兔 丝 燕 麦 , 南 箕 北 斗 哉 。 昔 刘 向 有 言 , 王 者 宜 兴 辟 雍 、 陈 礼 乐 以 风 天 下 。 夫 礼 乐 所 以 养 人 , 刑 法 所 以 杀 人 , 而 有 司 勤 勤 , 请 定 刑 法 , 至 於 礼 乐 , 则 曰 未 敢 。 205 | 是 敢 於 杀 人 , 不 敢 於 养 人 也 。 臣 以 为 当 今 四 海 清 平 , 九 服 宁 宴 , 经 国 要 重 , 理 应 先 营 , 脱 复 稽 延 , 则 刘 向 之 言 徵 矣 。 但 事 不 两 兴 , 须 有 进 退 。 206 | 以 臣 愚 量 , 宜 罢 尚 方 雕 靡 之 作 , 颇 省 永 宁 土 木 之 功 , 并 减 瑶 光 材 瓦 之 力 , 兼 分 石 窟 镌 琢 之 劳 , 及 诸 事 役 非 世 急 者 , 三 时 农 隙 , 修 此 数 条 。 使 辟 雍 之 礼 , 蔚 尔 而 复 兴 。 207 | 讽 诵 之 音 , 焕 然 而 更 作 , 美 榭 高 墉 严 壮 於 外 , 槐 宫 棘 寺 显 丽 於 中 。 更 明 古 今 , 重 遵 乡 饮 , 敦 进 郡 学 , 精 课 经 业 , 如 此 则 元 、 凯 可 得 之 於 上 序 , 游 、 夏 可 致 之 於 下 国 , 岂 不 休 欤 。 208 | 灵 太 后 令 曰 “ 配 飨 大 礼 , 为 国 之 本 , 比 以 戎 马 在 郊 , 未 遑 修 缮 。 累 迁 太 常 卿 、 中 书 监 , 摄 国 子 祭 酒 。 是 时 朝 臣 多 守 一 职 , 带 领 二 官 甚 少 , 邵 顿 居 三 职 , 并 是 文 学 之 首 , 当 世 荣 之 。 文 宣 幸 晋 阳 , 路 中 频 有 甘 露 之 瑞 , 朝 臣 皆 作 《 甘 露 颂 》 , 尚 书 符 令 邵 为 之 序 。 209 | 及 文 宣 皇 帝 崩 , 凶 礼 多 见 讯 访 , 敕 撰 哀 策 。 后 授 特 进 , 卒 。 邵 率 情 简 素 , 内 行 修 谨 , 兄 弟 亲 姻 之 间 , 称 为 雍 睦 。 210 | 博 览 坟 籍 , 无 不 通 晓 , 晚 年 尤 以 《 五 经 》 章 句 为 意 , 穷 其 指 要 。 吉 凶 礼 仪 , 公 私 谘 禀 , 质 疑 去 惑 , 为 世 指 南 。 每 公 卿 会 议 , 事 关 典 故 , 邵 援 笔 立 成 , 证 引 该 洽 。 帝 命 朝 章 , 取 定 俄 顷 。 词 致 宏 远 , 独 步 当 时 。 与 济 阴 温 子 升 为 文 士 之 冠 , 世 论 谓 之 温 、 邢 。 211 | 巨 鹿 魏 收 , 虽 天 才 艳 发 , 而 年 事 在 二 人 之 后 , 故 子 升 死 后 , 方 称 邢 、 魏 焉 。 虽 望 实 兼 重 , 不 以 才 位 傲 物 。 212 | 脱 略 简 易 , 不 修 威 仪 , 车 服 器 用 , 充 事 而 已 。 有 斋 不 居 , 坐 卧 恒 在 一 小 屋 。 果 饵 之 属 , 或 置 之 梁 上 , 宾 至 , 下 而 共 啖 。 天 姿 质 素 , 特 安 异 同 , 士 无 贤 愚 , 皆 能 顾 接 , 对 客 或 解 衣 觅 虱 , 且 与 剧 谈 。 有 书 甚 多 , 而 不 甚 仇 校 。 见 人 校 书 , 常 笑 曰 “ 何 愚 之 甚 , 天 下 书 至 死 读 不 可 遍 , 焉 能 始 复 校 此 。 213 | 且 误 书 思 之 更 是 一 适 ” 妻 弟 李 季 节 , 才 学 之 士 , 谓 子 才 曰 “ 世 间 人 多 不 聪 明 , 思 误 书 何 由 能 得 ” 子 才 曰 “ 若 思 不 能 得 , 便 不 劳 读 书 ” 与 妇 甚 疏 , 未 尝 内 宿 。 自 云 尝 昼 入 内 阁 , 为 狗 所 吠 , 言 毕 便 抚 掌 大 笑 。 性 好 谈 赏 , 不 能 闲 独 , 公 事 归 休 , 恒 须 宾 客 自 伴 。 事 寡 嫂 甚 谨 , 养 孤 子 恕 , 慈 爱 特 深 。 214 | 在 兖 州 , 有 都 信 云 恕 疾 , 便 忧 之 , 废 寝 食 , 颜 色 贬 损 。 及 卒 , 人 士 为 之 伤 心 , 痛 悼 虽 甚 , 竟 不 再 哭 , 宾 客 吊 慰 , 抆 泪 而 已 。 215 | 其 高 情 达 识 , 开 遣 滞 累 , 东 门 吴 以 还 , 所 未 有 也 。 有 集 三 十 卷 , 见 行 於 世 。 子 大 宝 , 有 文 情 。 孽 子 大 德 、 大 道 , 略 不 识 字 焉 。 216 | 卷 三 十 七 · 列 传 第 二 十 九 魏 收 , 字 伯 起 , 小 字 佛 助 , 巨 鹿 下 曲 阳 人 也 。 曾 祖 缉 , 祖 韶 。 父 子 建 , 字 敬 忠 , 赠 仪 同 、 定 州 刺 史 。 收 年 十 五 , 颇 已 属 文 。 及 随 父 赴 边 , 好 习 骑 射 , 欲 以 武 艺 自 达 。 217 | 荥 阳 郑 伯 调 之 曰 “ 魏 郎 弄 戟 多 少 ” 收 惭 , 遂 折 节 读 书 。 夏 月 坐 板 床 , 随 树 阴 讽 诵 , 积 年 , 板 床 为 之 锐 减 , 而 精 力 不 辍 。 以 文 华 显 。 初 除 太 学 博 士 。 218 | 及 尔 朱 荣 於 河 阴 滥 害 朝 士 , 收 亦 在 围 中 , 以 日 晏 获 免 。 吏 部 尚 书 李 神 俊 重 收 才 学 , 奏 授 司 徒 记 室 参 军 。 永 安 三 年 , 除 北 主 客 郎 中 。 219 | 节 闵 帝 立 , 妙 简 近 侍 , 诏 试 收 为 《 封 禅 书 》 , 收 下 笔 便 就 , 不 立 稿 草 , 文 将 千 言 , 所 改 无 几 。 220 | 时 黄 门 郎 贾 思 同 侍 立 , 深 奇 之 , 白 帝 曰 “ 虽 七 步 之 才 , 无 以 过 此 ” 迁 散 骑 侍 郎 , 寻 敕 典 起 居 注 , 并 修 国 史 , 兼 中 书 侍 郎 , 时 年 二 十 六 。 孝 武 初 , 又 诏 收 摄 本 职 。 文 诰 填 积 , 事 咸 称 旨 。 黄 门 郎 崔 忄 夌 从 齐 神 武 入 朝 , 熏 灼 於 世 , 收 初 不 诣 门 。 忄 夌 为 帝 登 阼 赦 , 云 “ 朕 托 体 孝 文 ” , 收 嗤 其 率 直 。 221 | 正 员 郎 李 慎 以 告 之 , 忄 夌 深 愤 忌 。 时 节 闵 帝 殂 , 令 收 为 诏 。 忄 夌 乃 宣 言 : 收 普 泰 世 出 入 帏 幄 , 一 日 造 诏 , 优 为 词 旨 , 然 则 义 旗 之 士 尽 为 逆 人 。 又 收 父 老 合 解 官 归 侍 , 南 台 将 加 弹 劾 , 赖 尚 书 辛 雄 为 言 於 中 尉 綦 俊 , 乃 解 。 收 有 贱 生 弟 仲 同 , 先 未 齿 录 , 因 此 怖 惧 , 上 籍 , 遣 还 乡 扶 侍 。 222 | 孝 武 尝 大 发 士 卒 , 狩 於 嵩 少 之 南 旬 有 六 日 。 时 天 寒 , 朝 野 嗟 怨 。 帝 与 从 官 及 诸 妃 主 , 奇 伎 异 饰 , 多 非 礼 度 。 收 欲 言 则 惧 , 欲 默 不 能 已 , 乃 上 《 南 狩 赋 》 以 讽 焉 , 时 年 二 十 七 , 虽 富 言 淫 丽 , 而 终 归 雅 正 。 223 | 帝 手 诏 报 焉 , 甚 见 褒 美 。 初 , 神 武 固 让 天 柱 大 将 军 , 魏 帝 敕 收 为 诏 , 令 遂 所 请 。 欲 加 相 国 , 问 品 秩 , 收 以 实 对 , 帝 遂 止 。 224 | 收 既 未 测 主 相 之 意 , 以 前 事 不 安 , 求 解 , 诏 许 焉 。 久 之 , 除 帝 兄 子 广 平 王 赞 开 府 从 事 中 郎 , 收 不 敢 辞 , 乃 为 《 庭 竹 赋 》 以 致 己 意 。 225 | 寻 兼 中 书 舍 人 , 与 济 阴 温 子 升 、 河 间 邢 子 才 齐 誉 , 世 号 三 才 。 时 孝 武 猜 忌 神 武 , 内 有 间 隙 , 收 遂 以 疾 固 辞 而 免 。 其 舅 崔 孝 芬 怪 而 问 之 , 收 曰 “ 惧 有 晋 阳 之 甲 ” 寻 而 神 武 南 上 , 帝 西 入 关 。 226 | 收 兼 通 直 散 骑 常 侍 , 副 王 昕 使 梁 , 昕 风 流 文 辩 , 收 辞 藻 富 逸 , 梁 主 及 其 群 臣 咸 加 敬 异 。 先 是 南 北 初 和 , 李 谐 、 卢 元 明 首 通 使 命 , 二 人 才 器 , 并 为 邻 国 所 重 。 227 | 至 此 , 梁 主 称 曰 “ 卢 、 李 命 世 , 王 、 魏 中 兴 , 未 知 后 来 复 何 如 耳 ” 收 在 馆 , 遂 买 吴 婢 入 馆 , 其 部 下 有 买 婢 者 , 收 亦 唤 取 , 遍 行 奸 秽 , 梁 朝 馆 司 皆 为 之 获 罪 。 人 称 其 才 而 鄙 其 行 。 在 途 作 《 聘 游 赋 》 , 辞 甚 美 盛 。 228 | 使 还 , 尚 书 右 仆 射 高 隆 之 求 南 货 於 昕 、 收 , 不 能 如 志 , 遂 讽 御 史 中 尉 高 仲 密 禁 止 昕 、 收 於 其 台 , 久 之 得 释 。 及 孙 搴 死 , 司 马 子 如 荐 收 , 召 赴 晋 阳 , 以 为 中 外 府 主 簿 。 以 受 旨 乖 忤 , 频 被 嫌 责 , 加 以 箠 楚 , 久 不 得 志 。 会 司 马 子 如 奉 使 霸 朝 , 收 假 其 馀 光 。 229 | 子 如 因 宴 戏 言 於 神 武 曰 “ 魏 收 天 子 中 书 郎 , 一 国 大 才 , 愿 大 王 借 以 颜 色 ” 由 此 转 府 属 , 然 未 甚 优 礼 。 收 从 叔 季 景 , 有 才 学 , 历 官 著 名 , 并 在 收 前 , 然 收 常 所 欺 忽 。 230 | 季 景 、 收 初 赴 并 , 顿 丘 李 庶 者 , 故 大 司 农 谐 之 子 也 , 以 华 辩 见 称 , 曾 谓 收 曰 “ 霸 朝 便 有 二 魏 ” 收 率 尔 曰 “ 以 从 叔 见 比 , 便 是 耶 输 之 比 卿 ” 耶 输 者 , 故 尚 书 令 陈 留 公 继 伯 之 子 也 , 愚 痴 有 名 , 好 自 入 市 肆 , 高 价 买 物 , 商 贾 共 所 嗤 玩 。 收 忽 季 景 , 故 方 之 , 不 逊 例 多 如 此 。 231 | 收 本 以 文 才 , 必 望 颖 脱 见 知 , 位 既 不 遂 , 求 修 国 史 。 崔 暹 为 言 於 文 襄 曰 “ 国 史 事 重 , 公 家 父 子 霸 王 功 业 , 皆 须 具 载 , 非 收 不 可 ” 文 襄 启 收 兼 散 骑 常 侍 , 修 国 史 。 武 定 二 年 , 除 正 常 侍 , 领 兼 中 书 侍 郎 , 仍 修 史 。 魏 帝 宴 百 僚 , 问 何 故 名 人 日 , 皆 莫 能 知 。 232 | 收 对 曰 “ 晋 议 郎 董 勋 《 答 问 礼 俗 》 云 “ 正 月 一 日 为 鸡 , 二 日 为 狗 , 三 日 为 猪 , 四 日 为 羊 , 五 日 为 牛 , 六 日 为 马 , 七 日 为 人 ” 时 邢 邵 亦 在 侧 , 甚 恧 焉 。 233 | 自 魏 、 梁 和 好 , 书 下 纸 每 云 “ 想 彼 境 内 宁 静 , 此 率 土 安 和 ” 梁 后 使 , 其 书 乃 去 “ 彼 ” 字 , 自 称 犹 著 “ 此 ” , 欲 示 无 外 之 意 。 234 | 收 定 报 书 云 “ 想 境 内 清 晏 , 今 万 国 安 和 ” 梁 人 复 书 , 依 以 为 体 。 后 神 武 入 朝 , 静 帝 授 相 国 , 固 让 , 令 收 为 启 。 235 | 启 成 呈 上 , 文 襄 时 侍 侧 , 神 武 指 收 曰 “ 此 人 当 复 为 崔 光 ” 四 年 , 神 武 於 西 门 豹 祠 宴 集 , 谓 司 马 子 如 曰 “ 魏 收 为 史 官 , 书 吾 等 善 恶 , 闻 北 伐 时 , 诸 贵 常 饷 史 官 饮 食 , 司 马 仆 射 颇 曾 饷 不 ” 因 共 大 笑 。 236 | 仍 谓 收 曰 “ 卿 勿 见 元 康 等 在 吾 目 下 趋 走 , 谓 吾 以 为 勤 劳 , 我 后 世 身 名 在 卿 手 , 勿 谓 我 不 知 ” 寻 加 兼 著 作 郎 。 收 昔 在 洛 京 , 轻 薄 尤 甚 , 人 号 云 “ 魏 收 惊 蛱 蝶 ” 文 襄 曾 游 东 山 , 令 给 事 黄 门 侍 郎 颢 等 宴 。 237 | 文 襄 曰 “ 魏 收 恃 才 无 宜 适 , 须 出 其 短 ” 往 复 数 番 , 收 忽 大 唱 曰 “ 杨 遵 彦 理 屈 已 倒 ” 愔 从 容 曰 “ 我 绰 有 馀 暇 , 山 立 不 动 , 若 遇 当 涂 , 恐 翩 翩 遂 逝 ” 当 涂 者 魏 , 翩 翩 者 蛱 蝶 也 。 文 襄 先 知 之 , 大 笑 称 善 。 238 | 文 襄 又 曰 “ 向 语 犹 微 , 宜 更 指 斥 ” 愔 应 声 曰 “ 魏 收 在 并 作 一 篇 诗 , 对 众 读 讫 , 云 : 打 从 叔 季 景 出 六 百 斛 米 , 亦 不 辨 此 。 远 近 所 知 , 非 敢 妄 语 ” 文 襄 喜 曰 “ 我 亦 先 闻 ” 众 人 皆 笑 。 收 虽 自 申 雪 , 不 复 抗 拒 , 终 身 病 之 。 侯 景 叛 入 梁 , 寇 南 境 , 文 襄 时 在 晋 阳 , 令 收 为 檄 五 十 馀 纸 , 不 日 而 就 。 239 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/data_loader.py: -------------------------------------------------------------------------------- 1 | import json 2 | import torch 3 | import numpy as np 4 | from torch.utils.data import DataLoader, Dataset 5 | from utils.common_utils import sequence_padding 6 | 7 | 8 | class ListDataset(Dataset): 9 | def __init__(self, file_path=None, data=None, tokenizer=None, max_len=None, **kwargs): 10 | self.kwargs = kwargs 11 | if isinstance(file_path, (str, list)): 12 | self.data = self.load_data(file_path, tokenizer, max_len) 13 | elif isinstance(data, list): 14 | self.data = data 15 | else: 16 | raise ValueError('The input args shall be str format file_path / list format dataset') 17 | 18 | def __len__(self): 19 | return len(self.data) 20 | 21 | def __getitem__(self, index): 22 | return self.data[index] 23 | 24 | @staticmethod 25 | def load_data(file_path, tokenizer, max_len): 26 | return file_path 27 | 28 | 29 | 30 | # 加载数据集 31 | class MyDataset(ListDataset): 32 | @staticmethod 33 | def load_data(filename, tokenizer, max_len): 34 | data = [] 35 | all_tokens = [] 36 | with open(filename, encoding='utf-8') as f: 37 | f = f.read() 38 | f = json.loads(f) 39 | for d in f: 40 | text = d['text'] 41 | labels = d['labels'] 42 | tokens = [i for i in text] 43 | if len(tokens) > max_len - 2: 44 | tokens = tokens[:max_len] 45 | tokens = ['[CLS]'] + tokens + ['[SEP]'] 46 | all_tokens.append(tokens) 47 | token_ids = tokenizer.convert_tokens_to_ids(tokens) 48 | label = [] 49 | for lab in labels: # 这里需要加上CLS的位置, lab[3]不用加1,因为是实体结尾的后一位 50 | label.append([lab[2]+1, lab[3], lab[1]]) 51 | data.append((token_ids, label)) # label为[[start, end, entity], ...] 52 | return data, all_tokens 53 | 54 | class Collate: 55 | def __init__(self, max_len, tag2id, device): 56 | self.maxlen = max_len 57 | self.tag2id = tag2id 58 | self.device = device 59 | 60 | def collate_fn(self, batch): 61 | batch_labels = [] 62 | batch_token_ids = [] 63 | batch_attention_mask = [] 64 | batch_token_type_ids = [] 65 | for i, (token_ids, text_labels) in enumerate(batch): 66 | labels = np.zeros((len(self.tag2id), self.maxlen, self.maxlen)) 67 | batch_token_ids.append(token_ids) # 前面已经限制了长度 68 | batch_attention_mask.append([1] * len(token_ids)) 69 | batch_token_type_ids.append([0] * len(token_ids)) 70 | for start, end, label in text_labels: 71 | # 排除SEP及之后的 72 | if end >= self.maxlen - 1: 73 | continue 74 | label_id = self.tag2id[label] 75 | labels[label_id, start, end] = 1 76 | batch_labels.append(labels) 77 | batch_token_ids = torch.tensor(sequence_padding(batch_token_ids, length=self.maxlen), dtype=torch.long, device=self.device) 78 | attention_mask = torch.tensor(sequence_padding(batch_attention_mask, length=self.maxlen), dtype=torch.long, device=self.device) 79 | token_type_ids = torch.tensor(sequence_padding(batch_token_type_ids, length=self.maxlen), dtype=torch.long, device=self.device) 80 | batch_labels = torch.tensor(batch_labels, dtype=torch.long, device=self.device) 81 | return batch_token_ids, attention_mask, token_type_ids, batch_labels 82 | 83 | 84 | if __name__ == "__main__": 85 | from transformers import BertTokenizer 86 | max_len = 150 87 | tokenizer = BertTokenizer.from_pretrained('model_hub/chinese-bert-wwm-ext/vocab.txt') 88 | train_dataset, train_callback = MyDataset(file_path='data/cner/mid_data/train.json', 89 | tokenizer=tokenizer, 90 | max_len=max_len) 91 | print(train_dataset[0]) 92 | 93 | with open('data/cner/mid_data/labels.json') as fp: 94 | labels = json.load(fp) 95 | id2tag = {} 96 | tag2id = {} 97 | for i,label in enumerate(labels): 98 | id2tag[i] = label 99 | tag2id[label] = i 100 | device = torch.device("cuda" if torch.cuda.is_available() else "cpu") 101 | collate = Collate(max_len=max_len, tag2id=tag2id, device=device) 102 | batch_size = 2 103 | train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=False, collate_fn=collate.collate_fn) 104 | 105 | for i, batch in enumerate(train_dataloader): 106 | print(batch[0].shape) 107 | print(batch[1].shape) 108 | print(batch[2].shape) 109 | print(batch[3].shape) 110 | break 111 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/globalpoint.py: -------------------------------------------------------------------------------- 1 | import math 2 | import torch 3 | import torch.nn as nn 4 | from transformers import BertModel, AutoModel 5 | 6 | class MultilabelCategoricalCrossentropy(nn.Module): 7 | """多标签分类的交叉熵 8 | 说明:y_true和y_pred的shape一致,y_true的元素非0即1, 1表示对应的类为目标类,0表示对应的类为非目标类。 9 | 警告:请保证y_pred的值域是全体实数,换言之一般情况下y_pred不用加激活函数,尤其是不能加sigmoid或者softmax!预测 10 | 阶段则输出y_pred大于0的类。如有疑问,请仔细阅读并理解本文。 11 | 参考:https://kexue.fm/archives/7359 12 | """ 13 | def __init__(self, **kwargs): 14 | super().__init__(**kwargs) 15 | def forward(self, y_pred, y_true): 16 | """ y_true ([Tensor]): [..., num_classes] 17 | y_pred ([Tensor]): [..., num_classes] 18 | """ 19 | y_pred = (1-2*y_true) * y_pred 20 | y_pred_pos = y_pred - (1-y_true) * 1e12 21 | y_pred_neg = y_pred - y_true * 1e12 22 | 23 | y_pred_pos = torch.cat([y_pred_pos, torch.zeros_like(y_pred_pos[..., :1])], dim=-1) 24 | y_pred_neg = torch.cat([y_pred_neg, torch.zeros_like(y_pred_neg[..., :1])], dim=-1) 25 | pos_loss = torch.logsumexp(y_pred_pos, dim=-1) 26 | neg_loss = torch.logsumexp(y_pred_neg, dim=-1) 27 | return (pos_loss + neg_loss).mean() 28 | 29 | 30 | 31 | class MyLoss(MultilabelCategoricalCrossentropy): 32 | def __init__(self, **kwargs): 33 | super().__init__(**kwargs) 34 | def forward(self, y_pred, y_true): 35 | y_true = y_true.view(y_true.shape[0]*y_true.shape[1], -1) # [btz*ner_vocab_size, seq_len*seq_len] 36 | y_pred = y_pred.view(y_pred.shape[0]*y_pred.shape[1], -1) # [btz*ner_vocab_size, seq_len*seq_len] 37 | return super().forward(y_pred, y_true) 38 | 39 | 40 | def get_sinusoid_encoding_table(n_position, d_hid, padding_idx=None): 41 | '''Returns: [seq_len, d_hid] 42 | ''' 43 | position = torch.arange(0, n_position, dtype=torch.float).unsqueeze(1) 44 | div_term = torch.exp(torch.arange(0, d_hid, 2).float() * (-math.log(10000.0) / d_hid)) 45 | embeddings_table = torch.zeros(n_position, d_hid) 46 | embeddings_table[:, 0::2] = torch.sin(position * div_term) 47 | embeddings_table[:, 1::2] = torch.cos(position * div_term) 48 | return embeddings_table 49 | 50 | 51 | class RoPEPositionEncoding(nn.Module): 52 | """旋转式位置编码: https://kexue.fm/archives/8265 53 | """ 54 | def __init__(self, max_position, embedding_size): 55 | super(RoPEPositionEncoding, self).__init__() 56 | position_embeddings = get_sinusoid_encoding_table(max_position, embedding_size) # [seq_len, hdsz] 57 | cos_position = position_embeddings[:, 1::2].repeat_interleave(2, dim=-1) 58 | sin_position = position_embeddings[:, ::2].repeat_interleave(2, dim=-1) 59 | # register_buffer是为了最外层model.to(device),不用内部指定device 60 | self.register_buffer('cos_position', cos_position) 61 | self.register_buffer('sin_position', sin_position) 62 | 63 | def forward(self, qw, seq_dim=-2): 64 | # 默认最后两个维度为[seq_len, hdsz] 65 | seq_len = qw.shape[seq_dim] 66 | qw2 = torch.stack([-qw[..., 1::2], qw[..., ::2]], dim=-1).reshape_as(qw) 67 | return qw * self.cos_position[:seq_len] + qw2 * self.sin_position[:seq_len] 68 | 69 | 70 | class EfficientGlobalPointer(nn.Module): 71 | """更加参数高效的GlobalPointer 72 | 参考:https://kexue.fm/archives/8877 73 | """ 74 | def __init__(self, hidden_size, heads, head_size, RoPE=True, max_len=512, use_bias=True, tril_mask=True): 75 | super().__init__() 76 | self.heads = heads 77 | self.head_size = head_size 78 | self.RoPE = RoPE 79 | self.tril_mask = tril_mask 80 | self.RoPE = RoPE 81 | 82 | self.p_dense = nn.Linear(hidden_size, head_size * 2, bias=use_bias) 83 | self.q_dense = nn.Linear(head_size * 2, heads * 2, bias=use_bias) 84 | if self.RoPE: 85 | self.position_embedding = RoPEPositionEncoding(max_len, head_size) 86 | 87 | def forward(self, inputs, mask=None): 88 | ''' inputs: [..., hdsz] 89 | mask: [bez, seq_len], padding部分为0 90 | ''' 91 | sequence_output = self.p_dense(inputs) # [..., head_size*2] 92 | qw, kw = sequence_output[..., :self.head_size], sequence_output[..., self.head_size:] # [..., heads, head_size] 93 | 94 | # ROPE编码 95 | if self.RoPE: 96 | qw = self.position_embedding(qw) 97 | kw = self.position_embedding(kw) 98 | 99 | # 计算内积 100 | logits = torch.einsum('bmd,bnd->bmn', qw, kw) / self.head_size**0.5 # [btz, seq_len, seq_len] 101 | bias_input = self.q_dense(sequence_output) # [..., heads*2] 102 | bias = torch.stack(torch.chunk(bias_input, self.heads, dim=-1), dim=-2).transpose(1,2) # [btz, head_size, seq_len,2] 103 | logits = logits.unsqueeze(1) + bias[..., :1] + bias[..., 1:].transpose(2, 3) # [btz, head_size, seq_len, seq_len] 104 | 105 | # 排除padding 106 | if mask is not None: 107 | attention_mask1 = 1 - mask.unsqueeze(1).unsqueeze(3) # [btz, 1, seq_len, 1] 108 | attention_mask2 = 1 - mask.unsqueeze(1).unsqueeze(2) # [btz, 1, 1, seq_len] 109 | logits = logits.masked_fill(attention_mask1.bool(), value=-float('inf')) 110 | logits = logits.masked_fill(attention_mask2.bool(), value=-float('inf')) 111 | 112 | # 排除下三角 113 | if self.tril_mask: 114 | logits = logits - torch.tril(torch.ones_like(logits), -1) * 1e12 115 | 116 | return logits 117 | 118 | 119 | class GlobalPointer(nn.Module): 120 | """全局指针模块 121 | 将序列的每个(start, end)作为整体来进行判断 122 | 参考:https://kexue.fm/archives/8373 123 | """ 124 | def __init__(self, hidden_size, heads, head_size, RoPE=True, max_len=512, use_bias=True, tril_mask=True): 125 | super().__init__() 126 | self.heads = heads 127 | self.head_size = head_size 128 | self.RoPE = RoPE 129 | self.tril_mask = tril_mask 130 | self.RoPE = RoPE 131 | 132 | self.dense = nn.Linear(hidden_size, heads * head_size * 2, bias=use_bias) 133 | if self.RoPE: 134 | self.position_embedding = RoPEPositionEncoding(max_len, head_size) 135 | 136 | 137 | 138 | def forward(self, inputs, mask=None): 139 | ''' inputs: [..., hdsz] 140 | mask: [bez, seq_len], padding部分为0 141 | ''' 142 | # [batchsize, 150, 8*64*2] 143 | sequence_output = self.dense(inputs) # [..., heads*head_size*2] 144 | # torch.chunk(sequence_output, self.heads, dim=-1) 8个(batchsize, 150, 64*2) 145 | # [batchsize, 150, 8, 64*2] 146 | sequence_output = torch.stack(torch.chunk(sequence_output, self.heads, dim=-1), dim=-2) # [..., heads, head_size*2] 147 | # qw:[batchsize, 150, 8, 64], kw:[batchsize, 150, 8, 64] 148 | qw, kw = sequence_output[..., :self.head_size], sequence_output[..., self.head_size:] # [..., heads, head_size] 149 | 150 | # ROPE编码 151 | if self.RoPE: 152 | qw = self.position_embedding(qw) 153 | kw = self.position_embedding(kw) 154 | 155 | # 计算内积 156 | logits = torch.einsum('bmhd,bnhd->bhmn', qw, kw) # [btz, heads, seq_len, seq_len] 157 | 158 | # 排除padding 159 | if mask is not None: 160 | attention_mask1 = 1 - mask.unsqueeze(1).unsqueeze(3) # [btz, 1, seq_len, 1] 161 | attention_mask2 = 1 - mask.unsqueeze(1).unsqueeze(2) # [btz, 1, 1, seq_len] 162 | logits = logits.masked_fill(attention_mask1.bool(), value=-float('inf')) 163 | logits = logits.masked_fill(attention_mask2.bool(), value=-float('inf')) 164 | 165 | # 排除下三角 166 | if self.tril_mask: 167 | logits = logits - torch.tril(torch.ones_like(logits), -1) * 1e12 168 | 169 | return logits / self.head_size**0.5 170 | 171 | 172 | class GlobalPointerNer(nn.Module): 173 | def __init__(self, args): 174 | super().__init__() 175 | 176 | if "guwenbert" in args.bert_dir: 177 | self.bert = AutoModel.from_pretrained(args.bert_dir, output_hidden_states=True, 178 | hidden_dropout_prob=args.dropout_prob) 179 | else: 180 | self.bert = BertModel.from_pretrained(args.bert_dir, output_hidden_states=True, 181 | hidden_dropout_prob=args.dropout_prob) 182 | if args.use_efficient_globalpointer == "True": 183 | self.global_pointer = EfficientGlobalPointer(hidden_size=768, heads=args.num_tags, head_size=args.head_size) 184 | else: 185 | self.global_pointer = GlobalPointer(hidden_size=768, heads=args.num_tags, head_size=args.head_size) 186 | self.criterion = MyLoss() 187 | 188 | def forward(self, token_ids, attention_masks, token_type_ids, labels=None): 189 | output = self.bert(token_ids, attention_masks, token_type_ids) # [btz, seq_len, hdsz] 190 | sequence_output = output[0] 191 | logits = self.global_pointer(sequence_output, attention_masks.gt(0).long()) 192 | if labels is None: 193 | # scale返回 194 | return logits 195 | 196 | loss = self.criterion(logits, labels) 197 | return loss, logits -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/globalpoint2.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn as nn 3 | from transformers import BertModel 4 | 5 | def multilabel_categorical_crossentropy(y_pred, y_true): 6 | """ 7 | https://kexue.fm/archives/7359 8 | """ 9 | y_true = y_true.view(y_true.shape[0]*y_true.shape[1], -1) # [btz*ner_vocab_size, seq_len*seq_len] 10 | y_pred = y_pred.view(y_pred.shape[0]*y_pred.shape[1], -1) # [btz*ner_vocab_size, seq_len*seq_len] 11 | y_pred = (1 - 2 * y_true) * y_pred # -1 -> pos classes, 1 -> neg classes 12 | y_pred_neg = y_pred - y_true * 1e12 # mask the pred outputs of pos classes 13 | y_pred_pos = (y_pred - (1 - y_true) * 1e12) # mask the pred outputs of neg classes 14 | zeros = torch.zeros_like(y_pred[..., :1]) 15 | y_pred_neg = torch.cat([y_pred_neg, zeros], dim=-1) 16 | y_pred_pos = torch.cat([y_pred_pos, zeros], dim=-1) 17 | neg_loss = torch.logsumexp(y_pred_neg, dim=-1) 18 | pos_loss = torch.logsumexp(y_pred_pos, dim=-1) 19 | return (neg_loss + pos_loss).mean() 20 | 21 | class GlobalPointer(nn.Module): 22 | def __init__(self, hidden_size, heads, head_size, RoPE=True): 23 | super().__init__() 24 | self.heads = heads 25 | self.head_size = head_size 26 | self.dense = nn.Linear(hidden_size, self.heads * self.head_size * 2) 27 | self.RoPE = RoPE 28 | 29 | 30 | def sinusoidal_position_embedding(self, batch_size, seq_len, output_dim): 31 | position_ids = torch.arange(0, seq_len, dtype=torch.float).unsqueeze(-1) 32 | indices = torch.arange(0, output_dim // 2, dtype=torch.float) 33 | indices = torch.pow(10000, -2 * indices / output_dim) 34 | embeddings = position_ids * indices 35 | embeddings = torch.stack([torch.sin(embeddings), torch.cos(embeddings)], dim=-1) 36 | embeddings = embeddings.repeat((batch_size, *([1]*len(embeddings.shape)))) 37 | embeddings = torch.reshape(embeddings, (batch_size, seq_len, output_dim)) 38 | return embeddings 39 | 40 | def forward(self, inputs, attention_mask): 41 | 42 | batch_size = inputs.size()[0] 43 | seq_len = inputs.size()[1] 44 | 45 | # outputs:(batch_size, seq_len, ent_type_size*inner_dim*2) 46 | outputs = self.dense(inputs) 47 | outputs = torch.split(outputs, self.head_size * 2, dim=-1) 48 | # outputs:(batch_size, seq_len, ent_type_size, inner_dim*2) 49 | outputs = torch.stack(outputs, dim=-2) 50 | # qw,kw:(batch_size, seq_len, ent_type_size, inner_dim) 51 | qw, kw = outputs[...,:self.head_size], outputs[...,self.head_size:] # TODO:修改为Linear获取? 52 | 53 | if self.RoPE: 54 | # pos_emb:(batch_size, seq_len, inner_dim) 55 | pos_emb = self.sinusoidal_position_embedding(batch_size, seq_len, self.head_size).to(outputs.device) 56 | # cos_pos,sin_pos: (batch_size, seq_len, 1, inner_dim) 57 | cos_pos = pos_emb[..., None, 1::2].repeat_interleave(2, dim=-1) 58 | sin_pos = pos_emb[..., None,::2].repeat_interleave(2, dim=-1) 59 | qw2 = torch.stack([-qw[..., 1::2], qw[...,::2]], -1) 60 | qw2 = qw2.reshape(qw.shape) 61 | qw = qw * cos_pos + qw2 * sin_pos 62 | kw2 = torch.stack([-kw[..., 1::2], kw[...,::2]], -1) 63 | kw2 = kw2.reshape(kw.shape) 64 | kw = kw * cos_pos + kw2 * sin_pos 65 | 66 | # logits:(batch_size, ent_type_size, seq_len, seq_len) 67 | logits = torch.einsum('bmhd,bnhd->bhmn', qw, kw) 68 | 69 | # padding mask 70 | pad_mask = attention_mask.unsqueeze(1).unsqueeze(1).expand(batch_size, self.heads, seq_len, seq_len) 71 | # pad_mask_h = attention_mask.unsqueeze(1).unsqueeze(-1).expand(batch_size, self.ent_type_size, seq_len, seq_len) 72 | # pad_mask = pad_mask_v&pad_mask_h 73 | logits = logits*pad_mask - (1-pad_mask)*1e12 74 | 75 | # 排除下三角 76 | mask = torch.tril(torch.ones_like(logits), -1) 77 | logits = logits - mask * 1e12 78 | 79 | return logits/self.head_size**0.5 80 | 81 | 82 | class GlobalPointerNer(nn.Module): 83 | def __init__(self, args): 84 | super().__init__() 85 | self.bert = BertModel.from_pretrained(args.bert_dir, output_hidden_states=True, 86 | hidden_dropout_prob=args.dropout_prob) 87 | self.global_pointer = GlobalPointer(hidden_size=768, heads=args.num_tags, head_size=args.head_size) 88 | 89 | def forward(self, token_ids, attention_masks, token_type_ids, labels=None): 90 | output = self.bert(token_ids, attention_masks, token_type_ids) # [btz, seq_len, hdsz] 91 | sequence_output = output[0] 92 | logits = self.global_pointer(sequence_output, attention_masks.gt(0).long()) 93 | if labels is None: 94 | # scale返回 95 | return logits 96 | 97 | loss = multilabel_categorical_crossentropy(logits, labels) 98 | return loss, logits -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | import numpy as np 4 | import json 5 | from collections import defaultdict 6 | import torch 7 | from torch.utils.data import DataLoader, RandomSampler 8 | from transformers import BertTokenizer, AutoTokenizer 9 | 10 | import config 11 | import data_loader 12 | import globalpoint 13 | from utils.common_utils import set_seed, set_logger, read_json, trans_ij2k, fine_grade_tokenize 14 | from utils.train_utils import load_model_and_parallel, build_optimizer_and_scheduler, save_model 15 | from utils.metric_utils import calculate_metric, classification_report, get_p_r_f 16 | from tensorboardX import SummaryWriter 17 | 18 | args = config.Args().get_parser() 19 | set_seed(args.seed) 20 | logger = logging.getLogger(__name__) 21 | 22 | if args.use_tensorboard == "True": 23 | writer = SummaryWriter(log_dir='./tensorboard') 24 | 25 | 26 | class BertForNer: 27 | def __init__(self, args, train_loader, dev_loader, test_loader, idx2tag, model, device): 28 | self.train_loader = train_loader 29 | self.dev_loader = dev_loader 30 | self.test_loader = test_loader 31 | self.args = args 32 | self.idx2tag = idx2tag 33 | self.model = model 34 | self.device = device 35 | if train_loader is not None: 36 | self.t_total = len(self.train_loader) * args.train_epochs 37 | self.optimizer, self.scheduler = build_optimizer_and_scheduler(args, model, self.t_total) 38 | 39 | def train(self): 40 | # Train 41 | global_step = 0 42 | self.model.zero_grad() 43 | eval_steps = self.args.eval_steps # 每多少个step打印损失及进行验证 44 | best_f1 = 0.0 45 | for epoch in range(1, self.args.train_epochs+1): 46 | for step, batch_data in enumerate(self.train_loader): 47 | self.model.train() 48 | for batch in batch_data: 49 | batch = batch.to(self.device) 50 | loss, logits = self.model(batch_data[0], batch_data[1], batch_data[2], batch_data[3]) 51 | 52 | # loss.backward(loss.clone().detach()) 53 | loss.backward() 54 | torch.nn.utils.clip_grad_norm_(self.model.parameters(), self.args.max_grad_norm) 55 | self.optimizer.step() 56 | if self.scheduler is not None: 57 | self.scheduler.step() 58 | self.model.zero_grad() 59 | logger.info('【train】 epoch:{} {}/{} loss:{:.4f}'.format(epoch, global_step, self.t_total, loss.item())) 60 | 61 | global_step += 1 62 | if self.args.use_tensorboard == "True": 63 | writer.add_scalar('data/loss', loss.item(), global_step) 64 | if global_step % eval_steps == 0: 65 | dev_loss, precision, recall, f1_score = self.dev() 66 | logger.info('[eval] loss:{:.4f} precision={:.4f} recall={:.4f} f1_score={:.4f}'.format(dev_loss, precision, recall, f1_score)) 67 | if f1_score > best_f1: 68 | save_model(self.args, self.model, model_name, global_step) 69 | best_f1 = f1_score 70 | logger.info("best f1:{}".format(best_f1)) 71 | 72 | def dev(self): 73 | self.model.eval() 74 | with torch.no_grad(): 75 | pred_entities = [] 76 | true_entities = [] 77 | tot_dev_loss = 0.0 78 | for eval_step, dev_batch_data in enumerate(self.dev_loader): 79 | labels = dev_batch_data[3] 80 | for dev_batch in dev_batch_data: 81 | dev_batch = dev_batch.to(device) 82 | # logits:[8, 8, 150, 150] 83 | _, logits = model(dev_batch_data[0], dev_batch_data[1], dev_batch_data[2], dev_batch_data[3]) 84 | batch_size = logits.size(0) 85 | dev_callbak = dev_callback[eval_step * batch_size:(eval_step + 1) * batch_size] 86 | 87 | for i in range(batch_size): 88 | pred_tmp = defaultdict(list) 89 | logit = logits[i, ...] 90 | tokens = dev_callbak[i] 91 | for j in range(self.args.num_tags): 92 | logit_ = logit[j, :len(tokens), :len(tokens)] 93 | for start, end in zip(*np.where(logit_.cpu().numpy() > 0.5)): 94 | pred_tmp[id2tag[j]].append(["".join(tokens[start:end + 1]), start]) 95 | pred_entities.append(dict(pred_tmp)) 96 | 97 | for i in range(batch_size): 98 | true_tmp = defaultdict(list) 99 | logit = labels[i, ...] 100 | tokens = dev_callbak[i] 101 | for j in range(self.args.num_tags): 102 | logit_ = logit[j, :len(tokens), :len(tokens)] 103 | for start, end in zip(*np.where(logit_.cpu().numpy() == 1)): 104 | true_tmp[id2tag[j]].append(["".join(tokens[start:end + 1]), start]) 105 | true_entities.append(true_tmp) 106 | 107 | total_count = [0 for _ in range(len(id2tag))] 108 | role_metric = np.zeros([len(id2tag), 3]) 109 | for pred, true in zip(pred_entities, true_entities): 110 | tmp_metric = np.zeros([len(id2tag), 3]) 111 | for idx, _type in enumerate(label_list): 112 | if _type not in pred: 113 | pred[_type] = [] 114 | total_count[idx] += len(true[_type]) 115 | tmp_metric[idx] += calculate_metric(true[_type], pred[_type]) 116 | 117 | role_metric += tmp_metric 118 | 119 | mirco_metrics = np.sum(role_metric, axis=0) 120 | mirco_metrics = get_p_r_f(mirco_metrics[0], mirco_metrics[1], mirco_metrics[2]) 121 | # print('[eval] loss:{:.4f} precision={:.4f} recall={:.4f} f1_score={:.4f}'.format(tot_dev_loss, mirco_metrics[0], mirco_metrics[1], mirco_metrics[2])) 122 | return tot_dev_loss, mirco_metrics[0], mirco_metrics[1], mirco_metrics[2] 123 | 124 | def test(self, model_path): 125 | model = globalpoint.GlobalPointerNer(self.args) 126 | model, device = load_model_and_parallel(model, self.args.gpu_ids, model_path) 127 | model.eval() 128 | pred_entities = [] 129 | true_entities = [] 130 | with torch.no_grad(): 131 | for eval_step, dev_batch_data in enumerate(dev_loader): 132 | labels = dev_batch_data[3] 133 | for dev_batch in dev_batch_data: 134 | dev_batch = dev_batch.to(device) 135 | # logits:[8, 8, 150, 150] 136 | _, logits = model(dev_batch_data[0], dev_batch_data[1], dev_batch_data[2], dev_batch_data[3]) 137 | batch_size = logits.size(0) 138 | dev_callbak = dev_callback[eval_step * batch_size:(eval_step + 1) * batch_size] 139 | 140 | for i in range(batch_size): 141 | pred_tmp = defaultdict(list) 142 | logit = logits[i, ...] 143 | tokens = dev_callbak[i] 144 | for j in range(self.args.num_tags): 145 | logit_ = logit[j, :len(tokens), :len(tokens)] 146 | for start, end in zip(*np.where(logit_.cpu().numpy() > 0.5)): 147 | pred_tmp[id2tag[j]].append(["".join(tokens[start:end + 1]), start]) 148 | pred_entities.append(dict(pred_tmp)) 149 | 150 | for i in range(batch_size): 151 | true_tmp = defaultdict(list) 152 | logit = labels[i, ...] 153 | tokens = dev_callbak[i] 154 | for j in range(self.args.num_tags): 155 | logit_ = logit[j, :len(tokens), :len(tokens)] 156 | for start, end in zip(*np.where(logit_.cpu().numpy() == 1)): 157 | true_tmp[id2tag[j]].append(["".join(tokens[start:end + 1]), start]) 158 | true_entities.append(true_tmp) 159 | 160 | total_count = [0 for _ in range(len(id2tag))] 161 | role_metric = np.zeros([len(id2tag), 3]) 162 | for pred, true in zip(pred_entities, true_entities): 163 | tmp_metric = np.zeros([len(id2tag), 3]) 164 | for idx, _type in enumerate(label_list): 165 | if _type not in pred: 166 | pred[_type] = [] 167 | total_count[idx] += len(true[_type]) 168 | tmp_metric[idx] += calculate_metric(true[_type], pred[_type]) 169 | 170 | role_metric += tmp_metric 171 | logger.info(classification_report(role_metric, label_list, id2tag, total_count)) 172 | 173 | def predict(self, raw_text, model_path): 174 | model = globalpoint.GlobalPointerNer(self.args) 175 | model, device = load_model_and_parallel(model, self.args.gpu_ids, model_path) 176 | model.eval() 177 | with torch.no_grad(): 178 | tokenizer = BertTokenizer(self.args.bert_dir) 179 | # tokens = fine_grade_tokenize(raw_text, tokenizer) 180 | tokens = [i for i in raw_text] 181 | encode_dict = tokenizer.encode_plus(text=tokens, 182 | max_length=self.args.max_seq_len, 183 | padding='max_length', 184 | truncation='longest_first', 185 | is_pretokenized=True, 186 | return_token_type_ids=True, 187 | return_attention_mask=True) 188 | tokens = ['[CLS]'] + tokens + ['[SEP]'] 189 | token_ids = torch.from_numpy(np.array(encode_dict['input_ids'])).unsqueeze(0) 190 | attention_masks = torch.from_numpy(np.array(encode_dict['attention_mask'], dtype=np.uint8)).unsqueeze(0) 191 | token_type_ids = torch.from_numpy(np.array(encode_dict['token_type_ids'])).unsqueeze(0) 192 | logits = model(token_ids.to(device), attention_masks.to(device), token_type_ids.to(device), None) 193 | batch_size = logits.size(0) 194 | pred_tmp = defaultdict(list) 195 | for i in range(batch_size): 196 | logit = logits[i, ...] 197 | for j in range(self.args.num_tags): 198 | logit_ = logit[j, :len(tokens), :len(tokens)] 199 | for start, end in zip(*np.where(logit_.cpu().numpy() > 0.5)): 200 | pred_tmp[id2tag[j]].append(["".join(tokens[start:end + 1]), start-1]) 201 | 202 | logger.info(dict(pred_tmp)) 203 | 204 | 205 | if __name__ == '__main__': 206 | 207 | if args.use_efficient_globalpointer == "True": 208 | model_name = 'bert-1-eff' 209 | else: 210 | model_name = 'bert-1' 211 | 212 | set_logger(os.path.join(args.log_dir, '{}.log'.format(model_name))) 213 | data_path = os.path.join(args.data_dir, 'mid_data') 214 | label_list = read_json(data_path, 'labels') 215 | tag2id = {} 216 | id2tag = {} 217 | for k, v in enumerate(label_list): 218 | tag2id[v] = k 219 | id2tag[k] = v 220 | 221 | logger.info(args) 222 | max_seq_len = args.max_seq_len 223 | if "guwenbert" in args.bert_dir: 224 | tokenizer = AutoTokenizer.from_pretrained(args.bert_dir) 225 | else: 226 | tokenizer = BertTokenizer.from_pretrained(args.bert_dir) 227 | 228 | model = globalpoint.GlobalPointerNer(args) 229 | model, device = load_model_and_parallel(model, args.gpu_ids) 230 | 231 | 232 | collate = data_loader.Collate(max_len=max_seq_len, tag2id=tag2id, device=device) 233 | 234 | train_dataset, _ = data_loader.MyDataset(file_path=os.path.join(data_path, 'train.json'), 235 | tokenizer=tokenizer, 236 | max_len=max_seq_len) 237 | 238 | train_loader = DataLoader(train_dataset, batch_size=args.train_batch_size, shuffle=True, 239 | collate_fn=collate.collate_fn) 240 | dev_dataset, dev_callback = data_loader.MyDataset(file_path=os.path.join(data_path, 'dev.json'), 241 | tokenizer=tokenizer, 242 | max_len=max_seq_len) 243 | 244 | dev_loader = DataLoader(dev_dataset, batch_size=args.eval_batch_size, shuffle=False, 245 | collate_fn=collate.collate_fn) 246 | 247 | test_dataset, test_callback = data_loader.MyDataset(file_path=os.path.join(data_path, 'test.json'), 248 | tokenizer=tokenizer, 249 | max_len=max_seq_len) 250 | 251 | test_loader = DataLoader(dev_dataset, batch_size=args.eval_batch_size, shuffle=False, 252 | collate_fn=collate.collate_fn) 253 | 254 | bertForNer = BertForNer(args, train_loader, dev_loader, test_loader, id2tag, model, device) 255 | bertForNer.train() 256 | 257 | with open("./checkpoints/{}/args.json".format(model_name), "w", encoding="utf-8") as fp: 258 | json.dump(vars(args), fp, ensure_ascii=False) 259 | 260 | 261 | model_path = './checkpoints/{}/model.pt'.format(model_name) 262 | bertForNer.test(model_path) 263 | 264 | if "cner" in args.data_dir: 265 | raw_text = "虞兔良先生:1963年12月出生,汉族,中国国籍,无境外永久居留权,浙江绍兴人,中共党员,MBA,经济师。" 266 | elif "guwen" in args.data_dir: 267 | raw_text = "冬十月,天子拜太祖兖州牧。十二月,雍丘溃,超自杀。夷邈三族。邈诣袁术请救,为其众所杀,兖州平,遂东略陈地。" 268 | 269 | logger.info(raw_text) 270 | bertForNer.predict(raw_text, model_path) 271 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/preprocess.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import logging 4 | from transformers import BertTokenizer 5 | from utils import cut_sentence, common_utils 6 | 7 | logger = logging.getLogger(__name__) 8 | 9 | 10 | class InputExample: 11 | def __init__(self, set_type, text, labels=None): 12 | self.set_type = set_type 13 | self.text = text 14 | self.labels = labels 15 | 16 | def __repr__(self): 17 | string = "" 18 | for key, value in self.__dict__.items(): 19 | string += f"{key}: {value}\n" 20 | return f"<{string}>" 21 | 22 | 23 | class NerProcessor: 24 | def __init__(self, cut_sent=True, cut_sent_len=256): 25 | self.cut_sent = cut_sent 26 | self.cut_sent_len = cut_sent_len 27 | 28 | @staticmethod 29 | def read_json(file_path): 30 | with open(file_path, encoding='utf-8') as f: 31 | raw_examples = json.load(f) 32 | return raw_examples 33 | 34 | def get_examples(self, raw_examples, set_type): 35 | examples = [] 36 | # 这里是从json数据中的字典中获取 37 | for i, item in enumerate(raw_examples): 38 | # print(i,item) 39 | text = item['text'] 40 | if self.cut_sent: 41 | sentences = cut_sentence.cut_sent_for_bert(text, self.cut_sent_len) 42 | start_index = 0 43 | 44 | for sent in sentences: 45 | labels = cut_sentence.refactor_labels(sent, item['labels'], start_index) 46 | start_index += len(sent) 47 | 48 | examples.append(InputExample(set_type=set_type, 49 | text=sent, 50 | labels=labels)) 51 | else: 52 | labels = item['labels'] 53 | if len(labels) != 0: 54 | labels = [(label[1],label[4],label[2]) for label in labels] 55 | examples.append(InputExample(set_type=set_type, 56 | text=text, 57 | labels=labels)) 58 | 59 | return examples 60 | 61 | 62 | 63 | if __name__ == "__main__": 64 | nerProcessor = NerProcessor(cut_sent=True, cut_sent_len=150) 65 | raw_examples = nerProcessor.read_json('data/people-daily/mid_data/train.json') 66 | examples = nerProcessor.get_examples(raw_examples, set_type="train") 67 | print(examples[0]) 68 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/tensorboard/占位.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_Ner/tensorboard/占位.txt -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_Ner/utils/__init__.py -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/utils/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_Ner/utils/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/utils/__pycache__/common_utils.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_Ner/utils/__pycache__/common_utils.cpython-37.pyc -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/utils/__pycache__/cut_sentence.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_Ner/utils/__pycache__/cut_sentence.cpython-37.pyc -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/utils/__pycache__/metric_utils.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_Ner/utils/__pycache__/metric_utils.cpython-37.pyc -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/utils/__pycache__/train_utils.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_Ner/utils/__pycache__/train_utils.cpython-37.pyc -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/utils/common_utils.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import random 3 | import os 4 | import json 5 | import logging 6 | import time 7 | import pickle 8 | import numpy as np 9 | import torch 10 | from torch.nn.utils.rnn import pad_sequence 11 | 12 | 13 | def trans_ij2k(seq_len, i, j): 14 | '''把第i行,第j列转化成上三角flat后的序号 15 | ''' 16 | if (i > seq_len - 1) or (j > seq_len - 1) or (i > j): 17 | return 0 18 | return int(0.5*(2*seq_len-i+1)*i+(j-i)) 19 | 20 | def sequence_padding(inputs, length=None, value=0, seq_dims=1, mode='post'): 21 | """将序列padding到同一长度 22 | """ 23 | if isinstance(inputs[0], (np.ndarray, list)): 24 | if length is None: 25 | length = np.max([np.shape(x)[:seq_dims] for x in inputs], axis=0) 26 | elif not hasattr(length, '__getitem__'): 27 | length = [length] 28 | 29 | slices = [np.s_[:length[i]] for i in range(seq_dims)] 30 | slices = tuple(slices) if len(slices) > 1 else slices[0] 31 | pad_width = [(0, 0) for _ in np.shape(inputs[0])] 32 | 33 | outputs = [] 34 | for x in inputs: 35 | x = x[slices] 36 | for i in range(seq_dims): 37 | if mode == 'post': 38 | pad_width[i] = (0, length[i] - np.shape(x)[i]) 39 | elif mode == 'pre': 40 | pad_width[i] = (length[i] - np.shape(x)[i], 0) 41 | else: 42 | raise ValueError('"mode" argument must be "post" or "pre".') 43 | x = np.pad(x, pad_width, 'constant', constant_values=value) 44 | outputs.append(x) 45 | 46 | return np.array(outputs) 47 | 48 | elif isinstance(inputs[0], torch.Tensor): 49 | assert mode == 'post', '"mode" argument must be "post" when element is torch.Tensor' 50 | if length is not None: 51 | inputs = [i[:length] for i in inputs] 52 | return pad_sequence(inputs, padding_value=value, batch_first=True) 53 | else: 54 | raise ValueError('"input" argument must be tensor/list/ndarray.') 55 | 56 | 57 | def timer(func): 58 | """ 59 | 函数计时器 60 | :param func: 61 | :return: 62 | """ 63 | 64 | @functools.wraps(func) 65 | def wrapper(*args, **kwargs): 66 | start = time.time() 67 | res = func(*args, **kwargs) 68 | end = time.time() 69 | print("{}共耗时约{:.4f}秒".format(func.__name__, end - start)) 70 | return res 71 | 72 | return wrapper 73 | 74 | 75 | def set_seed(seed=123): 76 | """ 77 | 设置随机数种子,保证实验可重现 78 | :param seed: 79 | :return: 80 | """ 81 | random.seed(seed) 82 | torch.manual_seed(seed) 83 | np.random.seed(seed) 84 | torch.cuda.manual_seed_all(seed) 85 | 86 | 87 | def set_logger(log_path): 88 | """ 89 | 配置log 90 | :param log_path:s 91 | :return: 92 | """ 93 | logger = logging.getLogger() 94 | logger.setLevel(logging.INFO) 95 | 96 | # 由于每调用一次set_logger函数,就会创建一个handler,会造成重复打印的问题,因此需要判断root logger中是否已有该handler 97 | if not any(handler.__class__ == logging.FileHandler for handler in logger.handlers): 98 | file_handler = logging.FileHandler(log_path) 99 | formatter = logging.Formatter( 100 | '%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)d - %(message)s') 101 | file_handler.setFormatter(formatter) 102 | logger.addHandler(file_handler) 103 | 104 | if not any(handler.__class__ == logging.StreamHandler for handler in logger.handlers): 105 | stream_handler = logging.StreamHandler() 106 | stream_handler.setFormatter(logging.Formatter('%(message)s')) 107 | logger.addHandler(stream_handler) 108 | 109 | 110 | def save_json(data_dir, data, desc): 111 | """保存数据为json""" 112 | with open(os.path.join(data_dir, '{}.json'.format(desc)), 'w', encoding='utf-8') as f: 113 | json.dump(data, f, ensure_ascii=False, indent=2) 114 | 115 | 116 | def read_json(data_dir, desc): 117 | """读取数据为json""" 118 | with open(os.path.join(data_dir, '{}.json'.format(desc)), 'r', encoding='utf-8') as f: 119 | data = json.load(f) 120 | return data 121 | 122 | 123 | def save_pkl(data_dir, data, desc): 124 | """保存.pkl文件""" 125 | with open(os.path.join(data_dir, '{}.pkl'.format(desc)), 'wb') as f: 126 | pickle.dump(data, f) 127 | 128 | 129 | def read_pkl(data_dir, desc): 130 | """读取.pkl文件""" 131 | with open(os.path.join(data_dir, '{}.pkl'.format(desc)), 'rb') as f: 132 | data = pickle.load(f) 133 | return data 134 | 135 | 136 | def fine_grade_tokenize(raw_text, tokenizer): 137 | """ 138 | 序列标注任务 BERT 分词器可能会导致标注偏移, 139 | 用 char-level 来 tokenize 140 | """ 141 | tokens = [] 142 | 143 | for _ch in raw_text: 144 | if _ch in [' ', '\t', '\n']: 145 | tokens.append('[BLANK]') 146 | else: 147 | if not len(tokenizer.tokenize(_ch)): 148 | tokens.append('[INV]') 149 | else: 150 | tokens.append(_ch) 151 | 152 | return tokens -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/utils/cut_sentence.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | def cut_sentences_v1(sent): 5 | """ 6 | the first rank of sentence cut 7 | """ 8 | sent = re.sub('([。!?\?])([^”’])', r"\1\n\2", sent) # 单字符断句符 9 | sent = re.sub('(\.{6})([^”’])', r"\1\n\2", sent) # 英文省略号 10 | sent = re.sub('(\…{2})([^”’])', r"\1\n\2", sent) # 中文省略号 11 | sent = re.sub('([。!?\?][”’])([^,。!?\?])', r"\1\n\2", sent) 12 | # 如果双引号前有终止符,那么双引号才是句子的终点,把分句符\n放到双引号后 13 | return sent.split("\n") 14 | 15 | 16 | def cut_sentences_v2(sent): 17 | """ 18 | the second rank of spilt sentence, split ';' | ';' 19 | """ 20 | sent = re.sub('([;;])([^”’])', r"\1\n\2", sent) 21 | return sent.split("\n") 22 | 23 | 24 | def cut_sent_for_bert(text, max_seq_len): 25 | # 将句子分句,细粒度分句后再重新合并 26 | sentences = [] 27 | 28 | # 细粒度划分 29 | sentences_v1 = cut_sentences_v1(text) 30 | # print("sentences_v1=", sentences_v1) 31 | for sent_v1 in sentences_v1: 32 | if len(sent_v1) > max_seq_len - 2: 33 | sentences_v2 = cut_sentences_v2(sent_v1) 34 | sentences.extend(sentences_v2) 35 | else: 36 | sentences.append(sent_v1) 37 | 38 | assert ''.join(sentences) == text 39 | 40 | # 合并 41 | merged_sentences = [] 42 | start_index_ = 0 43 | 44 | while start_index_ < len(sentences): 45 | tmp_text = sentences[start_index_] 46 | 47 | end_index_ = start_index_ + 1 48 | # 针对于bert模型,注意这里最大长度要减去2 49 | while end_index_ < len(sentences) and \ 50 | len(tmp_text) + len(sentences[end_index_]) <= max_seq_len - 2: 51 | tmp_text += sentences[end_index_] 52 | end_index_ += 1 53 | 54 | start_index_ = end_index_ 55 | 56 | merged_sentences.append(tmp_text) 57 | 58 | return merged_sentences 59 | 60 | 61 | def refactor_labels(sent, labels, start_index): 62 | """ 63 | 分句后需要重构 labels 的 offset 64 | :param sent: 切分并重新合并后的句子 65 | :param labels: 原始文档级的 labels 66 | :param start_index: 该句子在文档中的起始 offset 67 | :return (type, entity, offset) 68 | """ 69 | new_labels = [] 70 | end_index = start_index + len(sent) 71 | # _label: TI, 实体类别, 实体起始位置, 实体结束位置, 实体名) 72 | for _label in labels: 73 | if start_index <= _label[2] <= _label[3] <= end_index: 74 | new_offset = _label[2] - start_index 75 | 76 | assert sent[new_offset: new_offset + len(_label[-1])] == _label[-1] 77 | 78 | new_labels.append((_label[1], _label[-1], new_offset)) 79 | # label 被截断的情况 80 | elif _label[2] < end_index < _label[3]: 81 | raise RuntimeError(f'{sent}, {_label}') 82 | 83 | return new_labels 84 | 85 | 86 | if __name__ == '__main__': 87 | raw_examples = [{ 88 | "text": "深圳市沙头角保税区今后五年将充分发挥保税区的区位优势和政策优势,以高新技术产业为先导,积极调整产品结构,实施以转口贸易和仓储业为辅助的经营战略。把沙头角保税区建成按国际惯例运作、国内领先的特殊综合经济区域,使其成为该市外向型经济的快速增长点。", 89 | "labels": [ 90 | [ 91 | "T0", 92 | "GPE", 93 | 0, 94 | 3, 95 | "深圳市" 96 | ], 97 | [ 98 | "T1", 99 | "GPE", 100 | 3, 101 | 6, 102 | "沙头角" 103 | ], 104 | [ 105 | "T2", 106 | "LOC", 107 | 6, 108 | 9, 109 | "保税区" 110 | ], 111 | [ 112 | "T3", 113 | "LOC", 114 | 18, 115 | 21, 116 | "保税区" 117 | ], 118 | [ 119 | "T4", 120 | "GPE", 121 | 73, 122 | 76, 123 | "沙头角" 124 | ], 125 | [ 126 | "T5", 127 | "LOC", 128 | 76, 129 | 79, 130 | "保税区" 131 | ] 132 | ] 133 | }] 134 | for i, item in enumerate(raw_examples): 135 | text = item['text'] 136 | print(text[:90]) 137 | sentences = cut_sent_for_bert(text, 90) 138 | start_index = 0 139 | 140 | for sent in sentences: 141 | labels = refactor_labels(sent, item['labels'], start_index) 142 | start_index += len(sent) 143 | 144 | print(sent) 145 | print(labels) -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/utils/metric_utils.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from __future__ import division 3 | from __future__ import print_function 4 | 5 | from collections import defaultdict 6 | 7 | import numpy as np 8 | 9 | 10 | 11 | def calculate_metric(gt, predict): 12 | """ 13 | 计算 tp fp fn 14 | """ 15 | tp, fp, fn = 0, 0, 0 16 | for entity_predict in predict: 17 | flag = 0 18 | for entity_gt in gt: 19 | if entity_predict[0] == entity_gt[0] and entity_predict[1] == entity_gt[1]: 20 | flag = 1 21 | tp += 1 22 | break 23 | if flag == 0: 24 | fp += 1 25 | 26 | fn = len(gt) - tp 27 | 28 | return np.array([tp, fp, fn]) 29 | 30 | 31 | def get_p_r_f(tp, fp, fn): 32 | p = tp / (tp + fp) if tp + fp != 0 else 0 33 | r = tp / (tp + fn) if tp + fn != 0 else 0 34 | f1 = 2 * p * r / (p + r) if p + r != 0 else 0 35 | return np.array([p, r, f1]) 36 | 37 | def classification_report(metrics_matrix, label_list, id2label, total_count, digits=2, suffix=False): 38 | name_width = max([len(label) for label in label_list]) 39 | last_line_heading = 'micro-f1' 40 | width = max(name_width, len(last_line_heading), digits) 41 | 42 | headers = ["precision", "recall", "f1-score", "support"] 43 | head_fmt = u'{:>{width}s} ' + u' {:>9}' * len(headers) 44 | report = head_fmt.format(u'', *headers, width=width) 45 | report += u'\n\n' 46 | 47 | row_fmt = u'{:>{width}s} ' + u' {:>9.{digits}f}' * 3 + u' {:>9}\n' 48 | 49 | ps, rs, f1s, s = [], [], [], [] 50 | for label_id, label_matrix in enumerate(metrics_matrix): 51 | type_name = id2label[label_id] 52 | p,r,f1 = get_p_r_f(label_matrix[0],label_matrix[1],label_matrix[2]) 53 | nb_true = total_count[label_id] 54 | report += row_fmt.format(*[type_name, p, r, f1, nb_true], width=width, digits=digits) 55 | ps.append(p) 56 | rs.append(r) 57 | f1s.append(f1) 58 | s.append(nb_true) 59 | 60 | report += u'\n' 61 | mirco_metrics = np.sum(metrics_matrix, axis=0) 62 | mirco_metrics = get_p_r_f(mirco_metrics[0], mirco_metrics[1], mirco_metrics[2]) 63 | # compute averages 64 | print('precision:{:.4f} recall:{:.4f} micro_f1:{:.4f}'.format(mirco_metrics[0],mirco_metrics[1],mirco_metrics[2])) 65 | report += row_fmt.format(last_line_heading, 66 | mirco_metrics[0], 67 | mirco_metrics[1], 68 | mirco_metrics[2], 69 | np.sum(s), 70 | width=width, digits=digits) 71 | 72 | return report -------------------------------------------------------------------------------- /pytorch_GlobalPointer_Ner/utils/train_utils.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import os 3 | import logging 4 | from transformers import AdamW, get_linear_schedule_with_warmup 5 | import torch 6 | 7 | logger = logging.getLogger(__name__) 8 | 9 | 10 | def build_optimizer_and_scheduler(args, model, t_total, optim="adamw", schd="lstep"): 11 | module = ( 12 | model.module if hasattr(model, "module") else model 13 | ) 14 | 15 | # 差分学习率 16 | no_decay = ["bias", "LayerNorm.weight"] 17 | model_param = list(module.named_parameters()) 18 | 19 | bert_param_optimizer = [] 20 | crf_param_optimizer = [] 21 | other_param_optimizer = [] 22 | 23 | for name, para in model_param: 24 | space = name.split('.') 25 | # print(name) 26 | if space[0] == 'bert_module': 27 | bert_param_optimizer.append((name, para)) 28 | elif space[0] == 'crf': 29 | crf_param_optimizer.append((name, para)) 30 | else: 31 | other_param_optimizer.append((name, para)) 32 | 33 | optimizer_grouped_parameters = [ 34 | # bert other module 35 | {"params": [p for n, p in bert_param_optimizer if not any(nd in n for nd in no_decay)], 36 | "weight_decay": args.weight_decay, 'lr': args.lr}, 37 | {"params": [p for n, p in bert_param_optimizer if any(nd in n for nd in no_decay)], 38 | "weight_decay": 0.0, 'lr': args.lr}, 39 | 40 | # 其他模块,差分学习率 41 | {"params": [p for n, p in other_param_optimizer if not any(nd in n for nd in no_decay)], 42 | "weight_decay": args.weight_decay, 'lr': args.other_lr}, 43 | {"params": [p for n, p in other_param_optimizer if any(nd in n for nd in no_decay)], 44 | "weight_decay": 0.0, 'lr': args.other_lr}, 45 | ] 46 | 47 | if optim.lower() == "adamw": 48 | optimizer = AdamW(optimizer_grouped_parameters, lr=args.lr, eps=args.adam_epsilon) 49 | elif optim.lower() == "adam": 50 | optimizer = torch.optim.Adam(optimizer_grouped_parameters, 51 | lr=args.lr, 52 | betas=(0.9, 0.999), 53 | eps=args.adam_epsilon, 54 | ) 55 | 56 | if schd == "step": 57 | scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=100, gamma=0.999) 58 | elif schd == "lstep": 59 | scheduler = get_linear_schedule_with_warmup( 60 | optimizer, num_warmup_steps=int(args.warmup_proportion * t_total), num_training_steps=t_total 61 | ) 62 | else: 63 | scheduler = None 64 | 65 | return optimizer, scheduler 66 | 67 | def save_model(args, model, model_name, global_step): 68 | """保存最好的验证集效果最好那个模型""" 69 | output_dir = os.path.join(args.output_dir, '{}'.format(model_name, global_step)) 70 | if not os.path.exists(output_dir): 71 | os.makedirs(output_dir, exist_ok=True) 72 | 73 | # take care of model distributed / parallel training 74 | model_to_save = ( 75 | model.module if hasattr(model, "module") else model 76 | ) 77 | logger.info('Saving model checkpoint to {}'.format(output_dir)) 78 | torch.save(model_to_save.state_dict(), os.path.join(output_dir, 'model.pt')) 79 | 80 | def save_model_step(args, model, global_step): 81 | """根据global_step来保存模型""" 82 | output_dir = os.path.join(args.output_dir, 'checkpoint-{}'.format(global_step)) 83 | if not os.path.exists(output_dir): 84 | os.makedirs(output_dir, exist_ok=True) 85 | 86 | # take care of model distributed / parallel training 87 | model_to_save = ( 88 | model.module if hasattr(model, "module") else model 89 | ) 90 | logger.info('Saving model & optimizer & scheduler checkpoint to {}.format(output_dir)') 91 | torch.save(model_to_save.state_dict(), os.path.join(output_dir, 'model.pt')) 92 | 93 | def load_model_and_parallel(model, gpu_ids, ckpt_path=None, strict=True): 94 | """ 95 | 加载模型 & 放置到 GPU 中(单卡 / 多卡) 96 | """ 97 | gpu_ids = gpu_ids.split(',') 98 | 99 | # set to device to the first cuda 100 | device = torch.device("cpu" if gpu_ids[0] == '-1' else "cuda:" + gpu_ids[0]) 101 | 102 | if ckpt_path is not None: 103 | logger.info('Load ckpt from {}'.format(ckpt_path)) 104 | model.load_state_dict(torch.load(ckpt_path, map_location=torch.device('cpu')), strict=strict) 105 | 106 | model.to(device) 107 | 108 | if len(gpu_ids) > 1: 109 | logger.info('Use multi gpus in: {}'.format(gpu_ids)) 110 | gpu_ids = [int(x) for x in gpu_ids] 111 | model = torch.nn.DataParallel(model, device_ids=gpu_ids) 112 | else: 113 | logger.info('Use single gpu in: {}'.format(gpu_ids)) 114 | 115 | return model, device -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/README.md: -------------------------------------------------------------------------------- 1 | # pytorch_GlobalPointer_triple_extraction 2 | 3 | 基于pytorch的GlobalPointer进行三元组抽取。 4 | 5 | 具体使用说明: 6 | 7 | - 1、在data/ske/raw_data下是原始数据,新建一个process.py,主要是得到mid_data下的关系的类型。 8 | - 2、针对于不同的数据源,在data_loader.py中修改MyDataset类下,返回的是一个列表,列表中的每个元素是:(text, labels),其中labels是[[主体,类别,客体]]。 9 | - 3、运行main.py进行训练、验证、测试和预测。 10 | 11 | 数据和模型下载地址:链接:https://pan.baidu.com/s/1HOaGUiRsknIBtXS_ASNF-w?pwd=rm2u 提取码:rm2u 12 | 13 | # 依赖 14 | 15 | ``` 16 | pytorch==1.6.0 17 | transformers==4.5.0 18 | ``` 19 | 20 | # 运行 21 | 22 | ```python 23 | !python main.py \ 24 | --bert_dir="model_hub/chinese-bert-wwm-ext/" \ 25 | --data_dir="./data/ske/" \ 26 | --log_dir="./logs/" \ 27 | --output_dir="./checkpoints/" \ 28 | --num_tags=49 \ 29 | --seed=123 \ 30 | --gpu_ids="0" \ 31 | --max_seq_len=256 \ 32 | --lr=5e-5 \ 33 | --other_lr=5e-5 \ 34 | --train_batch_size=32 \ 35 | --train_epochs=1 \ 36 | --eval_steps=10 \ 37 | --eval_batch_size=8 \ 38 | --max_grad_norm=1 \ 39 | --warmup_proportion=0.1 \ 40 | --adam_epsilon=1e-8 \ 41 | --weight_decay=0.01 \ 42 | --dropout_prob=0.1 \ 43 | --use_tensorboard="False" \ 44 | --use_dev_num=1000 \ 45 | ``` 46 | 47 | ### 结果 48 | 49 | 这里以batch_size=32运行了2000步。 50 | 51 | ```python 52 | precision:0.7831715210355987 recall:0.7298578199052133 f1:0.7555753791257805 53 | ``` 54 | 55 | ```python 56 | 文本: 查尔斯·阿兰基斯(Charles Aránguiz),1989年4月17日出生于智利圣地亚哥,智利职业足球运动员,司职中场,效力于德国足球甲级联赛勒沃库森足球俱乐部 57 | 主体: [['查尔斯·阿兰基斯']] 58 | 客体: [['智利', '圣地亚哥', '智利圣地亚哥', '1989年4月17日']] 59 | 关系: [[('查尔斯·阿兰基斯', '出生日期', '1989年4月17日'), ('查尔斯·阿兰基斯', '出生地', '智利'), ('查尔斯·阿兰基斯', '国籍', '智利'), ('查尔斯·阿兰基斯', '出生地', '智利圣地亚哥'), ('查尔斯·阿兰基斯', '国籍', '智利圣地亚哥'), ('查尔斯·阿兰基斯', '出生地', '圣地亚哥')]] 60 | ==================================================================================================== 61 | 文本: 《离开》是由张宇谱曲,演唱 62 | 主体: [['离开']] 63 | 客体: [['张宇']] 64 | 关系: [[('离开', '歌手', '张宇'), ('离开', '作曲', '张宇')]] 65 | ==================================================================================================== 66 | 文本: 《愤怒的唐僧》由北京吴意波影视文化工作室与优酷电视剧频道联合制作,故事以喜剧元素为主,讲述唐僧与佛祖打牌,得罪了佛祖,被踢下人间再渡九九八十一难的故事 67 | 主体: [['愤怒的唐僧']] 68 | 客体: [['北京吴意波影视文化工作室']] 69 | 关系: [[('愤怒的唐僧', '出品公司', '北京吴意波影视文化工作室')]] 70 | ==================================================================================================== 71 | 文本: 李治即位后,萧淑妃受宠,王皇后为了排挤萧淑妃,答应李治让身在感业寺的武则天续起头发,重新纳入后宫 72 | 主体: [['李治', '萧淑妃']] 73 | 客体: [['李治', '萧淑妃']] 74 | 关系: [[('李治', '妻子', '萧淑妃'), ('萧淑妃', '丈夫', '李治')]] 75 | ==================================================================================================== 76 | 文本: 《工业4.0》是2015年机械工业出版社出版的图书,作者是(德)阿尔冯斯·波特霍夫,恩斯特·安德雷亚斯·哈特曼 77 | 主体: [['工业4.0']] 78 | 客体: [['机械工业出版社', '阿尔冯斯·波特霍夫']] 79 | 关系: [[('工业4.0', '出版社', '机械工业出版社'), ('工业4.0', '作者', '阿尔冯斯·波特霍夫')]] 80 | ==================================================================================================== 81 | 文本: 周佛海被捕入狱之后,其妻杨淑慧散尽家产请蒋介石枪下留人,于是周佛海从死刑变为无期,不过此人或许作恶多端,改判没多久便病逝于监狱,据悉是心脏病发作 82 | 主体: [['周佛海', '杨淑慧', '蒋介石']] 83 | 客体: [['周佛海', '杨淑慧', '蒋介石']] 84 | 关系: [[('周佛海', '妻子', '杨淑慧'), ('杨淑慧', '丈夫', '周佛海'), ('杨淑慧', '丈夫', '蒋介石'), ('蒋介石', '妻子', '杨淑慧')]] 85 | ==================================================================================================== 86 | 文本: 《李烈钧自述》是2011年11月1日人民日报出版社出版的图书,作者是李烈钧 87 | 主体: [['李烈钧自述']] 88 | 客体: [['李烈钧', '人民日报出版社']] 89 | 关系: [[('李烈钧自述', '作者', '李烈钧'), ('李烈钧自述', '出版社', '人民日报出版社')]] 90 | ==================================================================================================== 91 | 文本: 除演艺事业外,李冰冰热心公益,发起并亲自参与多项环保慈善活动,积极投身其中,身体力行担起了回馈社会的责任于02年出演《少年包青天》,进入大家视线 92 | 主体: [['少年包青天']] 93 | 客体: [['李冰冰']] 94 | 关系: [[('少年包青天', '主演', '李冰冰')]] 95 | ==================================================================================================== 96 | 文本: 马志舟,1907年出生,陕西三原人,汉族,中国共产党,任红四团第一连连长,1933年逝世 97 | 主体: [['马志舟']] 98 | 客体: [['汉族', '1907年', '中国', '陕西三原']] 99 | 关系: [[('马志舟', '出生日期', '1907年'), ('马志舟', '出生地', '陕西三原'), ('马志舟', '民族', '汉族'), ('马志舟', '国籍', '中国')]] 100 | ==================================================================================================== 101 | 文本: 斑刺莺是雀形目、剌嘴莺科的一种动物,分布于澳大利亚和新西兰,包括澳大利亚、新西兰、塔斯马尼亚及其附近的岛屿 102 | 主体: [['斑刺莺']] 103 | 客体: [['雀形目']] 104 | 关系: [[('斑刺莺', '目', '雀形目')]] 105 | ==================================================================================================== 106 | 文本: 《课本上学不到的生物学2》是2013年上海科技教育出版社出版的图书 107 | 主体: [['课本上学不到的生物学2']] 108 | 客体: [['上海科技教育出版社']] 109 | 关系: [[('课本上学不到的生物学2', '出版社', '上海科技教育出版社')]] 110 | ==================================================================================================== 111 | ``` 112 | 113 | # 参考 114 | 115 | > 模型参考:[bert4torch/task_relation_extraction_gplinker.py](https://github.com/Tongjilibo/bert4torch/blob/master/examples/relation_extraction/task_relation_extraction_gplinker.py) 116 | > 117 | > [将“softmax+交叉熵”推广到多标签分类问题 - 科学空间|Scientific Spaces](https://spaces.ac.cn/archives/7359) 118 | > 119 | > [GPLinker:基于GlobalPointer的实体关系联合抽取 - 科学空间|Scientific Spaces](https://spaces.ac.cn/archives/8888) 120 | 121 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/checkpoints/bert/args.json: -------------------------------------------------------------------------------- 1 | {"output_dir": "./checkpoints/", "bert_dir": "../model_hub/chinese-bert-wwm-ext/", "data_dir": "./data/guwen/", "log_dir": "./logs/", "num_tags": 25, "seed": 123, "gpu_ids": "0", "max_seq_len": 256, "eval_batch_size": 8, "train_epochs": 10, "dropout_prob": 0.3, "lr": 5e-05, "other_lr": 5e-05, "max_grad_norm": 1.0, "use_tensorboard": "False", "warmup_proportion": 0.1, "weight_decay": 0.01, "adam_epsilon": 1e-08, "train_batch_size": 32, "use_dev_num": 1000, "eval_steps": 100} -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/checkpoints/占位.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_triple_extraction/checkpoints/占位.txt -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/config.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | 4 | class Args: 5 | @staticmethod 6 | def parse(): 7 | parser = argparse.ArgumentParser() 8 | return parser 9 | 10 | @staticmethod 11 | def initialize(parser): 12 | # args for path 13 | parser.add_argument('--output_dir', default='./checkpoints/', 14 | help='the output dir for model checkpoints') 15 | 16 | parser.add_argument('--bert_dir', default='../model_hub/bert-base-chinese/', 17 | help='bert dir for uer') 18 | parser.add_argument('--data_dir', default='./data/cner/', 19 | help='data dir for uer') 20 | parser.add_argument('--log_dir', default='./logs/', 21 | help='log dir for uer') 22 | 23 | # other args 24 | parser.add_argument('--num_tags', default=53, type=int, 25 | help='number of tags') 26 | parser.add_argument('--seed', type=int, default=123, help='random seed') 27 | 28 | parser.add_argument('--gpu_ids', type=str, default='0', 29 | help='gpu ids to use, -1 for cpu, "0,1" for multi gpu') 30 | 31 | parser.add_argument('--max_seq_len', default=256, type=int) 32 | 33 | parser.add_argument('--eval_batch_size', default=12, type=int) 34 | 35 | 36 | # train args 37 | parser.add_argument('--train_epochs', default=15, type=int, 38 | help='Max training epoch') 39 | 40 | parser.add_argument('--dropout_prob', default=0.1, type=float, 41 | help='drop out probability') 42 | 43 | # 2e-5 44 | parser.add_argument('--lr', default=3e-5, type=float, 45 | help='bert学习率') 46 | # 2e-3 47 | parser.add_argument('--other_lr', default=3e-4, type=float, 48 | help='bilstm和多层感知机学习率') 49 | # 0.5 50 | parser.add_argument('--max_grad_norm', default=1, type=float, 51 | help='max grad clip') 52 | parser.add_argument('--use_tensorboard', default="True", 53 | help='max grad clip') 54 | 55 | parser.add_argument('--warmup_proportion', default=0.1, type=float) 56 | 57 | parser.add_argument('--weight_decay', default=0.01, type=float) 58 | 59 | parser.add_argument('--adam_epsilon', default=1e-8, type=float) 60 | 61 | parser.add_argument('--train_batch_size', default=32, type=int) 62 | parser.add_argument('--use_dev_num', default=32, type=int, help="用于验证和测试的数量") 63 | parser.add_argument('--eval_steps', default=32, type=int, help="多少步进行验证") 64 | 65 | 66 | 67 | return parser 68 | 69 | def get_parser(self): 70 | parser = self.parse() 71 | parser = self.initialize(parser) 72 | return parser.parse_args() -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/data/guwen/mid_data/predicates.json: -------------------------------------------------------------------------------- 1 | ["管理", "归属", "讨伐", "作战", "名", "姓", "同名于", "隶属于", "出生地", "父", "弟", "号", "杀", "朋友", "兄", "任职", "属于", "升迁", "去往", "子", "字", "依附", "葬于", "作", "位于"] -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/data/guwen/raw_data/process.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | from collections import defaultdict, Counter 4 | from tqdm import tqdm 5 | import pandas as pd 6 | 7 | if not os.path.exists('../mid_data'): 8 | os.mkdir("../mid_data") 9 | 10 | predicates = set() 11 | 12 | with open('train.json', 'r', encoding='utf-8') as fp: 13 | data = fp.readlines() 14 | 15 | count_lengths = [] 16 | count_predicates = defaultdict(int) 17 | for d in tqdm(data, ncols=100): 18 | d = json.loads(d) 19 | text = d['text'] 20 | spo = d['spo_list'] 21 | predicates.add(spo['predicate']) 22 | count_predicates[spo['predicate']] += 1 23 | count_lengths.append(len(text)) 24 | 25 | with open('../mid_data/predicates.json', 'w', encoding='utf-8') as fp: 26 | json.dump(list(predicates), fp, ensure_ascii=False) 27 | 28 | lengths = Counter(count_lengths) 29 | print(lengths) 30 | print(count_predicates) 31 | 32 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/data_loader.py: -------------------------------------------------------------------------------- 1 | import json 2 | import torch 3 | import numpy as np 4 | from torch.utils.data import DataLoader, Dataset 5 | from utils.common_utils import sequence_padding 6 | 7 | 8 | class ListDataset(Dataset): 9 | def __init__(self, file_path=None, data=None, **kwargs): 10 | self.kwargs = kwargs 11 | if isinstance(file_path, (str, list)): 12 | self.data = self.load_data(file_path) 13 | elif isinstance(data, list): 14 | self.data = data 15 | else: 16 | raise ValueError('The input args shall be str format file_path / list format dataset') 17 | 18 | def __len__(self): 19 | return len(self.data) 20 | 21 | def __getitem__(self, index): 22 | return self.data[index] 23 | 24 | @staticmethod 25 | def load_data(file_path): 26 | return file_path 27 | 28 | 29 | 30 | # 加载数据集 31 | class MyDataset(ListDataset): 32 | @staticmethod 33 | def load_data(filename): 34 | examples = [] 35 | with open(filename, encoding='utf-8') as f: 36 | raw_examples = f.readlines() 37 | # 这里是从json数据中的字典中获取 38 | for i, item in enumerate(raw_examples): 39 | # print(i,item) 40 | item = json.loads(item) 41 | text = item['text'] 42 | spo_list = item['spo_list'] 43 | labels = [] # [subject, predicate, object] 44 | for spo in spo_list: 45 | subject = spo['subject'] 46 | object = spo['object'] 47 | predicate = spo['predicate'] 48 | labels.append([subject, predicate, object]) 49 | examples.append((text, labels)) 50 | return examples 51 | 52 | # 加载古文数据集 53 | class GuwenDataset(ListDataset): 54 | @staticmethod 55 | def load_data(filename): 56 | examples = [] 57 | with open(filename, encoding='utf-8') as f: 58 | raw_examples = f.readlines() 59 | # 这里是从json数据中的字典中获取 60 | for i, item in enumerate(raw_examples): 61 | # print(i,item) 62 | item = json.loads(item) 63 | text = item['text'] 64 | spo = item['spo_list'] 65 | labels = [] # [subject, predicate, object] 66 | subject = spo['subject'] 67 | object = spo['object'] 68 | predicate = spo['predicate'] 69 | labels.append([subject, predicate, object]) 70 | examples.append((text, labels)) 71 | return examples 72 | 73 | class Collate: 74 | def __init__(self, max_len, tag2id, device, tokenizer): 75 | self.maxlen = max_len 76 | self.tag2id = tag2id 77 | self.id2tag = {v:k for k,v in tag2id.items()} 78 | self.device = device 79 | self.tokenizer = tokenizer 80 | 81 | def collate_fn(self, batch): 82 | def search(pattern, sequence): 83 | """从sequence中寻找子串pattern 84 | 如果找到,返回第一个下标;否则返回-1。 85 | """ 86 | n = len(pattern) 87 | for i in range(len(sequence)): 88 | if sequence[i:i + n] == pattern: 89 | return i 90 | return -1 91 | batch_head_labels = [] 92 | batch_tail_labels = [] 93 | batch_entity_labels = [] 94 | batch_token_ids = [] 95 | batch_attention_mask = [] 96 | batch_token_type_ids = [] 97 | callback = [] 98 | for i, (text, text_labels) in enumerate(batch): 99 | if len(text) > self.maxlen - 2: 100 | text = text[:self.maxlen - 2] 101 | tokens = [i for i in text] 102 | tokens = ['[CLS]'] + tokens + ['[SEP]'] 103 | spoes = set() 104 | callback_text_labels = [] 105 | for s, p, o in text_labels: 106 | p = self.tag2id[p] 107 | s = [i for i in s] 108 | o = [i for i in o] 109 | s_idx = search(s, tokens) # 主体的头 110 | o_idx = search(o, tokens) # 客体的头 111 | if s_idx != -1 and o_idx != -1: 112 | callback_text_labels.append(("".join(s), self.id2tag[p], "".join(o))) 113 | spoes.add((s_idx, s_idx + len(s) - 1, p, o_idx, o_idx + len(o) - 1)) 114 | # print(text_labels) 115 | # print(text) 116 | # print(spoes) 117 | # 构建标签 118 | entity_labels = [set() for _ in range(2)] # [主体, 客体] 119 | head_labels = [set() for _ in range(len(self.tag2id))] # 每个关系中主体和客体的头 120 | tail_labels = [set() for _ in range(len(self.tag2id))] # 每个关系中主体和客体的尾 121 | for sh, st, p, oh, ot in spoes: 122 | entity_labels[0].add((sh, st)) 123 | entity_labels[1].add((oh, ot)) 124 | head_labels[p].add((sh, oh)) 125 | tail_labels[p].add((st, ot)) 126 | 127 | 128 | for label in entity_labels + head_labels + tail_labels: 129 | if not label: # 至少要有一个标签 130 | label.add((0, 0)) # 如果没有则用0填充 131 | 132 | # entity_labels:(2, 1, 2) head_labels:(49, 1, 2) tail_labels:(49, 1, 2) 133 | """ 134 | 对于entity_labels而言,第一个集合是主体,第二个集合是客体,使用pading补全到相同长度 135 | [{(0, 2)}, {(21, 22), (5, 9)}] 136 | [[[ 0 2] 137 | [ 0 0]] 138 | 139 | [[21 22] 140 | [ 5 9]]] 141 | [['九玄珠', '连载网站', '纵横中文网'], ['九玄珠', '作者', '龙马']] 142 | """ 143 | 144 | entity_labels = sequence_padding([list(l) for l in entity_labels]) # [subject/object=2, 实体个数, 实体起终点] 145 | head_labels = sequence_padding([list(l) for l in head_labels]) # [关系个数, 该关系下subject/object配对数, subject/object起点] 146 | tail_labels = sequence_padding([list(l) for l in tail_labels]) # [关系个数, 该关系下subject/object配对数, subject/object终点] 147 | 148 | 149 | token_ids = self.tokenizer.convert_tokens_to_ids(tokens) 150 | batch_token_ids.append(token_ids) # 前面已经限制了长度 151 | batch_attention_mask.append([1] * len(token_ids)) 152 | batch_token_type_ids.append([0] * len(token_ids)) 153 | batch_head_labels.append(head_labels) 154 | batch_tail_labels.append(tail_labels) 155 | batch_entity_labels.append(entity_labels) 156 | callback.append((text, callback_text_labels)) 157 | batch_token_ids = torch.tensor(sequence_padding(batch_token_ids, length=self.maxlen), dtype=torch.long, device=self.device) 158 | attention_mask = torch.tensor(sequence_padding(batch_attention_mask, length=self.maxlen), dtype=torch.long, device=self.device) 159 | token_type_ids = torch.tensor(sequence_padding(batch_token_type_ids, length=self.maxlen), dtype=torch.long, device=self.device) 160 | batch_head_labels = torch.tensor(sequence_padding(batch_head_labels, seq_dims=2), dtype=torch.float, device=self.device) 161 | batch_tail_labels = torch.tensor(sequence_padding(batch_tail_labels, seq_dims=2), dtype=torch.float, device=self.device) 162 | batch_entity_labels = torch.tensor(sequence_padding(batch_entity_labels, seq_dims=2), dtype=torch.float, device=self.device) 163 | 164 | return batch_token_ids, attention_mask, token_type_ids, batch_head_labels, batch_tail_labels, batch_entity_labels, callback 165 | 166 | 167 | if __name__ == "__main__": 168 | from transformers import BertTokenizer 169 | max_len = 256 170 | tokenizer = BertTokenizer.from_pretrained('model_hub/chinese-bert-wwm-ext/vocab.txt') 171 | train_dataset = MyDataset(file_path='data/ske/raw_data/train_data.json', 172 | tokenizer=tokenizer, 173 | max_len=max_len) 174 | # print(train_dataset[0]) 175 | 176 | with open('data/ske/mid_data/predicates.json') as fp: 177 | labels = json.load(fp) 178 | id2tag = {} 179 | tag2id = {} 180 | for i,label in enumerate(labels): 181 | id2tag[i] = label 182 | tag2id[label] = i 183 | device = torch.device("cuda" if torch.cuda.is_available() else "cpu") 184 | collate = Collate(max_len=max_len, tag2id=tag2id, device=device, tokenizer=tokenizer) 185 | # collate.collate_fn(train_dataset[:16]) 186 | batch_size = 2 187 | train_dataset = train_dataset[:10] 188 | train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=False, collate_fn=collate.collate_fn) 189 | 190 | """ 191 | torch.Size([2, 256]) 192 | torch.Size([2, 256]) 193 | torch.Size([2, 256]) 194 | torch.Size([2, 49, 1, 2]) 195 | torch.Size([2, 49, 1, 2]) 196 | torch.Size([2, 2, 1, 2]) 197 | """ 198 | for i, batch in enumerate(train_dataloader): 199 | leng = len(batch) - 1 200 | for j in range(leng): 201 | print(batch[j].shape) 202 | break -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | import json 4 | from re import template 5 | import numpy as np 6 | from collections import defaultdict 7 | import torch 8 | from torch.utils.data import DataLoader, RandomSampler 9 | from transformers import BertTokenizer 10 | 11 | import config 12 | import data_loader 13 | from model import GlobalPointerRe 14 | from utils.common_utils import set_seed, set_logger, read_json, fine_grade_tokenize 15 | from utils.train_utils import load_model_and_parallel, build_optimizer_and_scheduler, save_model 16 | from utils.metric_utils import calculate_metric_relation, get_p_r_f 17 | from tensorboardX import SummaryWriter 18 | 19 | args = config.Args().get_parser() 20 | set_seed(args.seed) 21 | logger = logging.getLogger(__name__) 22 | 23 | if args.use_tensorboard == "True": 24 | writer = SummaryWriter(log_dir='./tensorboard') 25 | 26 | 27 | class BertForRe: 28 | def __init__(self, args, train_loader, dev_loader, test_loader, id2tag, tag2id, model, device): 29 | self.train_loader = train_loader 30 | self.dev_loader = dev_loader 31 | self.test_loader = test_loader 32 | self.args = args 33 | self.id2tag = id2tag 34 | self.tag2id = tag2id 35 | self.model = model 36 | self.device = device 37 | if train_loader is not None: 38 | self.t_total = len(self.train_loader) * args.train_epochs 39 | self.optimizer, self.scheduler = build_optimizer_and_scheduler(args, model, self.t_total) 40 | 41 | def train(self): 42 | # Train 43 | global_step = 0 44 | self.model.zero_grad() 45 | eval_steps = args.eval_steps #每多少个step打印损失及进行验证 46 | best_f1 = 0.0 47 | for epoch in range(self.args.train_epochs): 48 | for step, batch_data in enumerate(self.train_loader): 49 | self.model.train() 50 | for batch in batch_data[:-1]: 51 | batch = batch.to(self.device) 52 | # batch_token_ids, attention_mask, token_type_ids, batch_head_labels, batch_tail_labels, batch_entity_ids 53 | all_loss = self.model(batch_data[0], batch_data[1], batch_data[2], batch_data[3], batch_data[4], batch_data[5]) 54 | loss = all_loss['loss'] 55 | entity_loss = all_loss['entity_loss'] 56 | head_loss = all_loss['head_loss'] 57 | tail_loss = all_loss['tail_loss'] 58 | # loss.backward(loss.clone().detach()) 59 | loss.backward() 60 | torch.nn.utils.clip_grad_norm_(self.model.parameters(), self.args.max_grad_norm) 61 | self.optimizer.step() 62 | self.scheduler.step() 63 | self.model.zero_grad() 64 | logger.info('【train】 epoch:{} {}/{} loss:{:.4f} entity_loss:{:.4f} head_loss:{:.4f} tail_loss:{:.4f}'.format( 65 | epoch, global_step, self.t_total, loss.item(), entity_loss.item(), head_loss.item(), tail_loss.item())) 66 | global_step += 1 67 | 68 | if self.args.use_tensorboard == "True": 69 | writer.add_scalar('data/loss', loss.item(), global_step) 70 | if global_step % eval_steps == 0: 71 | precision, recall, f1_score = self.dev() 72 | logger.info('[eval] precision={:.4f} recall={:.4f} f1_score={:.4f}'.format(precision, recall, f1_score)) 73 | if f1_score > best_f1: 74 | save_model(self.args, self.model, model_name, global_step) 75 | best_f1 = f1_score 76 | 77 | 78 | def dev(self): 79 | self.model.eval() 80 | spos = [] 81 | true_spos = [] 82 | subjects = [] 83 | objects = [] 84 | all_examples = [] 85 | with torch.no_grad(): 86 | for eval_step, dev_batch_data in enumerate(dev_loader): 87 | for dev_batch in dev_batch_data[:-1]: 88 | dev_batch = dev_batch.to(device) 89 | 90 | entity_output, head_output, tail_output = model(dev_batch_data[0], dev_batch_data[1], dev_batch_data[2]) 91 | cur_batch_size = dev_batch_data[0].shape[0] 92 | dev_examples = dev_batch_data[-1] 93 | true_spos += [i[1] for i in dev_examples] 94 | all_examples += [i[0] for i in dev_examples] 95 | 96 | # torch.Size([8, 2, 256, 256]) torch.Size([8, 49, 256, 256]) torch.Size([8, 49, 256, 256]) 97 | # print(entity_output.shape, head_output.shape, tail_output.shape) 98 | for i in range(cur_batch_size): 99 | example = dev_examples[i][0] 100 | l = len(example) 101 | subject = [] 102 | object = [] 103 | subject_ids = [] 104 | object_ids = [] 105 | spo = [] 106 | single_entity_output = entity_output[i, ...] 107 | single_head_output = head_output[i, ...] 108 | single_tail_output = tail_output[i, ...] 109 | single_head_output = single_head_output[:, 1:l+1:, 1:l+1] 110 | single_tail_output = single_tail_output[:, 1:l+1:, 1:l+1] 111 | subject_entity_outpout = single_entity_output[:1, 1:l+1:, 1:l+1].squeeze() 112 | object_entity_output = single_entity_output[1:, 1:l+1:, 1:l+1].squeeze() 113 | # 注意这里阈值为什么是0 114 | subject_entity_outpout = np.where(subject_entity_outpout.cpu().numpy() > 0) 115 | object_entity_output = np.where(object_entity_output.cpu().numpy() > 0) 116 | for m,n in zip(*subject_entity_outpout): 117 | subject_ids.append((m, n)) 118 | for m,n in zip(*object_entity_output): 119 | object_ids.append((m, n)) 120 | for sh, st in subject_ids: 121 | for oh, ot in object_ids: 122 | # print(example[sh:st+1], example[oh:ot+1]) 123 | # print(np.where(single_head_output[:, sh, oh].cpu().numpy() > 0)) 124 | # print(np.where(single_tail_output[:, st, ot].cpu().numpy() > 0)) 125 | subj = example[sh:st+1] 126 | obj = example[oh:ot+1] 127 | subject.append(subj) 128 | object.append(obj) 129 | 130 | re1 = np.where(single_head_output[:, sh, oh].cpu().numpy() > 0)[0] 131 | re2 = np.where(single_tail_output[:, st, ot].cpu().numpy() > 0)[0] 132 | res = set(re1) & set(re2) 133 | for r in res: 134 | spo.append((subj, self.id2tag[r], obj)) 135 | subjects.append(subject) 136 | objects.append(object) 137 | spos.append(spo) 138 | 139 | 140 | tp, fp, fn = calculate_metric_relation(spos, true_spos) 141 | p, r, f1 = get_p_r_f(tp, fp, fn) 142 | 143 | return p, r, f1 144 | 145 | 146 | 147 | def test(self, model_path): 148 | model = GlobalPointerRe(self.args) 149 | model, device = load_model_and_parallel(model, self.args.gpu_ids, model_path) 150 | model.eval() 151 | spos = [] 152 | true_spos = [] 153 | subjects = [] 154 | objects = [] 155 | all_examples = [] 156 | with torch.no_grad(): 157 | for eval_step, dev_batch_data in enumerate(dev_loader): 158 | for dev_batch in dev_batch_data[:-1]: 159 | dev_batch = dev_batch.to(device) 160 | 161 | entity_output, head_output, tail_output = model(dev_batch_data[0], dev_batch_data[1], dev_batch_data[2]) 162 | cur_batch_size = dev_batch_data[0].shape[0] 163 | dev_examples = dev_batch_data[-1] 164 | true_spos += [i[1] for i in dev_examples] 165 | all_examples += [i[0] for i in dev_examples] 166 | 167 | # torch.Size([8, 2, 256, 256]) torch.Size([8, 49, 256, 256]) torch.Size([8, 49, 256, 256]) 168 | # print(entity_output.shape, head_output.shape, tail_output.shape) 169 | for i in range(cur_batch_size): 170 | example = dev_examples[i][0] 171 | l = len(example) 172 | subject = [] 173 | object = [] 174 | subject_ids = [] 175 | object_ids = [] 176 | spo = [] 177 | single_entity_output = entity_output[i, ...] 178 | single_head_output = head_output[i, ...] 179 | single_tail_output = tail_output[i, ...] 180 | single_head_output = single_head_output[:, 1:l+1:, 1:l+1] 181 | single_tail_output = single_tail_output[:, 1:l+1:, 1:l+1] 182 | subject_entity_outpout = single_entity_output[:1, 1:l+1:, 1:l+1].squeeze() 183 | object_entity_output = single_entity_output[1:, 1:l+1:, 1:l+1].squeeze() 184 | # 注意这里阈值为什么是0 185 | subject_entity_outpout = np.where(subject_entity_outpout.cpu().numpy() > 0) 186 | object_entity_output = np.where(object_entity_output.cpu().numpy() > 0) 187 | for m,n in zip(*subject_entity_outpout): 188 | subject_ids.append((m, n)) 189 | for m,n in zip(*object_entity_output): 190 | object_ids.append((m, n)) 191 | for sh, st in subject_ids: 192 | for oh, ot in object_ids: 193 | # print(example[sh:st+1], example[oh:ot+1]) 194 | # print(np.where(single_head_output[:, sh, oh].cpu().numpy() > 0)) 195 | # print(np.where(single_tail_output[:, st, ot].cpu().numpy() > 0)) 196 | subj = example[sh:st+1] 197 | obj = example[oh:ot+1] 198 | subject.append(subj) 199 | object.append(obj) 200 | 201 | re1 = np.where(single_head_output[:, sh, oh].cpu().numpy() > 0)[0] 202 | re2 = np.where(single_tail_output[:, st, ot].cpu().numpy() > 0)[0] 203 | res = set(re1) & set(re2) 204 | for r in res: 205 | spo.append((subj, self.id2tag[r], obj)) 206 | subjects.append(subject) 207 | objects.append(object) 208 | spos.append(spo) 209 | 210 | 211 | # for i, (m, n, ex) in enumerate(zip(spos, true_spos, all_examples)): 212 | # if i <= 10: 213 | # print(ex) 214 | # print(m, n) 215 | # print('='*100) 216 | # print(len(all_examples)) 217 | # print(len(true_spos)) 218 | # print(len(spos)) 219 | tp, fp, fn = calculate_metric_relation(spos, true_spos) 220 | p, r, f1 = get_p_r_f(tp, fp, fn) 221 | print("========metric========") 222 | print("precision:{} recall:{} f1:{}".format(p, r, f1)) 223 | 224 | return p, r, f1 225 | 226 | def predict(self, raw_text, model, tokenizer): 227 | model.eval() 228 | with torch.no_grad(): 229 | tokens = [i for i in raw_text] 230 | if len(tokens) > self.args.max_seq_len - 2: 231 | tokens = tokens[:self.args.max_seq_len - 2] 232 | tokens = ['[CLS]'] + tokens + ['[SEP]'] 233 | token_ids = tokenizer.convert_tokens_to_ids(tokens) 234 | attention_masks = [1] * len(token_ids) 235 | token_type_ids = [0] * len(token_ids) 236 | if len(token_ids) < self.args.max_seq_len: 237 | token_ids = token_ids + [0] * (self.args.max_seq_len - len(tokens)) 238 | attention_masks = attention_masks + [0] * (self.args.max_seq_len - len(tokens)) 239 | token_type_ids = token_type_ids + [0] * (self.args.max_seq_len - len(tokens)) 240 | assert len(token_ids) == self.args.max_seq_len 241 | assert len(attention_masks) == self.args.max_seq_len 242 | assert len(token_type_ids) == self.args.max_seq_len 243 | token_ids = torch.from_numpy(np.array(token_ids)).unsqueeze(0).to(self.device) 244 | attention_masks = torch.from_numpy(np.array(attention_masks, dtype=np.uint8)).unsqueeze(0).to(self.device) 245 | token_type_ids = torch.from_numpy(np.array(token_type_ids)).unsqueeze(0).to(self.device) 246 | entity_output, head_output, tail_output = model(token_ids, attention_masks, token_type_ids) 247 | 248 | cur_batch_size = entity_output.shape[0] 249 | spos = [] 250 | subjects = [] 251 | objects = [] 252 | # print(entity_output.shape, head_output.shape, tail_output.shape) 253 | for i in range(cur_batch_size): 254 | example = raw_text 255 | l = len(example) 256 | subject = [] 257 | object = [] 258 | subject_ids = [] 259 | object_ids = [] 260 | spo = [] 261 | single_entity_output = entity_output[i, ...] 262 | single_head_output = head_output[i, ...] 263 | single_tail_output = tail_output[i, ...] 264 | single_head_output = single_head_output[:, 1:l+1:, 1:l+1] 265 | single_tail_output = single_tail_output[:, 1:l+1:, 1:l+1] 266 | subject_entity_outpout = single_entity_output[:1, 1:l+1:, 1:l+1].squeeze() 267 | object_entity_output = single_entity_output[1:, 1:l+1:, 1:l+1].squeeze() 268 | # 注意这里阈值为什么是0 269 | subject_entity_outpout = np.where(subject_entity_outpout.cpu().numpy() > 0) 270 | object_entity_output = np.where(object_entity_output.cpu().numpy() > 0) 271 | for m,n in zip(*subject_entity_outpout): 272 | subject_ids.append((m, n)) 273 | for m,n in zip(*object_entity_output): 274 | object_ids.append((m, n)) 275 | for sh, st in subject_ids: 276 | for oh, ot in object_ids: 277 | # print(example[sh:st+1], example[oh:ot+1]) 278 | # print(np.where(single_head_output[:, sh, oh].cpu().numpy() > 0)) 279 | # print(np.where(single_tail_output[:, st, ot].cpu().numpy() > 0)) 280 | subj = example[sh:st+1] 281 | obj = example[oh:ot+1] 282 | subject.append(subj) 283 | object.append(obj) 284 | 285 | re1 = np.where(single_head_output[:, sh, oh].cpu().numpy() > 0)[0] 286 | re2 = np.where(single_tail_output[:, st, ot].cpu().numpy() > 0)[0] 287 | res = set(re1) & set(re2) 288 | for r in res: 289 | spo.append((subj, self.id2tag[r], obj)) 290 | 291 | subjects.append(subject) 292 | objects.append(object) 293 | spos.append(spo) 294 | 295 | print("文本:", raw_text) 296 | print('主体:', [list(set(i)) for i in subjects]) 297 | print('客体:', [list(set(i)) for i in objects]) 298 | print('关系:', spos) 299 | print("="*100) 300 | 301 | if __name__ == '__main__': 302 | data_name = 'guwen' 303 | model_name = 'bert' 304 | 305 | set_logger(os.path.join(args.log_dir, '{}.log'.format(model_name))) 306 | data_path = os.path.join(args.data_dir, 'raw_data') 307 | label_list = read_json(os.path.join(args.data_dir, 'mid_data'), 'predicates') 308 | tag2id = {} 309 | id2tag = {} 310 | for k,v in enumerate(label_list): 311 | tag2id[v] = k 312 | id2tag[k] = v 313 | 314 | logger.info(args) 315 | max_seq_len = args.max_seq_len 316 | tokenizer = BertTokenizer.from_pretrained(args.bert_dir) 317 | 318 | model = GlobalPointerRe(args) 319 | model, device = load_model_and_parallel(model, args.gpu_ids) 320 | 321 | collate = data_loader.Collate(max_len=max_seq_len, tag2id=tag2id, device=device, tokenizer=tokenizer) 322 | if data_name == "ske": 323 | train_dataset = data_loader.MyDataset(file_path=os.path.join(data_path, 'train_data.json'), 324 | tokenizer=tokenizer, 325 | max_len=max_seq_len) 326 | 327 | train_loader = DataLoader(train_dataset, batch_size=args.train_batch_size, shuffle=True, collate_fn=collate.collate_fn) 328 | dev_dataset = data_loader.MyDataset(file_path=os.path.join(data_path, 'dev_data.json'), 329 | tokenizer=tokenizer, 330 | max_len=max_seq_len) 331 | 332 | dev_dataset = dev_dataset[:args.use_dev_num] 333 | dev_loader = DataLoader(dev_dataset, batch_size=args.eval_batch_size, shuffle=False, collate_fn=collate.collate_fn) 334 | 335 | 336 | texts = [ 337 | '查尔斯·阿兰基斯(Charles Aránguiz),1989年4月17日出生于智利圣地亚哥,智利职业足球运动员,司职中场,效力于德国足球甲级联赛勒沃库森足球俱乐部', 338 | '《离开》是由张宇谱曲,演唱', 339 | '《愤怒的唐僧》由北京吴意波影视文化工作室与优酷电视剧频道联合制作,故事以喜剧元素为主,讲述唐僧与佛祖打牌,得罪了佛祖,被踢下人间再渡九九八十一难的故事', 340 | '李治即位后,萧淑妃受宠,王皇后为了排挤萧淑妃,答应李治让身在感业寺的武则天续起头发,重新纳入后宫', 341 | '《工业4.0》是2015年机械工业出版社出版的图书,作者是(德)阿尔冯斯·波特霍夫,恩斯特·安德雷亚斯·哈特曼', 342 | '周佛海被捕入狱之后,其妻杨淑慧散尽家产请蒋介石枪下留人,于是周佛海从死刑变为无期,不过此人或许作恶多端,改判没多久便病逝于监狱,据悉是心脏病发作', 343 | '《李烈钧自述》是2011年11月1日人民日报出版社出版的图书,作者是李烈钧', 344 | '除演艺事业外,李冰冰热心公益,发起并亲自参与多项环保慈善活动,积极投身其中,身体力行担起了回馈社会的责任于02年出演《少年包青天》,进入大家视线', 345 | '马志舟,1907年出生,陕西三原人,汉族,中国共产党,任红四团第一连连长,1933年逝世', 346 | '斑刺莺是雀形目、剌嘴莺科的一种动物,分布于澳大利亚和新西兰,包括澳大利亚、新西兰、塔斯马尼亚及其附近的岛屿', 347 | '《课本上学不到的生物学2》是2013年上海科技教育出版社出版的图书', 348 | ] 349 | 350 | elif data_name == "guwen": 351 | 352 | train_dataset = data_loader.GuwenDataset(file_path=os.path.join(data_path, 'train.json'), 353 | tokenizer=tokenizer, 354 | max_len=max_seq_len) 355 | 356 | train_loader = DataLoader(train_dataset, batch_size=args.train_batch_size, shuffle=True, collate_fn=collate.collate_fn) 357 | dev_dataset = data_loader.GuwenDataset(file_path=os.path.join(data_path, 'dev.json'), 358 | tokenizer=tokenizer, 359 | max_len=max_seq_len) 360 | 361 | dev_dataset = dev_dataset[:args.use_dev_num] 362 | dev_loader = DataLoader(dev_dataset, batch_size=args.eval_batch_size, shuffle=False, collate_fn=collate.collate_fn) 363 | 364 | texts = [ 365 | "召公为保,周公为师,东伐淮夷,残奄,迁其君薄姑。成王自奄归,在宗周,作多方。既绌殷命,袭淮夷,归在丰,作周官", 366 | "初,尔朱荣将入洛,父劭恐,以韶寄所亲荥阳太守郑仲明。仲明寻为城人所杀,韶因乱与乳母相失,遂与仲明兄子僧副避难。", 367 | "明宗时,熙载南奔吴,谷送至正阳,酒酣临诀,熙载谓谷曰“江左用吾为相,当长驱以定中原”谷曰“中国用吾为相,取江南如探囊中物尔”及周师之征淮也,命谷为将,以取淮南,而熙载不能有所为也", 368 | "楚围雍氏,秦使庶长疾助韩而东攻齐,到满助魏攻燕。十四年,伐楚,取召陵。丹、犁臣,蜀相壮杀蜀侯来降。惠王卒,子武王立", 369 | ] 370 | 371 | 372 | bertForNer = BertForRe(args, train_loader, dev_loader, dev_loader, id2tag, tag2id, model, device) 373 | bertForNer.train() 374 | 375 | model_path = './checkpoints/{}/model.pt'.format(model_name) 376 | bertForNer.test(model_path) 377 | 378 | with open("./checkpoints/{}/args.json".format(model_name), "w", encoding="utf-8") as fp: 379 | json.dump(vars(args), fp, ensure_ascii=False) 380 | 381 | model = GlobalPointerRe(args) 382 | model, device = load_model_and_parallel(model, args.gpu_ids, model_path) 383 | for text in texts: 384 | bertForNer.predict(text, model, tokenizer) 385 | 386 | 387 | 388 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/model.py: -------------------------------------------------------------------------------- 1 | import math 2 | import torch 3 | import numpy as np 4 | import torch.nn as nn 5 | from transformers import BertModel 6 | 7 | class SparseMultilabelCategoricalCrossentropy(nn.Module): 8 | """稀疏版多标签分类的交叉熵 9 | 说明: 10 | 1. y_true.shape=[..., num_positive], 11 | y_pred.shape=[..., num_classes]; 12 | 2. 请保证y_pred的值域是全体实数,换言之一般情况下 13 | y_pred不用加激活函数,尤其是不能加sigmoid或者 14 | softmax; 15 | 3. 预测阶段则输出y_pred大于0的类; 16 | 4. 详情请看:https://kexue.fm/archives/7359 。 17 | """ 18 | def __init__(self, mask_zero=False, epsilon=1e-7, **kwargs): 19 | super().__init__(**kwargs) 20 | self.mask_zero = mask_zero 21 | self.epsilon = epsilon 22 | 23 | def forward(self, y_pred, y_true): 24 | zeros = torch.zeros_like(y_pred[..., :1]) 25 | y_pred = torch.cat([y_pred, zeros], dim=-1) 26 | if self.mask_zero: 27 | infs = zeros + float('inf') 28 | y_pred = torch.cat([infs, y_pred[..., 1:]], dim=-1) 29 | y_pos_2 = torch.gather(y_pred, dim=-1, index=y_true) 30 | y_pos_1 = torch.cat([y_pos_2, zeros], dim=-1) 31 | if self.mask_zero: 32 | y_pred = torch.cat([-infs, y_pred[..., 1:]], dim=-1) 33 | y_pos_2 = torch.gather(y_pred, dim=-1, index=y_true) 34 | pos_loss = torch.logsumexp(-y_pos_1, dim=-1) 35 | all_loss = torch.logsumexp(y_pred, dim=-1) # a 36 | aux_loss = torch.logsumexp(y_pos_2, dim=-1) - all_loss # b-a 37 | aux_loss = torch.clamp(1 - torch.exp(aux_loss), self.epsilon, 1) # 1-exp(b-a) 38 | neg_loss = all_loss + torch.log(aux_loss) # a + log[1-exp(b-a)] 39 | return pos_loss + neg_loss 40 | 41 | 42 | class MyLoss(SparseMultilabelCategoricalCrossentropy): 43 | def __init__(self, **kwargs): 44 | super().__init__(**kwargs) 45 | def forward(self, y_preds, y_trues): 46 | ''' y_preds: [Tensor], shape为[btz, heads, seq_len ,seq_len] 47 | ''' 48 | loss_list = [] 49 | for y_pred, y_true in zip(y_preds, y_trues): 50 | shape = y_pred.shape 51 | # 乘以seq_len是因为(i, j)在展开到seq_len*seq_len维度对应的下标是i*seq_len+j 52 | y_true = y_true[..., 0] * shape[2] + y_true[..., 1] # [btz, heads, 实体起终点的下标] 53 | y_pred = y_pred.reshape(shape[0], -1, np.prod(shape[2:])) # [btz, heads, seq_len*seq_len] 54 | loss = super().forward(y_pred, y_true.long()) 55 | loss = torch.mean(torch.sum(loss, dim=1)) 56 | loss_list.append(loss) 57 | return {'loss': sum(loss_list)/3, 'entity_loss': loss_list[0], 'head_loss': loss_list[1], 'tail_loss': loss_list[2]} 58 | 59 | 60 | def get_sinusoid_encoding_table(n_position, d_hid, padding_idx=None): 61 | '''Returns: [seq_len, d_hid] 62 | ''' 63 | position = torch.arange(0, n_position, dtype=torch.float).unsqueeze(1) 64 | div_term = torch.exp(torch.arange(0, d_hid, 2).float() * (-math.log(10000.0) / d_hid)) 65 | embeddings_table = torch.zeros(n_position, d_hid) 66 | embeddings_table[:, 0::2] = torch.sin(position * div_term) 67 | embeddings_table[:, 1::2] = torch.cos(position * div_term) 68 | return embeddings_table 69 | 70 | 71 | class RoPEPositionEncoding(nn.Module): 72 | """旋转式位置编码: https://kexue.fm/archives/8265 73 | """ 74 | def __init__(self, max_position, embedding_size): 75 | super(RoPEPositionEncoding, self).__init__() 76 | position_embeddings = get_sinusoid_encoding_table(max_position, embedding_size) # [seq_len, hdsz] 77 | cos_position = position_embeddings[:, 1::2].repeat_interleave(2, dim=-1) 78 | sin_position = position_embeddings[:, ::2].repeat_interleave(2, dim=-1) 79 | # register_buffer是为了最外层model.to(device),不用内部指定device 80 | self.register_buffer('cos_position', cos_position) 81 | self.register_buffer('sin_position', sin_position) 82 | 83 | def forward(self, qw, seq_dim=-2): 84 | # 默认最后两个维度为[seq_len, hdsz] 85 | seq_len = qw.shape[seq_dim] 86 | qw2 = torch.stack([-qw[..., 1::2], qw[..., ::2]], dim=-1).reshape_as(qw) 87 | return qw * self.cos_position[:seq_len] + qw2 * self.sin_position[:seq_len] 88 | 89 | 90 | class EfficientGlobalPointer(nn.Module): 91 | """更加参数高效的GlobalPointer 92 | 参考:https://kexue.fm/archives/8877 93 | """ 94 | def __init__(self, hidden_size, heads, head_size, RoPE=True, max_len=512, use_bias=True, tril_mask=True): 95 | super().__init__() 96 | self.heads = heads 97 | self.head_size = head_size 98 | self.RoPE = RoPE 99 | self.tril_mask = tril_mask 100 | 101 | self.p_dense = nn.Linear(hidden_size, head_size * 2, bias=use_bias) 102 | self.q_dense = nn.Linear(head_size * 2, heads * 2, bias=use_bias) 103 | if self.RoPE: 104 | self.position_embedding = RoPEPositionEncoding(max_len, head_size) 105 | 106 | def forward(self, inputs, mask=None): 107 | ''' inputs: [..., hdsz] 108 | mask: [bez, seq_len], padding部分为0 109 | ''' 110 | sequence_output = self.p_dense(inputs) # [..., head_size*2] 111 | qw, kw = sequence_output[..., :self.head_size], sequence_output[..., self.head_size:] # [..., heads, head_size] 112 | 113 | # ROPE编码 114 | if self.RoPE: 115 | qw = self.position_embedding(qw) 116 | kw = self.position_embedding(kw) 117 | 118 | # 计算内积 119 | logits = torch.einsum('bmd,bnd->bmn', qw, kw) / self.head_size**0.5 # [btz, seq_len, seq_len] 120 | bias_input = self.q_dense(sequence_output) # [..., heads*2] 121 | bias = torch.stack(torch.chunk(bias_input, self.heads, dim=-1), dim=-2).transpose(1,2) # [btz, head_size, seq_len,2] 122 | logits = logits.unsqueeze(1) + bias[..., :1] + bias[..., 1:].transpose(2, 3) # [btz, head_size, seq_len, seq_len] 123 | 124 | # 排除padding 125 | if mask is not None: 126 | attention_mask1 = 1 - mask.unsqueeze(1).unsqueeze(3) # [btz, 1, seq_len, 1] 127 | attention_mask2 = 1 - mask.unsqueeze(1).unsqueeze(2) # [btz, 1, 1, seq_len] 128 | logits = logits.masked_fill(attention_mask1.bool(), value=-float('inf')) 129 | logits = logits.masked_fill(attention_mask2.bool(), value=-float('inf')) 130 | 131 | # 排除下三角 132 | if self.tril_mask: 133 | logits = logits - torch.tril(torch.ones_like(logits), -1) * 1e12 134 | 135 | return logits 136 | 137 | 138 | class GlobalPointer(nn.Module): 139 | """全局指针模块 140 | 将序列的每个(start, end)作为整体来进行判断 141 | 参考:https://kexue.fm/archives/8373 142 | """ 143 | def __init__(self, hidden_size, heads, head_size, RoPE=True, max_len=512, use_bias=True, tril_mask=True): 144 | super().__init__() 145 | self.heads = heads 146 | self.head_size = head_size 147 | self.RoPE = RoPE 148 | self.tril_mask = tril_mask 149 | 150 | self.dense = nn.Linear(hidden_size, heads * head_size * 2, bias=use_bias) 151 | if self.RoPE: 152 | self.position_embedding = RoPEPositionEncoding(max_len, head_size) 153 | 154 | 155 | 156 | def forward(self, inputs, mask=None): 157 | ''' inputs: [..., hdsz] 158 | mask: [bez, seq_len], padding部分为0 159 | ''' 160 | # [batchsize, 150, 8*64*2] 161 | sequence_output = self.dense(inputs) # [..., heads*head_size*2] 162 | # torch.chunk(sequence_output, self.heads, dim=-1) 8个(batchsize, 150, 64*2) 163 | # [batchsize, 150, 8, 64*2] 164 | sequence_output = torch.stack(torch.chunk(sequence_output, self.heads, dim=-1), dim=-2) # [..., heads, head_size*2] 165 | # qw:[batchsize, 150, 8, 64], kw:[batchsize, 150, 8, 64] 166 | qw, kw = sequence_output[..., :self.head_size], sequence_output[..., self.head_size:] # [..., heads, head_size] 167 | 168 | # ROPE编码 169 | if self.RoPE: 170 | qw = self.position_embedding(qw) 171 | kw = self.position_embedding(kw) 172 | 173 | # 计算内积 174 | logits = torch.einsum('bmhd,bnhd->bhmn', qw, kw) # [btz, heads, seq_len, seq_len] 175 | 176 | # 排除padding 177 | if mask is not None: 178 | attention_mask1 = 1 - mask.unsqueeze(1).unsqueeze(3) # [btz, 1, seq_len, 1] 179 | attention_mask2 = 1 - mask.unsqueeze(1).unsqueeze(2) # [btz, 1, 1, seq_len] 180 | logits = logits.masked_fill(attention_mask1.bool(), value=-float('inf')) 181 | logits = logits.masked_fill(attention_mask2.bool(), value=-float('inf')) 182 | 183 | # 排除下三角 184 | if self.tril_mask: 185 | logits = logits - torch.tril(torch.ones_like(logits), -1) * 1e12 186 | 187 | return logits / self.head_size**0.5 188 | 189 | 190 | class GlobalPointerRe(nn.Module): 191 | def __init__(self, args): 192 | super().__init__() 193 | self.bert = BertModel.from_pretrained(args.bert_dir, output_hidden_states=True, 194 | hidden_dropout_prob=args.dropout_prob) 195 | self.entity_output = GlobalPointer(hidden_size=768, heads=2, head_size=64) 196 | self.head_output = GlobalPointer(hidden_size=768, heads=args.num_tags, head_size=64, RoPE=False, tril_mask=False) 197 | self.tail_output = GlobalPointer(hidden_size=768, heads=args.num_tags, head_size=64, RoPE=False, tril_mask=False) 198 | self.criterion = MyLoss(mask_zero=True) 199 | 200 | def forward(self, 201 | token_ids, 202 | attention_masks, 203 | token_type_ids, 204 | head_labels=None, 205 | tail_labels=None, 206 | entity_labels=None): 207 | bert_output = self.bert(token_ids, attention_masks, token_type_ids) # [btz, seq_len, hdsz] 208 | hidden_states = bert_output[0] 209 | mask = attention_masks 210 | 211 | entity_output = self.entity_output(hidden_states, mask) # [btz, heads, seq_len, seq_len] 212 | head_output = self.head_output(hidden_states, mask) # [btz, heads, seq_len, seq_len] 213 | tail_output = self.tail_output(hidden_states, mask) # [btz, heads, seq_len, seq_len] 214 | if head_labels is None: 215 | return entity_output, head_output, tail_output 216 | loss = self.criterion([entity_output, head_output, tail_output], [entity_labels, head_labels, tail_labels]) 217 | return loss -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/utils/__pycache__/common_utils.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_triple_extraction/utils/__pycache__/common_utils.cpython-37.pyc -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/utils/__pycache__/metric_utils.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_triple_extraction/utils/__pycache__/metric_utils.cpython-37.pyc -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/utils/__pycache__/train_utils.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taishan1994/classical_chinese_extraction/c9e71015645f4a09d436225cff2a7e0e71b67245/pytorch_GlobalPointer_triple_extraction/utils/__pycache__/train_utils.cpython-37.pyc -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/utils/common_utils.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import random 3 | import os 4 | import json 5 | import logging 6 | import time 7 | import pickle 8 | import numpy as np 9 | import torch 10 | from torch.nn.utils.rnn import pad_sequence 11 | 12 | 13 | def trans_ij2k(seq_len, i, j): 14 | '''把第i行,第j列转化成上三角flat后的序号 15 | ''' 16 | if (i > seq_len - 1) or (j > seq_len - 1) or (i > j): 17 | return 0 18 | return int(0.5*(2*seq_len-i+1)*i+(j-i)) 19 | 20 | def sequence_padding(inputs, length=None, value=0, seq_dims=1, mode='post'): 21 | """将序列padding到同一长度 22 | """ 23 | if isinstance(inputs[0], (np.ndarray, list)): 24 | if length is None: 25 | length = np.max([np.shape(x)[:seq_dims] for x in inputs], axis=0) 26 | elif not hasattr(length, '__getitem__'): 27 | length = [length] 28 | 29 | slices = [np.s_[:length[i]] for i in range(seq_dims)] 30 | slices = tuple(slices) if len(slices) > 1 else slices[0] 31 | pad_width = [(0, 0) for _ in np.shape(inputs[0])] 32 | 33 | outputs = [] 34 | for x in inputs: 35 | x = x[slices] 36 | for i in range(seq_dims): 37 | if mode == 'post': 38 | pad_width[i] = (0, length[i] - np.shape(x)[i]) 39 | elif mode == 'pre': 40 | pad_width[i] = (length[i] - np.shape(x)[i], 0) 41 | else: 42 | raise ValueError('"mode" argument must be "post" or "pre".') 43 | x = np.pad(x, pad_width, 'constant', constant_values=value) 44 | outputs.append(x) 45 | 46 | return np.array(outputs) 47 | 48 | elif isinstance(inputs[0], torch.Tensor): 49 | assert mode == 'post', '"mode" argument must be "post" when element is torch.Tensor' 50 | if length is not None: 51 | inputs = [i[:length] for i in inputs] 52 | return pad_sequence(inputs, padding_value=value, batch_first=True) 53 | else: 54 | raise ValueError('"input" argument must be tensor/list/ndarray.') 55 | 56 | 57 | def timer(func): 58 | """ 59 | 函数计时器 60 | :param func: 61 | :return: 62 | """ 63 | 64 | @functools.wraps(func) 65 | def wrapper(*args, **kwargs): 66 | start = time.time() 67 | res = func(*args, **kwargs) 68 | end = time.time() 69 | print("{}共耗时约{:.4f}秒".format(func.__name__, end - start)) 70 | return res 71 | 72 | return wrapper 73 | 74 | 75 | def set_seed(seed=123): 76 | """ 77 | 设置随机数种子,保证实验可重现 78 | :param seed: 79 | :return: 80 | """ 81 | random.seed(seed) 82 | torch.manual_seed(seed) 83 | np.random.seed(seed) 84 | torch.cuda.manual_seed_all(seed) 85 | 86 | 87 | def set_logger(log_path): 88 | """ 89 | 配置log 90 | :param log_path:s 91 | :return: 92 | """ 93 | logger = logging.getLogger() 94 | logger.setLevel(logging.INFO) 95 | 96 | # 由于每调用一次set_logger函数,就会创建一个handler,会造成重复打印的问题,因此需要判断root logger中是否已有该handler 97 | if not any(handler.__class__ == logging.FileHandler for handler in logger.handlers): 98 | file_handler = logging.FileHandler(log_path) 99 | formatter = logging.Formatter( 100 | '%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)d - %(message)s') 101 | file_handler.setFormatter(formatter) 102 | logger.addHandler(file_handler) 103 | 104 | if not any(handler.__class__ == logging.StreamHandler for handler in logger.handlers): 105 | stream_handler = logging.StreamHandler() 106 | stream_handler.setFormatter(logging.Formatter('%(message)s')) 107 | logger.addHandler(stream_handler) 108 | 109 | 110 | def save_json(data_dir, data, desc): 111 | """保存数据为json""" 112 | with open(os.path.join(data_dir, '{}.json'.format(desc)), 'w', encoding='utf-8') as f: 113 | json.dump(data, f, ensure_ascii=False, indent=2) 114 | 115 | 116 | def read_json(data_dir, desc): 117 | """读取数据为json""" 118 | with open(os.path.join(data_dir, '{}.json'.format(desc)), 'r', encoding='utf-8') as f: 119 | data = json.load(f) 120 | return data 121 | 122 | 123 | def save_pkl(data_dir, data, desc): 124 | """保存.pkl文件""" 125 | with open(os.path.join(data_dir, '{}.pkl'.format(desc)), 'wb') as f: 126 | pickle.dump(data, f) 127 | 128 | 129 | def read_pkl(data_dir, desc): 130 | """读取.pkl文件""" 131 | with open(os.path.join(data_dir, '{}.pkl'.format(desc)), 'rb') as f: 132 | data = pickle.load(f) 133 | return data 134 | 135 | 136 | def fine_grade_tokenize(raw_text, tokenizer): 137 | """ 138 | 序列标注任务 BERT 分词器可能会导致标注偏移, 139 | 用 char-level 来 tokenize 140 | """ 141 | tokens = [] 142 | 143 | for _ch in raw_text: 144 | if _ch in [' ', '\t', '\n']: 145 | tokens.append('[BLANK]') 146 | else: 147 | if not len(tokenizer.tokenize(_ch)): 148 | tokens.append('[INV]') 149 | else: 150 | tokens.append(_ch) 151 | 152 | return tokens -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/utils/metric_utils.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from __future__ import division 3 | from __future__ import print_function 4 | 5 | from collections import defaultdict 6 | 7 | import numpy as np 8 | 9 | 10 | def calculate_metric_relation(predict, gt): 11 | tp, fp, fn = 0, 0, 0 12 | for entity_predict, entity_gt in zip(predict, gt): 13 | # print(entity_predict, entity_gt) 14 | flag = 0 15 | for ent in entity_predict: 16 | if ent in entity_gt: 17 | tp += 1 18 | else: 19 | fp += 1 20 | fn = sum([len(i) for i in gt]) - tp 21 | return tp, fp, fn 22 | 23 | 24 | 25 | def calculate_metric(gt, predict): 26 | """ 27 | 计算 tp fp fn 28 | """ 29 | tp, fp, fn = 0, 0, 0 30 | for entity_predict in predict: 31 | flag = 0 32 | for entity_gt in gt: 33 | if entity_predict[0] == entity_gt[0] and entity_predict[1] == entity_gt[1]: 34 | flag = 1 35 | tp += 1 36 | break 37 | if flag == 0: 38 | fp += 1 39 | 40 | fn = len(gt) - tp 41 | 42 | return np.array([tp, fp, fn]) 43 | 44 | 45 | def get_p_r_f(tp, fp, fn): 46 | p = tp / (tp + fp) if tp + fp != 0 else 0 47 | r = tp / (tp + fn) if tp + fn != 0 else 0 48 | f1 = 2 * p * r / (p + r) if p + r != 0 else 0 49 | return np.array([p, r, f1]) 50 | 51 | def classification_report(metrics_matrix, label_list, id2label, total_count, digits=2, suffix=False): 52 | name_width = max([len(label) for label in label_list]) 53 | last_line_heading = 'micro-f1' 54 | width = max(name_width, len(last_line_heading), digits) 55 | 56 | headers = ["precision", "recall", "f1-score", "support"] 57 | head_fmt = u'{:>{width}s} ' + u' {:>9}' * len(headers) 58 | report = head_fmt.format(u'', *headers, width=width) 59 | report += u'\n\n' 60 | 61 | row_fmt = u'{:>{width}s} ' + u' {:>9.{digits}f}' * 3 + u' {:>9}\n' 62 | 63 | ps, rs, f1s, s = [], [], [], [] 64 | for label_id, label_matrix in enumerate(metrics_matrix): 65 | type_name = id2label[label_id] 66 | p,r,f1 = get_p_r_f(label_matrix[0],label_matrix[1],label_matrix[2]) 67 | nb_true = total_count[label_id] 68 | report += row_fmt.format(*[type_name, p, r, f1, nb_true], width=width, digits=digits) 69 | ps.append(p) 70 | rs.append(r) 71 | f1s.append(f1) 72 | s.append(nb_true) 73 | 74 | report += u'\n' 75 | mirco_metrics = np.sum(metrics_matrix, axis=0) 76 | mirco_metrics = get_p_r_f(mirco_metrics[0], mirco_metrics[1], mirco_metrics[2]) 77 | # compute averages 78 | print('precision:{:.4f} recall:{:.4f} micro_f1:{:.4f}'.format(mirco_metrics[0],mirco_metrics[1],mirco_metrics[2])) 79 | report += row_fmt.format(last_line_heading, 80 | mirco_metrics[0], 81 | mirco_metrics[1], 82 | mirco_metrics[2], 83 | np.sum(s), 84 | width=width, digits=digits) 85 | 86 | return 87 | -------------------------------------------------------------------------------- /pytorch_GlobalPointer_triple_extraction/utils/train_utils.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import os 3 | import logging 4 | from transformers import AdamW, get_linear_schedule_with_warmup 5 | import torch 6 | 7 | logger = logging.getLogger(__name__) 8 | 9 | 10 | def build_optimizer_and_scheduler(args, model, t_total): 11 | module = ( 12 | model.module if hasattr(model, "module") else model 13 | ) 14 | 15 | # 差分学习率 16 | no_decay = ["bias", "LayerNorm.weight"] 17 | model_param = list(module.named_parameters()) 18 | 19 | bert_param_optimizer = [] 20 | other_param_optimizer = [] 21 | 22 | for name, para in model_param: 23 | space = name.split('.') 24 | # print(name) 25 | if space[0] == 'bert_module': 26 | bert_param_optimizer.append((name, para)) 27 | else: 28 | other_param_optimizer.append((name, para)) 29 | 30 | optimizer_grouped_parameters = [ 31 | # bert other module 32 | {"params": [p for n, p in bert_param_optimizer if not any(nd in n for nd in no_decay)], 33 | "weight_decay": args.weight_decay, 'lr': args.lr}, 34 | {"params": [p for n, p in bert_param_optimizer if any(nd in n for nd in no_decay)], 35 | "weight_decay": 0.0, 'lr': args.lr}, 36 | 37 | # 其他模块,差分学习率 38 | {"params": [p for n, p in other_param_optimizer if not any(nd in n for nd in no_decay)], 39 | "weight_decay": args.weight_decay, 'lr': args.other_lr}, 40 | {"params": [p for n, p in other_param_optimizer if any(nd in n for nd in no_decay)], 41 | "weight_decay": 0.0, 'lr': args.other_lr}, 42 | ] 43 | 44 | optimizer = AdamW(optimizer_grouped_parameters, lr=args.lr, eps=args.adam_epsilon) 45 | scheduler = get_linear_schedule_with_warmup( 46 | optimizer, num_warmup_steps=int(args.warmup_proportion * t_total), num_training_steps=t_total 47 | ) 48 | 49 | return optimizer, scheduler 50 | 51 | def save_model(args, model, model_name, global_step): 52 | """保存最好的验证集效果最好那个模型""" 53 | output_dir = os.path.join(args.output_dir, '{}'.format(model_name, global_step)) 54 | if not os.path.exists(output_dir): 55 | os.makedirs(output_dir, exist_ok=True) 56 | 57 | # take care of model distributed / parallel training 58 | model_to_save = ( 59 | model.module if hasattr(model, "module") else model 60 | ) 61 | logger.info('Saving model checkpoint to {}'.format(output_dir)) 62 | torch.save(model_to_save.state_dict(), os.path.join(output_dir, 'model.pt')) 63 | 64 | def save_model_step(args, model, global_step): 65 | """根据global_step来保存模型""" 66 | output_dir = os.path.join(args.output_dir, 'checkpoint-{}'.format(global_step)) 67 | if not os.path.exists(output_dir): 68 | os.makedirs(output_dir, exist_ok=True) 69 | 70 | # take care of model distributed / parallel training 71 | model_to_save = ( 72 | model.module if hasattr(model, "module") else model 73 | ) 74 | logger.info('Saving model & optimizer & scheduler checkpoint to {}.format(output_dir)') 75 | torch.save(model_to_save.state_dict(), os.path.join(output_dir, 'model.pt')) 76 | 77 | def load_model_and_parallel(model, gpu_ids, ckpt_path=None, strict=True): 78 | """ 79 | 加载模型 & 放置到 GPU 中(单卡 / 多卡) 80 | """ 81 | gpu_ids = gpu_ids.split(',') 82 | 83 | # set to device to the first cuda 84 | device = torch.device("cpu" if gpu_ids[0] == '-1' else "cuda:" + gpu_ids[0]) 85 | 86 | if ckpt_path is not None: 87 | logger.info('Load ckpt from {}'.format(ckpt_path)) 88 | model.load_state_dict(torch.load(ckpt_path, map_location=torch.device('cpu')), strict=strict) 89 | 90 | model.to(device) 91 | 92 | if len(gpu_ids) > 1: 93 | logger.info('Use multi gpus in: {}'.format(gpu_ids)) 94 | gpu_ids = [int(x) for x in gpu_ids] 95 | model = torch.nn.DataParallel(model, device_ids=gpu_ids) 96 | else: 97 | logger.info('Use single gpu in: {}'.format(gpu_ids)) 98 | 99 | return model, device --------------------------------------------------------------------------------