Baseline code for Korean open domain question answering(ODQA)

Overview

vumblebot-logo

Open-Domain Question Answering(ODQA)는 다양한 주제에 대한 문서 집합으로부터 자연어 질의에 대한 답변을 찾아오는 task입니다. 이때 사용자 질의에 답변하기 위해 주어지는 지문이 따로 존재하지 않습니다. 따라서 사전에 구축되어있는 Knowledge Resource(본 글에서는 한국어 Wikipedia)에서 질문에 대답할 수 있는 문서를 찾는 과정이 필요합니다.

VumBleBot은 ODQA 문제를 해결하기 위해 설계되었습니다. 질문에 관련된 문서를 찾아주는 Retriever, 관련된 문서를 읽고 간결한 답변을 내보내주는 Reader가 구현되어 있습니다. 이 두 단계를 거쳐 만들어진 VumBleBot은 어떤 어려운 질문을 던져도 척척 답변을 해주는 질의응답 시스템입니다.

📑 Wrap-up report에 모델, 실험 관리 및 검증 전략, 앙상블, 코드 추상화 등 저희가 다룬 기술의 흐름과 고민의 흔적들이 담겨있습니다.

VumBleBot - BaselineCode

DEMO

아래 문서에서 사용할 수 있는 reader/retriever 모델을 확인하실 수 있습니다.

Reader

python -m run_mrc --strategies RED_DPR_BERT --run_cnt 1 --debug False --report True

image

Retrieval

python -m run_retrieval --strategies RET_05_BM25_DPRBERT,RET_06_TFIDF_DPRBERT,RET_07_ATIREBM25_DPRBERT --run_cnt 1 --debug False --report False

retriever-top-k-compare

Installation

Dependencies

  • fuzzywuzzy==0.18.0
  • konlpy==0.5.2
  • numpy==1.19.4
  • pandas==1.1.4
  • pororo==0.4.2
  • scikit-learn==0.24.1
  • sentencepiece==0.1.95
  • slack-sdk==3.5.1
  • torch==1.7.1
  • tqdm==4.41.1
  • transformers==4.5.1
  • wandb==0.10.27
pip install -r requirements.txt

이 프로젝트는 mecab을 사용합니다.
KoNLPy 공식 홈페이지를 참고하여 KoNLPy 및 MeCab 설치를 진행해주세요.

현재 CUDA 버전이 낮을 경우 pororo 설치 시 GPU가 활성화되지 않는 이슈가 존재합니다.
만약 pororo 설치 이후 학습속도가 지나치게 느려졌을 경우, 아래 명령으로 torch 버전업을 통해 GPU를 활성화해주세요. 이슈 참고

pip install torch==1.7.1+cu101 torchvision==0.8.2+cu101 torchaudio==0.7.2 -f https://download.pytorch.org/whl/torch_stable.html

File Structure

Baseline code

odqa_baseline_code/
│
├── config/ - arguments config file
│   ├── README.md
│   ├── model_args.py
│   ├── data_args.py
│   ├── retriever_args.py
│   └── train_args.py
│
├── reader/ - reader 
│   ├── base_reader.py
│   ├── custom_head.py
│   ├── custom_reader.py
│   └── pororo_reader.py
│
├── retrieval/ - retriever
│   ├── base_retrieval.py
│   ├── dense
│   │   ├── dense_base.py
│   │   ├── dpr.py
│   │   ├── dpr_base.py
│   │   └── colbert.py
│   ├── hybrid
│   │   ├── hybrid_base.py
│   │   └── hybrid.py
│   └── sparse
│       ├── sparse_base.py
│       ├── tfidf.py
│       ├── bm25_base.py
│       ├── atire_bm25.py
│       └── ...
│
├── make_dataset/ - make necessary datasets
│   ├── aggregate_wiki.py
│   ├── kor_sample_dataset.py
│   ├── negative_ctxs_dataset.py
│   ├── qd_pair_bm25.py
│   ├── triplet_dataset.py
│   └── ...
│ 
├── utils/ - utils
│   ├── evaluation.py - for evaluation normalize
│   ├── prepare.py - get datasets/retriever/reader
│   ├── slack_api.py - for slack api loading, report to slack channel
│   ├── tokenization_kobert.py - for kobert tokenizer
│   ├── tools.py - update arguments, tester excuter
│   ├── tester.py - debugging, testing
│   ├── trainer_qa.py - trainer(custom evaluate, predict)
│   └── utils_qa.py - post processing function
│
├── examples/ - strategy files
│   ├── ST01.json
│   └── ...
│
├── scripts/ - executable script files
│   ├── run_mrc.sh - execute run_mrc module
│   ├── run_retrieval.sh - execute run_retrieval module
│   ├── run.sh - execute run module
│   └── predict.sh - execute predict module
│
├── ensemble.py - do ensemble
├── run_mrc.py - train/evaluate MRC model
├── run_retrieval.py - train/evaluate retriever model
├── run.py - evaluate both models
└── predict.py - inference

Input

input/
│
├── checkpoint/ - checkpoints&predictions (strategy_alias_seed)
│   ├── ST01_base_00
│   │   ├── checkpoint-500
│   │   └── ...
│   ├── ST01_base_95
│   └── ...
│ 
├── data/ - competition data
│   ├── wikipedia_documents.json
│   └── custom datasets(train_data/test_data) ...
│
├── embed/ - embedding caches of wikidocs.json
│   ├── TFIDF
│   │   ├── TFIDF.bin
│   │   └── embedding.bin
│   ├── BM25
│   │   ├── BM25.bin
│   │   └── embedding.bin
│   ├── ATIREBM25
│   │   ├── ATIREBM25_idf.bin
│   │   ├── ATIREBM25.bin
│   │   ├── embedding.bin
│   │   └── idf.bin
│   ├── DPRBERT
│   │   ├── DPRBERT.pth
│   │   └── embedding.bin
│   └── ATIREBM25_DPRBERT
│       └── classifier.bin
│
└── (optional) keys/ - secret keys or tokens
    └── (optional) secrets.json

Json File Example

전략 config 파일(ST00.json) 예시입니다.
arguments(hyperparameter)는 아래 파일들을 참고하여 수정하시면 됩니다.

예시 전략 파일들이 examples/에 존재하니, 참고하셔서 전략 파일을 작성하시면 됩니다.

{
    "alias": "vumblebot",
    "model": {
        "model_name_or_path": "monologg/koelectra-small-v3-discriminator",
        "retriever_name": "BM25_DPRKOBERT",
        "reader_name": "CNN",
        "config_name": "",
        "tokenizer_name": ""
    },
    "data": {
        "dataset_name": "squad_kor_v1",
        "sub_datasets": "",
        "sub_datasets_ratio": "", 
        "overwrite_cache": false,
        "preprocessing_num_workers": 2,
        "max_seq_length": 384,
        "pad_to_max_length": false,
        "doc_stride": 128,
        "max_answer_length": 30
    },
    "train": {
        "masking_ratio": 0.0,
        "do_train": true,
        "do_eval": true,
        "do_eval_during_training": true,
        "eval_step": 500,
        "pororo_prediction": false,
        "save_total_limit": 5,
        "save_steps": 100,
        "logging_steps": 100,
        "overwrite_output_dir": true,
        "freeze_backbone": false,
        "report_to": ["wandb"]
    },
    "retriever": {
        "b": 0.01,
        "k1": 0.1,
        "topk": 5,
        "alpha": 0.1,
        "retrain": false,
        "weight_decay": 0.01,
        "learning_rate": 3e-5,
        "num_train_epochs": 2,
        "per_device_eval_batch_size": 2,
        "gradient_accumulation_steps": 1,
        "per_device_train_batch_size": 4,
        "dense_train_dataset": "squad_kor_v1"
    }
}

Dataset setting

본 프로젝트는 transformers 라이브러리를 통해 KorQuAD 1.0을 불러와 학습 및 검증을 수행합니다.
만약 custom dataset을 통해 학습을 수행하려면 아래와 같이 input/data 경로에 커스텀 데이터셋을 넣어주어야 합니다.

input/
│
└── data
    ├── train_dataset
    │   ├── dataset_dict.json
    │   ├── train
    │   │   ├── dataset.arrow
    │   │   ├── dataset_info.json
    │   │   ├── indices.arrow
    │   │   └── state.json
    │   └── validation
    │       ├── dataset.arrow
    │       ├── dataset_info.json
    │       ├── indices.arrow
    │       └── state.json
    ├── test_dataset
    │   ├── dataset_dict.json
    │   └── validation
    │       ├── dataset.arrow
    │       ├── dataset_info.json
    │       ├── indices.arrow
    │       └── state.json
    └── wikipedia_documents.json

predict를 수행하려면 input/data/wikipedia_documents.jsoninput/data/test_dataset이 필수적으로 존재해야합니다.

  • wikipedia_documents.json은 용량이 큰 관계로 프로젝트에서 직접적으로 제공하지 않습니다. 한국어 위키피디아 홈페이지에서 위키피디아 데이터를 다운받아 examples/wikipedia_documents.json과 같은 형식으로 가공하여 활용하시면 됩니다.

  • test_dataset은 커스텀 데이터셋으로 huggingface 공식 문서를 참고하여 아래와 같은 형식으로 만들어 활용해주세요.

    • Dataset 예시

      DatasetDict({
        validation: Dataset({
            features: ['id', 'question'],
            num_rows: 100
        })
      })
      
    • Data 예시

      {
        'id': '질문 ID(str)',
        'question': '질문(str)'
      }
      
  • train_dataset은 KorQuAD로 모델 학습을 진행하실 경우 별도로 필요하지 않습니다. 커스텀 데이터셋으로 학습을 하려면 아래와 같은 형식으로 데이터셋을 만들어주세요.

    • Dataset 예시

      DatasetDict({
          train: Dataset({
              features: ['answers', 'context', 'document_id', 'id', 'question', 'title'],
              num_rows: 3000
          })
          validation: Dataset({
              features: ['answers', 'context', 'document_id', 'id', 'question', 'title'],
              num_rows: 500
          })
      })
      
    • Data 예시

      {
        'title': '제목(str)',
        'context': '내용(str)',
        'question': '질문(str)',
        'id': '질문 ID(str)',
        'answers': {'answer_start': [시작위치(int)], 'text': ['답(str)']},
        'document_id': 문서 ID(int)
      }
      
  • 커스텀 데이터셋을 활용하여 reader 모델 학습을 하려면 utils/prepare.py를 참고하여 아래와 같이 전략 config를 수정해주세요.

        ...
        "data": {
            "dataset_name": "train_dataset",
            "sub_datasets": "kor_dataset",
            "sub_datasets_ratio": "0.3", 
        ...
    
    • 커스텀 데이터셋을 활용하실 경우, KorQuAD 데이터셋을 위와 같이 sub_datasets로 주어 학습에 함께 활용할 수 있습니다. 이 때 sub_datasets_ratio를 이용하여 추가적인 데이터셋을 얼마나 활용할지 설정할 수 있습니다.
    • sub_datasets를 활용하시려면 아래 파트를 참고하여 추가적인 데이터셋을 생성해주세요.
  • 커스텀 데이터셋을 활용하여 dense retriever 모델 학습을 하려면 아래와 같이 전략 config를 수정해주세요.

      ...
      "retriever": {
          ...
          "dense_train_dataset": "train_dataset"
      }
      ...
    

Usage

Usage: Directory setting

Server의 디렉토리 구조에서 baseline code가 input과 같은 수준에 위치하면 됩니다.

root/  
├── input/
└── odqa_baseline_code/  

input 디렉토리에, 아래와 같이 input/checkpoint, input/data, input/embed 디렉토리를 생성해주세요.

input/
├── checkpoint/ - checkpoints&predictions (strategy_alias_seed)
├── data/ - competition data
├── embed/ - embedding caches of wikidocs.json
└── (optional) keys/ - secret keys or tokens

Slack 알람 봇을 활용하시려면 input/keyssecrets.json을 넣어주시고, --report argument를 True로 설정해주세요.
secrets.json은 아래와 같은 형식으로 작성해주세요.

{
    "SLACK": {
        "CHANNEL_ID": "[Slack 채널 ID]",
        "TOKEN": "[Slack 채널 토큰]",
        "USER_NAME": "[닉네임]",
        "COLOR": "[hex color]" i.e., "#FFFFFF", 
        "EMOJI": "[Emoji code]" i.e., ":dog:"
    }
}

Slack 알람 봇을 사용하지 않으실 경우 해당 디렉토리 및 파일은 만들지 않으셔도 됩니다.

Usage: Train

Reader

아래 스크립트를 실행하여 Reader 모델의 학습 및 평가를 진행합니다.

./scripts/run_mrc.sh
  • 전략 config의 Retriever 모델은 사용하지 않습니다. MRC 모델 학습시에는 정답 문서를 reader 모델에 바로 제공합니다.
  • 실행하면 아래와 같이 checkpoint와 validation set에 대한 결과파일이 생성됩니다.
  • config 파일에서 train.pororo_prediction argument를 True로 주면 pororo 라이브러리로 예측값이 보완된 pororo_predictions_test.json이 함께 생성됩니다.
input/  
└── checkpoint/  
    ├── ST02_temp_95/
    │   ├── checkpoint-500/
    │   └── ...
    ├── nbest_predictions_valid.json
    ├── predictions_valid.json
    ├── (optional) pororo_predictions_test.json
    └── valid_results.json

Retriever

아래 스크립트를 실행하여 Retriever 모델의 학습 및 평가를 진행합니다.

./scripts/run_retrieval.sh
  • 전략 config의 Reader 모델은 사용하지 않습니다. 문서 검색을 위한 retriever 모델만을 학습 및 평가합니다.

  • 전략 config에서 retriever.retrain argument를 True로 주면 retriever의 embedding을 재학습시킬 수 있습니다.

  • 실행하면 아래와 같이 wandb.ai에서 결과값을 확인 할 수 있습니다.

    전략: RET_07_ATIREBM25_DPRBERT: ATIREBM25_DPRBERT
    TOPK: 1 ACC: 75.00
    TOPK: 2 ACC: 85.83
    TOPK: 3 ACC: 90.42
    TOPK: 4 ACC: 90.83
    TOPK: 5 ACC: 91.67
    TOPK: 6 ACC: 93.33
    TOPK: 7 ACC: 95.00
    TOPK: 8 ACC: 95.42
    TOPK: 9 ACC: 95.83
    TOPK: 10 ACC: 96.25
    

image

Usage: Validation

아래 스크립트를 실행하여 종합적인 ODQA 프로세스의 성능 평가를 진행합니다.

./scripts/run.sh
  • Reader와 Retriever를 동시에 활용하여 ODQA 성능을 종합적으로 검증합니다.

  • 기학습된 파일들을 불러오기 때문에, train은 진행하지 않고 validation score만 측정합니다.

  • 검증 단계이므로 strategies로써 한 개의 전략만 집어넣는 것을 추천합니다.

  • 아래와 같이 전략명에 대한 디렉토리와 파일이 생성됩니다.

  • config 파일에서 train.pororo_prediction argument를 True로 주면 pororo 라이브러리로 예측값이 보완된 pororo_predictions_test.json이 함께 생성됩니다.

input/  
└── checkpoint/  
    ├── ST02_temp_95/
    │   ├── checkpoint-500/
    │   └── ...
    ├── nbest_predictions_valid.json
    ├── predictions_valid.json
    ├── (optional) pororo_predictions_test.json
    └── valid_results.json

Usage: Predict

아래 스크립트를 실행하여 학습된 모델을 불러와 예측(predict)을 진행합니다.

./scripts/predict.sh
  • Reader와 Retriever를 동시에 활용하여 prediction을 진행합니다.

  • 예측에 활용할 전략 한개만 활용할 것을 추천합니다.

  • 예측을 위해서는 예측 대상인 질문 dataset과 retrieval의 대상인 wikipedia document dataset이 필요합니다. 자세한 내용은 데이터셋 설정을 참조해주세요.

  • 예측 결과로 아래와 같이 전략명에 대한 디렉토리와 파일이 생성됩니다.

  • config 파일에서 train.pororo_prediction argument를 True로 주면 pororo 라이브러리로 예측값이 보완된 pororo_predictions_test.json이 함께 생성됩니다.

input/  
└── checkpoint/  
    └── ST01/
        ├── nbest_predictions_test.json
        ├── predictions_test.json
        ├── valid_results.json
        └── (optional) pororo_predictions_test.json

Usage: Make additional dataset

부가적인 데이터셋을 생성합니다.
일부 데이터셋은 생성 이전에 앞서 언급한 커스텀 데이터셋을 필요로 합니다.

python -m make_dataset.qd_pair_bm25
python -m make_dataset.cheat_dataset
python -m make_dataset.aggregate_wiki
python -m make_dataset.triplet_dataset
python -m make_dataset.kor_sample_dataset
python -m make_dataset.negative_ctxs_dataset

Test Driven Development

  • tester.py: 구현된 기능이 정상 작동되는지 테스트합니다.

  • 검증할 전략을 옵션으로 입력

    python -m utils.tester --strategies ST02,ST01
    python -m run --strategies ST01

  • (example) 결과 해석

    • 5가지 단위 테스트 중 1 fail, 1 error 발생
    
    ===================================================
    ERROR: test_strategies_with_dataset (__main__.TestReader)
    (Constraint)
    ---------------------------------------------------
    .... 
    
    ===================================================
    FAIL: test_valid_dataset (__main__.TestReader)
    ---------------------------------------------------
    ....
    
    Traceback (most recent call last):
    File "/opt/ml/odqa_baseline_code/tester.py", line 42, in test_valid_dataset
        assert False, "존재하지 않는 dataset입니다. "
    AssertionError: 존재하지 않는 dataset입니다. 
    
    ---------------------------------------------------
    Ran 5 tests in 11.046s
    
    FAILED (failures=1, errors=1)
    
    • 5가지 단위 테스트 모두 통과
    ----------------------------
    Ran 5 tests in 76.858s
    
    OK
    

Contributors

구건모(ggm1207) | 김성익(SeongIkKim) | 김종헌(olenmg) | 신지영(ebbunnim) | 이수연(sooyounlee)

Reference

Papers

Dataset

License

VumBleBot/odqa_baseline_codeApache License 2.0을 따릅니다.

Owner
VUMBLEB
upstage_3s_3b
VUMBLEB
Findings of ACL 2021

Assessing Dialogue Systems with Distribution Distances [arXiv][code] We propose to measure the performance of a dialogue system by computing the distr

Yahui Liu 16 Feb 24, 2022
Search msDS-AllowedToActOnBehalfOfOtherIdentity

前言 现在进行RBCD的攻击手段主要是搜索mS-DS-CreatorSID,如果机器的创建者是我们可控的话,那就可以修改对应机器的msDS-AllowedToActOnBehalfOfOtherIdentity,利用工具SharpAllowedToAct-Modify 那我们索性也试试搜索所有计算机

Jumbo 26 Dec 05, 2022
Tool to add main subject to items on Wikidata using a WMFs CirrusSearch for named entity recognition or a manually supplied list of QIDs

ItemSubjector Tool made to add main subject statements to items based on the title using a home-brewed CirrusSearch-based Named Entity Recognition alg

Dennis Priskorn 9 Nov 17, 2022
天池中药说明书实体识别挑战冠军方案;中文命名实体识别;NER; BERT-CRF & BERT-SPAN & BERT-MRC;Pytorch

天池中药说明书实体识别挑战冠军方案;中文命名实体识别;NER; BERT-CRF & BERT-SPAN & BERT-MRC;Pytorch

zxx飞翔的鱼 751 Dec 30, 2022
CDLA: A Chinese document layout analysis (CDLA) dataset

CDLA: A Chinese document layout analysis (CDLA) dataset 介绍 CDLA是一个中文文档版面分析数据集,面向中文文献类(论文)场景。包含以下10个label: 正文 标题 图片 图片标题 表格 表格标题 页眉 页脚 注释 公式 Text Title

buptlihang 84 Dec 28, 2022
Officile code repository for "A Game-Theoretic Perspective on Risk-Sensitive Reinforcement Learning"

CvarAdversarialRL Official code repository for "A Game-Theoretic Perspective on Risk-Sensitive Reinforcement Learning". Initial setup Create a virtual

Mathieu Godbout 1 Nov 19, 2021
Signature remover is a NLP based solution which removes email signatures from the rest of the text.

Signature Remover Signature remover is a NLP based solution which removes email signatures from the rest of the text. It helps to enchance data conten

Forges Alterway 8 Jan 06, 2023
✔👉A Centralized WebApp to Ensure Road Safety by checking on with the activities of the driver and activating label generator using NLP.

AI-For-Road-Safety Challenge hosted by Omdena Hyderabad Chapter Original Repo Link : https://github.com/OmdenaAI/omdena-india-roadsafety Final Present

Prathima Kadari 7 Nov 29, 2022
Sentence boundary disambiguation tool for Japanese texts (日本語文境界判定器)

Bunkai Bunkai is a sentence boundary (SB) disambiguation tool for Japanese texts. Quick Start $ pip install bunkai $ echo -e '宿を予約しました♪!まだ2ヶ月も先だけど。早すぎ

Megagon Labs 160 Dec 23, 2022
Yodatranslator is a simple translator English to Yoda-language

yodatranslator Overview yodatranslator is a simple translator English to Yoda-language. Project is created for educational purposes. It is intended to

1 Nov 11, 2021
Negative sampling for solving the unlabeled entity problem in NER. ICLR-2021 paper: Empirical Analysis of Unlabeled Entity Problem in Named Entity Recognition.

Negative Sampling for NER Unlabeled entity problem is prevalent in many NER scenarios (e.g., weakly supervised NER). Our paper in ICLR-2021 proposes u

Yangming Li 128 Dec 29, 2022
Constituency Tree Labeling Tool

Constituency Tree Labeling Tool The purpose of this package is to solve the constituency tree labeling problem. Look from the dataset labeled by NLTK,

张宇 6 Dec 20, 2022
PyTorch impelementations of BERT-based Spelling Error Correction Models.

PyTorch impelementations of BERT-based Spelling Error Correction Models

Heng Cai 209 Dec 30, 2022
基于Transformer的单模型、多尺度的VAE模型

UniVAE 基于Transformer的单模型、多尺度的VAE模型 介绍 https://kexue.fm/archives/8475 依赖 需要大于0.10.6版本的bert4keras(当前还没有推到pypi上,可以直接从GitHub上clone最新版)。 引用 @misc{univae,

苏剑林(Jianlin Su) 49 Aug 24, 2022
An easier way to build neural search on the cloud

An easier way to build neural search on the cloud Jina is a deep learning-powered search framework for building cross-/multi-modal search systems (e.g

Jina AI 17.1k Jan 09, 2023
🐍💯pySBD (Python Sentence Boundary Disambiguation) is a rule-based sentence boundary detection that works out-of-the-box.

pySBD: Python Sentence Boundary Disambiguation (SBD) pySBD - python Sentence Boundary Disambiguation (SBD) - is a rule-based sentence boundary detecti

Nipun Sadvilkar 549 Jan 06, 2023
Implementation of Natural Language Code Search in the project CodeBERT: A Pre-Trained Model for Programming and Natural Languages.

CodeBERT-Implementation In this repo we have replicated the paper CodeBERT: A Pre-Trained Model for Programming and Natural Languages. We are interest

Tanuj Sur 4 Jul 01, 2022
NLP made easy

GluonNLP: Your Choice of Deep Learning for NLP GluonNLP is a toolkit that helps you solve NLP problems. It provides easy-to-use tools that helps you l

Distributed (Deep) Machine Learning Community 2.5k Jan 04, 2023
Baseline code for Korean open domain question answering(ODQA)

Open-Domain Question Answering(ODQA)는 다양한 주제에 대한 문서 집합으로부터 자연어 질의에 대한 답변을 찾아오는 task입니다. 이때 사용자 질의에 답변하기 위해 주어지는 지문이 따로 존재하지 않습니다. 따라서 사전에 구축되어있는 Knowl

VUMBLEB 69 Nov 04, 2022