Giter VIP home page Giter VIP logo

mrc_competition_dureader's Introduction

机器阅读理解预训练模型及代码开源

*********************** 更新 ***********************

  • 5/21:开源基于大规模MRC数据再训练的模型(包括roberta-wwm-largemacbert-large
  • 5/18:开源比赛代码

Contents

基于大规模MRC数据再训练

此库发布的再训练模型,在 阅读理解/分类 等任务上均有大幅提高
(已有多位小伙伴在 Dureader、法研杯、医疗问答 等多个比赛中取得top5的好成绩😁)

模型/数据集 Dureader-2021 tencentmedical
F1-score Accuracy
dev / A榜 test-1
macbert-large (哈工大预训练语言模型) 65.49 / 64.27 82.5
roberta-wwm-ext-large (哈工大预训练语言模型) 65.49 / 64.27 82.5
macbert-large (ours) 70.45 / 68.13 83.4
roberta-wwm-ext-large (ours) 68.91 / 66.91 83.1
  • 数据来源

    • 网上收集的大量中文MRC数据 (其中包括公开的MRC数据集以及自己爬取的网页数据等, 囊括了医疗、教育、娱乐、百科、军事、法律、等领域。)
  • 数据构造

    • 清洗
      • 舍弃:context>1024的舍弃、question>64的舍弃、网页标签占比超过30%的舍弃。
      • 重新标注:若answer>64且不完全出现在文档中,则采用模糊匹配: 计算所有片段与answer的相似度(F1值),取相似度最高的且高于阈值(0.8)
    • 数据标注
      • 收集的数据有一部分是不包含的位置标签的,仅仅是(问题-文章-答案)的三元组形式。 所以,对于只有答案而没有位置标签的数据通过正则匹配进行位置标注:
        ① 若答案片段多次出现在文章中,选择上下文与问题最相似的答案片段作为标准答案(使用F1值计算相似度,答案片段的上文48和下文48个字符作为上下文);
        ② 若答案片段只出现一次,则默认该答案为标准答案。
      • 采用滑动窗口将长文档切分为多个重叠的子文档,故一个文档可能会生成多个有答案的子文档。
    • 无答案数据构造
      • 在跨领域数据上训练可以增加数据的领域多样性,进而提高模型的泛化能力,而负样本的引入恰好能使得模型编码尽可能多的数据,加强模型对难样本的识别能力:
        ① 对于每一个问题,随机从数据中捞取context,并保留对应的title作为负样本;(50%)
        ② 对于每一个问题,将其正样本中答案出现的句子删除,以此作为负样本;(20%)
        ③ 对于每一个问题,使用BM25算法召回得分最高的前十个文档,然后根据得分采样出一个context作为负样本, 对于非实体类答案,剔除得分最高的context(30%)
  • 用途

    • 此mrc模型可直接用于open domain点击体验
    • 将此模型放到下游 MRC/分类 任务微调可比直接使用预训练语言模型提高2个点/1个点以上
  • 合作

    • 相关训练数据以及使用更多数据训练的模型/一起打比赛 可邮箱联系([email protected])~
----- 使用方法 -----
from transformers import AutoTokenizer, AutoModelForQuestionAnswering

model_name = "chinese_pretrain_mrc_roberta_wwm_ext_large" # "chinese_pretrain_mrc_macbert_large"

# Use in Transformers
tokenizer = AutoTokenizer.from_pretrained(f"luhua/{model_name}")
model = AutoModelForQuestionAnswering.from_pretrained(f"luhua/{model_name}")

# Use locally(通过 https://huggingface.co/luhua 下载模型及配置文件)
tokenizer = BertTokenizer.from_pretrained(f'./{model_name}')
model = AutoModelForQuestionAnswering.from_pretrained(f'./{model_name}')

仓库介绍

  • 目的
    • 开源了基于MRC数据再训练的模型,在MRC任务下微调,效果大幅优于使用预训练的语言模型,其次,旨在提供一个效果不错的强基线
    • 有些mrc比赛由于"年代久远"整理不过来(others文件夹),但方案和代码都有,对比着看就看懂了
  • 优化
    • 代码基于Hugginface的squad代码。之前自己开发,版本多且许多细节没有考虑,便转移到squad代码上迭代。但其实现的类缺乏对中文的支持,推理结果有一些影响,修改之后 此库能较好的支持中文,抽取的答案精度也尽可能不受影响

运行流程

脚本参数解释

  • --lm: 要加载的模型的文件夹名称
  • --do_train: 开启训练
  • --evaluate_during_training: 开启训练时的验证
  • --do_test: 开启预测
  • --version_2_with_negative: 开启适配于数据中有无答案数据(如:squad2.0、dureader2021)
  • --threads: 数据处理所使用的线程数(可以通过os.cpu_count()查看机器支持的线程数)
一、数据 & 模型:
  • 将train、dev、test等数据放在datasets文件夹下(样例数据已给出,符合格式即可)
  • 通过 export lm=xxx 指定模型目录
二、一键运行
sh train_bert.sh  # sh test_bert.sh
三、无答案问题
  • 如果包含无答案类型数据(如:squad2.0、dureader2021),加入--version_2_with_negative就行
  • 将数据替换为Dureader2021_checklist的数据, 加入--version_2_with_negative即可

小小提示:

  • 代码上传前已经跑通。文件不多,所以如果碰到报错之类的信息,可能是代码路径不对、缺少安装包等问题,一步步解决,可以提issue
  • 环境
    pip install transformers==2.10.0 
    
  • 代码基于transformers 2.10.0版本,但是预训练模型可以使用其他版本加载。转换为tf可使用转换
  • 预训练相关参数 参考

感谢

zhangxiaoyu zhongjialun huanghui nanfulai

mrc_competition_dureader's People

Contributors

luhua-rain avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

mrc_competition_dureader's Issues

运行sh run.sh --para_extraction时报错

PROCESS_NAME="$1"
case $PROCESS_NAME in # 这个位置报错
--para_extraction)
# Start paragraph extraction
if [ ! -d ../data ]; then
echo "Please download the preprocessed data first (See README - Preprocess)"
exit 1
fi
paragraph_extraction ../data ../data/extracted
;;
--prepare|--train|--evaluate|--predict)
# Start Paddle baseline
python run.py $@
;;
*)
echo $"Usage: $0 {--para_extraction|--prepare|--train|--evaluate|--predict}"
esac

运行sh run.sh --para_extraction时报错
run.sh: 35: run.sh: Syntax error: word unexpected (expecting "in")
感觉语法也没问题,找来找去都没搞懂是哪里错了,有大佬知道吗?

制作datas出错

在第二步运行时报错:
Model name 'bert-base-chinese' was not found in model name list (bert-base-uncased, bert-large-uncased, bert-base-cased, bert-large-cased, bert-base-multilingual-uncased, bert-base-multilingual-cased, bert-base-chinese). We assumed 'https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-chinese-vocab.txt' was a path or url but couldn't find any file associated to this path or url.
AttributeError: 'NoneType' object has no attribute 'convert_tokens_to_ids'

测试集问题

请问大佬,我在python3 util.py中将路径改为测试集数据,报错,由于测试集中的数据格式与devset中不一样,因此报错,请问如何处理

你好,关于分数部分

请问你的分数是按照现在上传的代码得出来的吗,要按照代码里注释了按照分数排序的语句吗(paragrahs extraction文件),感觉注释了只是选取前5段会更低?期待解答,谢谢

metrics.py中compute_predictions_logits函数无法找到指定文件夹或文件

  • INFO - metrics - Writing predictions to: ./predictions_test_./du2021/384_bert/.json
    Traceback (most recent call last):
    File "main_bert.py", line 1036, in
    main()
    File "main_bert.py", line 1030, in main
    evaluate(args, model, tokenizer, prefix='test', step=global_step)
    File "main_bert.py", line 509, in evaluate
    tokenizer
    File "/nfs/users/sunyichen/data/MRC_Competition_Dureader/main/metrics.py", line 730, in compute_predictions_logits
    with open(output_prediction_file, "w", encoding='utf-8') as writer:
    FileNotFoundError: [Errno 2] No such file or directory: './du2021/384_bert/predictions_test_./du2021/384_bert/.json'1 - INFO - metrics - Writing nbest to: ./du2021/384_bert/nbest_predictions_test_./du2021/384_bert/.json

请教法律判决书法律条文的抽取问题

用以下模型对一个法律判决书做问答抽取信息:

        'luhua/chinese_pretrain_mrc_roberta_wwm_ext_large'
        'luhua/chinese_pretrain_mrc_macbert_large'

抽取被告人、徒刑等信息都正常,但是想抽取依据的法律和条文,怎么也得不到想要的效果。

比如抽取这一段里面的法律条文:

被告人陶某某自愿认罪认罚,可以从宽处理。综上,依据《中华人民共和国刑法》第二百六十六条,第六十七条第三款,第六十四条,《中华人民共和国刑事诉讼法》第十五条之规定,判决如下:

正确的结果应该是:

《中华人民共和国刑法》第二百六十六条,第六十七条第三款,第六十四条,《中华人民共和国刑事诉讼法》第十五条

实际测试结果:

Question: 判决依据是
{'score': 0.33327004313468933, 'start': 1525, 'end': 1537, 'answer': '连云港市海州区人民检察院'}
Question: 判决依据什么法律
{'score': 0.09680692106485367, 'start': 1727, 'end': 1730, 'answer': '诈骗罪'}
Question: 依据《中华人民共和国刑法》哪几条
{'score': 0.11693647503852844, 'start': 1666, 'end': 1673, 'answer': '第二百六十六条'}

请教一下,这种情况,有什么好办法。

测试代码:https://github.com/tigerzhang/bert-qa/blob/main/test-transformers-models.py#L43

请问您的结果是在epoch=4时得出的吗?

感谢您的代码,我已经跑通但是得到的结果却比较差

b'{"errorMsg": "success", "errorCode": 0, "data": [{"type": "BOTH", "name": "ROUGE-L", "value": 39.79}, {"type": "BOTH", "name": "BLEU-4", "value": 32.93}]}'

我用的BERT是最新的中文全词覆盖BERT BERT-wwm-ext, Chinese,按道理说应该比您这里的结果还要好一些才对。另外,如果想提交到官方网站的话应该提交哪份文件呢?

你好,我觉得squadexample这个类里面是不是有些问题?

我觉得squadexample这个类里面的这里有些问题吧
for c in self.context_text:

就这里转换位置的时候,因为context_text是个字符串,如果字符串里面没有空格,那么得到的char_to_word_offset里面就全都是0和1.。。这里是不是有一些问题啊?因为我看您在create example的时候并没有进行特殊处理,只是原始的字符串。我运行了一下发现会出现这种问题。谢谢!

预训练时长

您好,想要向您请教一下,预训练使用了多大数据量的数据,训练了多长时间。比赛中给出的训练集是作为下游任务进行微调,还是在预训练过程中也使用了该数据。不胜感激

CUDA : out of memory

使用roberate_wwm_large_ext会报错CUDA:out of memory, 是因为模型的参数太大导致显存放不下是嘛,用的是10G的显存,请问题主训练使用的显存大小为多大啊

dev.data 数据少

search.dev.json 和 zhidao.dev.json 各有5000条数据,但是跑完run_squad.py后的数据只有6000多条,我觉得应该有10000条,dev数据可以筛选得这么多吗?

time and storage needed

想问一下大家,你们运行这个模型的配置是多少G的内存?运行了多长时间?最后模型的效果如何?

main_bert存在不影响执行的错误

image
如上图所示,根据执行脚本的设置,图中的这个if条件是不会执行到的, 但是疑问的是:is_evaluate and SquadV1Processor 在哪里引用的,main_bert.py 这个文件没有说明

数据集很少

您好,我想问下数据集是删除了吗,我看了下zhidao.train.json里面的数据只有1060行,没有评论说的5000多行,而且dev、train、test三个数据好像数据都是一样的

dev data, most_related_paragraph

你好,请问你这边显示的dev data的metric结果,选取most_related_paragraph的方法是什么呢,根据question和paragraph之间的score?还是answer和paragraph之前的score呢,谢谢

分词问题

你好,分词部分为什么没有使用例如:
text = '你好,明天'
token = ['你', '#好', ',', '明', '#天']
这种格式去转换成 input_ids 进行训练呢?

main_bert.py 335行报错SyntaxError: invalid syntax

原版代码只改动了数据集的路径,执行sh train_bert.sh进行训练。
报错如下:

File "main_bert.py", line 335
  res_baidu = baidu_evaluate(f'{args.data_dir}/{args.predict_file}', f'{args.output_dir}/predictions_dev_{global_step}.json')
                                                                    ^
SyntaxError: invalid syntax

答案返回的是完整的context

from transformers import AutoTokenizer, AutoModelForQuestionAnswering
tokenizer = AutoTokenizer.from_pretrained("luhua/chinese_pretrain_mrc_roberta_wwm_ext_large")
model = AutoModelForQuestionAnswering.from_pretrained("luhua/chinese_pretrain_mrc_roberta_wwm_ext_large")
QA = pipeline('question-answering', model=model, tokenizer=tokenizer)
QA_input = {'question': "著名诗歌《假如生活欺骗了你》的作者是",'context': "普希金从那里学习人民的语言,吸取了许多有益的养料,这一切对普希金后来的创作产生了很大的影响。这两年里,普希金创作了不少优秀的作品,如《囚徒》、《致大海》、《致凯恩》和《假如生活欺骗了你》等几十首抒情诗,叙事诗《努林伯爵》,历史剧《鲍里斯·戈都诺夫》,以及《叶甫盖尼·奥涅金》前六章。"}
QA(QA_input)
这样返回答案是context,试了很多都是这样。
能麻烦帮忙看一下吗?谢谢!

哈工大讯飞Bert模型下载使用

你好,哈工大讯飞的Bert模型无法下载,请问可以提供下相关文件吗?
还有,哈工大的是基于词重新训练的Bert的模型吧?这个能和官方的基于字的中文Bert模型一起使用么?

确少配置文件config.json

OSError: Can't load '../init_model//roberta_wwm_ext/config.json'. Make sure that:

  • '../init_model//roberta_wwm_ext/config.json' is a correct model identifier listed on 'https://huggingface.co/models'

  • or '../init_model//roberta_wwm_ext/config.json' is the correct path to a directory containing a 'config.json' file
    11

python3环境下有问题

感谢楼主的code和分享。执行sh run.sh --para_extraction报错,这个因为官方是用的python2.7。用py3报错信息为: init() got an unexpected keyword argument 'encoding'
,把json.dumps()改成python3版本后,解决这个错误了。
但依然不能执行,这个代码if p_idx < para_id:报错:提示int不能和None做比较。

有几个实现细节想请教下

1.find_best_answer()函数里prior_scores的这几个概率有什么说法吗?为什么要加?怎么定出来的?
2.你们的code跑dev的分数,用到'most_related_para'标签,这个在跑dev的分数时,确定是可以用的吗?我是指如果dev的分数要公开
3.Q和A合并组成512时,A提前删掉了len(Q)长度的切割字符,为什么呢?

checklist/robust

checklist/robust 请问这两部分什么时候能开放出来呢,想学习一下@basketballandlearn

关于数据预处理

你好,我想问一下您自己写的预处理 和 官方提供的那个预处理数据集有区别吗。

第一步的数据预处理主要作用?

不好意思。 打扰了。 后面的bert训练知道 但是不知道你最初为什么要来一个抽取,这里主要抽取具体是想干什么? 感觉处理过的数据貌似跟原始数据没啥差别。。

请问是否能够分享一下预训练时的超参数,以及模型预训练时的一些经验?

如果方便的话,麻烦您能分享一些继续预训练的经验,包括但不限于:
1.预训练任务;
2.不同预训练模型,再次预训练时的差异;
3.超参数设置(是否需要根据训练数据量调整,怎么调整);
4.分段预训练是否有效,例如:第一次预训练使用10W数据,然后再此基础上用另外10W数据再次预训练,然后重复此过程;
5.根据您的经验,您是如何判断预训练在什么时候可以结束;
6.等等。

关于结果的得分

您好!我按照您的代码跑完,但达不到您的效果,大概只有30多左右,请问您知道是哪里的问题吗?或者我需要改哪里的参数?

predict 结果是no answer

下载chinese_pretrain_mrc_roberta_wwm_ext_large 到本地
参数为:

model_name = "roberta_wwm_ext_large" # "chinese_pretrain_mrc_macbert_large"

model_type = 'bert'
threads = 24
eval_batch_size = 64
max_seq_length = 384
max_query_length = 32
doc_stride = 128
n_best_size = 10
max_answer_length = 384
do_lower_case = True
version_2_with_negative = False
null_score_diff_threshold = 0.0
verbose_logging = False

output_prediction_file = None
output_nbest_file = None
output_null_log_odds_file = None

predict 代码如下

examples = []
example = SquadExample(
                    qas_id='f388cc7597def765543c1a6d00b19018',
                    question_text='张家港汽车站在哪里',
                    context_text="""1.张家港北站:位于南丰镇辖区内,北至内河泗兴港,南至市铁路专用线,西至沪通铁路,东至规划经四路(双丰公路西侧),面积约
2.6平方公里。 是货运站,沪通铁路沿线办理货运的中间站,设正线2条,到发线3条,有效长1050m。运输品类主要为集装箱、零担、笨重粗杂等。还设货场一处,牵出
线1条,有效长350m。货场初期占地185亩,其中围墙内装卸区100.7亩。货场内设货物线两条,具备笨重粗杂线装卸、仓库站台线装、粗杂货区装卸和仓库等功能。 >站点最新进展:目前,张家港北站范围的路基施工作业已完成,货场暂时用作铺轨基地,站区配套用房计划与张家港站同步实施。图片来源:张家港新闻 2.张家港站:>位于塘桥镇新204国道东侧,人民路北侧。 站前广场为两层结构,负二层是地铁车站,负一层是地下停车场。站前广场工程涉及地上空间广场、道路以及地下停车场>与地铁站,其中,地下停车场可容纳800辆车停放。本项目建设内容分为站前核心区(主要为广场和道路等)和铁路站场桥下区(主要为停车场和地铁区间等),总用地面
积约7.4公顷,总建筑面积约6.7万㎡。 站点最新进展:2020年7月1日,站房和站前广场将与沪通铁路同步投运。 ▽效果图""",
                    answer_text='',
                    start_position_character=None,
                    is_impossible=True,
                    answers=[],
                )
examples.append(example)
features, dataset = squad_convert_examples_to_features_orig(
            examples=examples,
            tokenizer=tokenizer,
            max_seq_length=max_seq_length,
            doc_stride=doc_stride,
            max_query_length=max_query_length,
            is_training=False,
            return_dataset="pt",
            threads=threads,
        )


eval_sampler = SequentialSampler(dataset)
eval_dataloader = DataLoader(dataset, sampler=eval_sampler, batch_size=eval_batch_size)

def to_list(tensor):
    return tensor.detach().cpu().tolist()



all_results = []
for batch in tqdm(eval_dataloader, desc="Evaluating"):
    model.eval()
    batch = tuple(t.to('cuda') for t in batch)

    with torch.no_grad():
        inputs = {
            "input_ids": batch[0],
            "attention_mask": batch[1],
            "token_type_ids": batch[2],
        }
        example_indices = batch[3]
        if model_type in ["xlm", "roberta", "distilbert", "camembert"]:
            del inputs["token_type_ids"]
        outputs = model(**inputs)
        
    for i, example_index in enumerate(example_indices):
        eval_feature = features[example_index.item()]
        unique_id = int(eval_feature.unique_id)

        output = [to_list(output[i]) for output in outputs]
        start_logits, end_logits = outputs
        result = SquadResult(unique_id, start_logits, end_logits)
        all_results.append(result)

predictions = compute_predictions_logits(
            examples,
            features,
            all_results,
            n_best_size,
            max_answer_length,
            do_lower_case,
            output_prediction_file,
            output_nbest_file,
            output_null_log_odds_file,
            verbose_logging,
            version_2_with_negative,
            null_score_diff_threshold,
            tokenizer
        )

返回结果为no answer

答案抽取部分代码逻辑请教

您好, 在这个目录下 Dureader-Bert/Dureader/predict/predicting.py, 有一段代码没看懂
find_best_answer_for_passage函数中, while True跑三个循环这里是为什么这么定义的,
每次预测出的start跟end位置相反就全部置为0重来, 似乎讲不通..
感觉跟其他模型中用动态规划的思路求最大score的区间方式不太一样.

附上代码:

def find_best_answer_for_passage(start_probs, end_probs, passage_len, question):
        best_start, best_end, max_prob = -1, -1, 0

        start_probs, end_probs  = start_probs.unsqueeze(0), end_probs.unsqueeze(0)
        prob_start, best_start = torch.max(start_probs, 1)
        prob_end, best_end = torch.max(end_probs, 1)
        num = 0
        while True:
            if num > 3:
                break
            if best_end >= best_start:
                break
            else:
                start_probs[0][best_start], end_probs[0][best_end] = 0.0, 0.0
                prob_start, best_start = torch.max(start_probs, 1)
                prob_end, best_end = torch.max(end_probs, 1)
            num += 1
        max_prob = prob_start * prob_end

        if best_start <= best_end:
            return (best_start, best_end), max_prob
        else:
            return (best_end, best_start), max_prob

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.