VumBleBot / odqa_baseline_code

Baseline code for Korean open domain question answering(ODQA)
https://bit.ly/3fvgZZ0
Apache License 2.0
77 stars 12 forks source link
bert electra korquad machine-reading-comprehension mrc odqa openqa pytorch question-answering

vumblebot

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

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

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

VumBleBot - BaselineCode

Tutorial

Google Colab환경에서 간편하게 VumBleBot의 베이스라인 코드를 사용할 수 있습니다.

ODQA Tutorial
Retrieval Tutorial
Reader Tutorial

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

pip install -r requirements.txt

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

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

pip install torch==1.7.1+cu101 -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

:exclamation: predict를 수행하려면 input/data/wikipedia_documents.jsoninput/data/test_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
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

image

Usage: Validation

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

./scripts/run.sh
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
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

Contributors

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

Reference

Papers

Dataset

License

VumBleBot/odqa_baseline_codeApache License 2.0을 따릅니다.