vumblebot / odqa_baseline_code Goto Github PK
View Code? Open in Web Editor NEWBaseline code for Korean open domain question answering(ODQA)
Home Page: https://bit.ly/3fvgZZ0
License: Apache License 2.0
Baseline code for Korean open domain question answering(ODQA)
Home Page: https://bit.ly/3fvgZZ0
License: Apache License 2.0
사용법
python -m run --strategis ST01,ST02 --run_cnt 3 --debug true
python -m run --strategis ST01,ST02 --run_cnt 3 --debug True
코드
args.debug로 접근 가능.
debug: default 값은 False로 두고 True시에 아래 처럼 parameter 수정
수정 해야 될 것들
기능 설명
==========
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
저는 위 명령어로 torch
를 재설치 하니 속도가 다시 빨라졌습니다! GPU 사용이 가능해졌어요 😄
struct.error: 'i' format requires -2147483648 <= number <= 2147483647
에러 발생합니다.README.md
의 예시 strategy로 돌렸을때 기준 OSError: [Errno 12] Cannot allocate memory
가 추가적으로 뜹니다.Python==3.6.6
혹은 Python==3.7.7
이라 해당 버그가 수정되지 않은 버전입니다.
Python==3.8
설치하면 됩니다.mecab
에러없게 설치 먼저 하시고, wandb
등 필요한 모듈 추가적으로 설치하고 conda install pytorch==1.7.1 torchvision==0.8.2 torchaudio==0.7.2 cudatoolkit=10.1 -c pytorch
로 pytorch 설치하시면 됩니다. (저희 서버 cuda 버전 10.1에 맞는 설치 명령어입니다)두번째 에러는 원인은 잘 모르겠고 ST00.json
에서 data
의 processing_num_workers
를 1로 주면 해결됩니다. 저건 GPU나 디스크 문제가 아니고 RAM 용량 문제인 것 같은데 아무튼 이러면 해결되는 것 같네요
(추가) xlm-roberta-large는 checkpoint 하나당 6.3GB의 디스크용량을 잡아먹으니 돌릴 때 디스크 용량도 주의해주세요! 제 기준 epoch 3.0에 예상시간 1시간~2시간 뜹니다. 왔다갔다거리네요
프로젝트에 덧붙이고 싶은 기능들을 제안합니다. 아래의 종류에 맞게 체크해주세요.
Data
Preprocessing
Model
Feature
Paper
Serving
ETC (ex - library, reference.
==========
기존 baseline code의 evaluation.py와 같은 역할을 하는 코드를(혹은 동일한 코드를) 저희 베이스라인에도 넣으려고 합니다.
실제 리더보드에서의 성능평가 방법과 동일 방식으로 최대한 정확한 validation score를 측정 및 저장하고자 합니다.
==========
(수행 전) retriever가 top-k개를 중복 없이 retrun하도록 refactoring
(수행 후) 결과는 어땠는지
def get_trainer(self):
trainer = QuestionAnsweringTrainer(
model=self.model,
args=self.args.train,
custom_args=self.args,
train_dataset=self.train_dataset,
eval_dataset=self.eval_dataset,
eval_examples=self.datasets["validation"], # self.datasets로 넘겨주면 안됨.
tokenizer=self.tokenizer,
data_collator=self.data_collator,
post_process_function=self._post_processing_function,
compute_metrics=self._compute_metrics,
)
self.datasets는 retrieve되기 전의 dataset이어서 top_k가 적용되지 않았습니다. ( 무조건 top-1 )
==========
==========
(수행 전) predict.py 좀 더 쉽게 사용 할 수 있도록 리팩토링 하려고 합니다.
(수행 후) 결과는 어땠는지
model_oath
대신에 전략 입력하도록
--cheat
인자 추가, 정보 유출된 정보를 사용할지 말지를 결정--ensemble
인자 추가, 전략에 해당하는 모델들의 결과를 Ensemble
프로젝트에 덧붙이고 싶은 기능들을 제안합니다. 아래의 종류에 맞게 체크해주세요.
Data
Preprocessing
Model
Feature
Paper
Serving
ETC (ex - library, reference)
==========
slack_api.py
를 포함해 혹시 추후에 api를 사용하는 환경에서 token이나 secret_key가 필요할 경우 github에 올라가지 않도록. input 디렉토리 아래에 secret.json을 따로 두어 key 및 token 값을 관리하고자 합니다.
단순히 같은 디렉토리에 숨김파일로 만들고 .gitignore로 처리해도되겠지만 의미상 input 디렉토리 아래에 두는게 좋을 것 같습니다!
괜찮으시면 기존 PR merge 이후에 제가 PR 날리겠습니다.
==========
-(수행 전) Improvements to BM25 and Language Models Examined 참조해서 추가적인 BM25 구현
(수행 전) question, document dataset 만들기
(수행 후) 학습 시간이 너무 오래 걸리고, 적당한 HyperParameter 찾기가 어려울 것 같다.
우선 학습이 굉장히 오래 걸려서 한 번 실험하기가 너무 어렵다...
(수행 전) wiki에 중복 문서 제거해서 retriever 돌려보기
(수행 후)
(수행 전) Bokeh 를 사용한 Dash Board 제작
(수행 후) 결과는 어땠는지
이 세 가지를 잘 결합하면 Retriever 분석에 큰 도움이 될 것 같습니다! 필요한 기능 있으시면 댓글 달아주세요
(수행 전) Transformer DPR Encoder를 사용해서 Dense Retriever를 구현하고 성능을 보려합니다.
(수행 후) 결과는 어땠는지
(수행 전) Token 수준의 Interaction을 하는 Dense Retriever를 구축합니다.
(수행 후) TOP-3 90%인데 이걸 굳이? 라는 느낌이 드네요..
(수행 전) 기능 부분 커밋 먼저 하였고 변수명은 차차 수정하도록 하겠습니다.
(수행 후) 결과는 어땠는지
안녕하세요, 좋은 repository 공유해주셔서 감사합니다.
retrieval 의 DPRBERT embedding을 처음부터 다시 학습하려고 하는데, 궁금한점이 있어서 문의드립니다.
README 의 내용을 참고해서, "retriever_name": "DPRBERT", "retrain": true, "dense_train_dataset": "train_dataset", 등으로 설정하고 30 epoch을 돌렸는데, loss 는 떨어지는데 retrieve된 결과가 좀 이상한것 같습니다.
DPRBERT 학습 시, BaseTrainMixin 의 _train() 함수로 학습을 시작하는데, 혹시 제가 뭔가 잘못 진행하고 있는걸까요?
가능하다면, DPRBERT 학습에 필요한 전략 파일 설정을 받을 수 있을까요?
감사합니다!
아래는 제가 사용했던 전략 파일 내용입니다.
{
"alias": "EXAMPLES DPRBERT",
"model": {
"retriever_name": "DPRBERT",
"tokenizer_name": ""
},
"data": {
"dataset_name": "squad_kor_v1",
"sub_datasets": ""
},
"train": {
"save_total_limit": 2,
"save_steps": 100,
"logging_steps": 100,
"overwrite_output_dir": true,
"do_train": true,
"do_eval": true,
"do_predict": false,
"report_to": ["wandb"]
},
"retriever": {
"retrain": true,
"dense_train_dataset": "train_dataset",
"topk": 10,
"learning_rate": 3e-5,
"per_device_train_batch_size": 4,
"per_device_eval_batch_size": 4,
"num_train_epochs": 30,
"weight_decay": 0.01
}
}
if args.train.do_eval:
eval_results = trainer.evaluate()
evaluation(args)
print(eval_results)
여기서 찍히는 eval_results 값이 저장되는 값이랑 다릅니다!
==========
if args.train.do_eval:
eval_results = trainer.evaluate()
results = evaluation(args)
## 여기서 eval_results 를 갱신한다음 Print 하는 방향으로 진행하겠습니다!
print(eval_results)
==========
non_agg
, 묶은 경우 agg
)BM25
로 실험: 동일 parameter 기준TFIDF
로 실험: parameter 영향을 제외하고 보기 위해, TFIDF로 두 조건 구동.non_agg
: topk=1
에서 43.33%, topk=2
에서 63.75%, topk=3
에서 70.83%, topk=100
에서 94.17%agg
: topk=1
에서 57.08%, topk=2
에서 70%, topk=3
에서 73.33%, topk=100
에서 95%BM25
파라미터 바꿔보기:프로젝트에 덧붙이고 싶은 기능들을 제안합니다. 아래의 종류에 맞게 체크해주세요.
Data
Preprocessing
Model
Feature
Paper
Serving
ETC (ex - library, reference.
Reader 모델 학습 시 document를 random으로 masking해서 task의 난이도를 상승시킴
일단 제가 나중에 보려고 이해한 내용을 적어보았고, 아직 안보신 분들께도 도움이 될 수도 있어 올립니다 😊
python -m run strategies ST01 --run_cnt 1
tool.get_args
로 argument 가져오기train_reader
실행
tools.update_args
실행
update_args
는 config에서 json 파일 불러와서 반영할(덮어쓸) argument를 args
에 넣어주는 역할prepare.prepare_dataset
실행
prepare.get_reader_model
실행
args.model
과 args.model_path
args.model = ModelArguments(model_name_or_path='monologg/koelectra-small-v3-discriminator', ...)
args.model_path = '/input/checkpoint/ST01_0_temp/checkpoint-500'
prepare.get_retriever
실행
retrieval.SpraseRetrieval
객체 생성(이건 이전과 동일한 코드)prepare.preprocess_dataset
prepare.retrieve_pipeline
, prepare.preprocess_dataset
retrieve_pipeline
실행
self.retrieve
실행
features: ['__index_level_0__', 'answers', 'context', 'document_id', 'id', 'question', 'title']
features: ['answers', 'context', 'id', 'question']
prepare.preprocess_dataset
data_collator
불러오기valid dataset 정제시 retrieve
에서 실제로 활용하는 column은 위에서 언급했듯이 ['answers', 'context', 'id', 'question'] 뿐인데 다른 column값들(context_id, original_context 등)을 굳이 넣어야할까요? 아니면 나중에 다른 곳에 쓰일수도 있기 때문에 다른 부분도 넣는걸까요? (사실 이건 그렇게 주요한 사안은 아닙니다. 😕 가볍게 생각해주세요)
args.train.do_train
, args.train.do_eval
을 train_reader
에서 설정해주지 말고, 사용자의 argument 입력으로부터 정보를 얻어와서update_args
에서 값 설정해주고 아래
train_results = trainer.train()
eval_results = trainer.evaluate()
이 부분과 eval_dataset
불러오는 부분도 이에 맞춰 분기 나눠주면 좋을 것 같습니다.
추후 retriever가 여러개 생겼을 때를 대비하여 run.py
에서 retriever 불러오는 부분을 수정하는게 좋을 것 같습니다.
get_sparse_embedding()
을 아예 get_retriever
내부로 넣는 방향으로요!
수정 전
#run.py
...
retriever = get_retriever(args)
retriever.get_sparse_embedding()
...
#prepare.py
...
def get_retriever(args):
if args.model.retriever_name == "tfidf":
from konlpy.tag import Mecab
mecab = Mecab()
retriever = SparseRetrieval(args, tokenize_fn=mecab.morphs)
return retriever
...
수정 후
#run.py
...
retriever = get_retriever(args)
...
#prepare.py
...
def get_retriever(args):
if args.model.retriever_name == "tfidf":
from konlpy.tag import Mecab
mecab = Mecab()
retriever = SparseRetrieval(args, tokenize_fn=mecab.morphs)
retriever.get_sparse_embedding()
elif ...
return retriever
...
현재 post_processing_function
을 train/eval dataset 전처리마다 한번씩 리턴해주고, train만 할때는 사용하지도 않는 함수라서 이 함수를 그냥 밖으로 빼려고 했는데 생각해보니까 args
변수때문에 밖으로 뺄 수가 없더라구요.
굳이 뺄 필요가 없긴 한데, 그래도 현재 코드가 완전히 깔끔한 구조라고는 볼 수 없을 것 같습니다.
이 부분에 대해서 아이디어 있으신 분은 제안 부탁드립니다!
nbest 생성된 답/context pair 바탕으로, 답이 속한 문장을 pos tagging한 뒤 답을 후처리하는 노트북 코드를 작성했습니다.
EM 혹은 F1 스코어가 상승하는 것으로 보입니다. 다만 첫 번째 뽑힌 답이 부적절해서 필터링이 되고, 후순위에 답이 있을 경우에만 유의미합니다.
노트북 파일 참조
노트북파일 받으셔서 서버에 올리시고 아래 변수 바꿔주시면 사용하실 수 있습니다.
건모님 파일 post-processing한 결과 EM이 상승하셨다고 합니다.
다만 약간 너무 인간이 필터링한...느낌이라서... 종헌님/지영님께서 하시는 작업으로 이런 이상한 답들이 다 걸러지길 기대해봅니다 ㅎㅎ
추후 Retrieval이 얼마나 많이 생길진 모르겠지만, 좀 더 명확한 구분을 위해
SparseRetrieval
-> TfIdfRetrieval
혹은 TfIdf
등으로 클래스명 변경하는 것이 좋을 것 같습니다.
수연님께서 구현해주신 BM25도 Sparse Retrieval의 일종이기도 하구요!
프로젝트가 더 커지기전에 이름 변경 미리 해두는게 좋을 것 같아요
정답(추측) : 빌헬름 미클라스
기존의 prediction : 대통령인 빌헬름 미클라스
정답(추측) : 다케다 한시, 다케다 한시(武田範之)
기존의 prediction : 다케다 한시(武田範之)
정답(추측) : 이회창, 이회창 후보
기존의 prediction : 이회창 후보
이회창
대신 이회창 후보
).{
"dataset": str,
"question": str,
"answers": list of str
"positive_ctxs": list of dictionaries of format {'title': str, 'text': str, 'score': int, 'title_score': int, 'passage_id': str}
"negative_ctxs": list of dictionaries of format {'title': str, 'text': str, 'score': int, 'title_score': int, 'passage_id': str}
"hard_negative_ctxs": list of dictionaries of format {'title': str, 'text': str, 'score': int, 'title_score': int, 'passage_id': str}
}
negative_ctxs
은 저희가 논의한 negative sample을 넣는 컬럼 같습니다!
조교님 추천에 계속 등장하는 논문의 구현체들이라, 꼭 사용해보고 싶은데 늘 데이터셋 형식을 맞추는 것에서 발목을 잡히네요.
혹시 이 오픈소스를 사용할 수 있는 방법 (haystack은 DPR 오픈소스를 쉽게 사용할 수 있도록 도와주는 오픈소스입니다) 떠오르시는 분들은 알려주시면 좋겠습니다. ㅠㅠ
(수행 전) Dense retriever training 쪽에 evaluation이 없어서 과적합 판단이 어려운 상황입니다. evaluation 코드를 추가하고자 합니다.
(수행 후) 결과는 어땠는지
보이는대로 갈아버리고 피드백을 받아보자 하고 올리는거라 이건 아닌거같다 싶으면 말씀해주세요
주요 내용
BaseReader
클래스의 __init__()
에서 dataset
초기화 관련 내용 삭제
대신 BaseReader
클래스의 set_dataset()
메소드에서 train_dataset
, eval_dataset
, 초기화
set_dataset()
에서 is_run
arg삭제, train_dataset
, eval_dataset
argument 유무로 판단
run*.py
의 경우 set_dataset()
에서 train_dataset
, eval_dataset
모두 넘겨줌predict.py
의 경우 set_dataset()
에서 eval_dataset
부분만 argument로 넘겨줌BaseReader
클래스의 preprocess_dataset()
에서 is_train
을 통해 datasets['train']
을 가져올지, datasets['validation']
을 가져올지 결정하는 부분 삭제
datasets
에 2개 key(train, validation)가 있어서 어떤걸 preprocessing할지 고르기 위해서였는데 애초 넘겨줄 때부터 datasets
대신 datasets['train']
혹은 datasets['validation']
을 넘겨주면 이런 과정 필요 없음is_train
은 prepare_*_features()
가져올 때 필요해서 꼭 필요한 수정 사항은 아님 (오히려 과한 수정일수도 있음)적용 예시
#base_reader.py
class BaseReader:
def __init__(self, args, model, tokenizer):
self.args = args
self.metric = load_metric("squad")
self.model, self.tokenizer = model, tokenizer
self.data_collator = DataCollatorWithPadding(
self.tokenizer, pad_to_multiple_of=8 if self.args.train.fp16 else None
)
self.train_dataset = None
self.eval_dataset = None
self.eval_examples = None
def set_dataset(self, train_dataset=None, eval_dataset=None):
if train_dataset:
self.train_dataset = self.preprocess_dataset(train_dataset, is_train=True)
if eval_dataset:
self.eval_dataset = self.preprocess_dataset(eval_dataset, is_train=False)
self.eval_examples = eval_dataset
def preprocess_dataset(self, dataset, is_train=True):
column_names = dataset.column_names
self.question_column_name = "question" if "question" in column_names else column_names[0]
self.context_column_name = "context" if "context" in column_names else column_names[1]
self.answer_column_name = "answers" if "answers" in column_names else column_names[2]
self.pad_on_right = self.tokenizer.padding_side == "right"
self.max_seq_length = min(self.args.data.max_seq_length, self.tokenizer.model_max_length)
prepare_func = self._prepare_train_features if is_train else self._prepare_validation_features
dataset = dataset.map(
prepare_func,
batched=True,
batch_size=self.args.data.batch_size,
num_proc=self.args.data.preprocessing_num_workers,
remove_columns=column_names,
load_from_cache_file=not self.args.data.overwrite_cache,
cache_file_name=self.args.data.cache_file_name
)
return dataset
...
def get_trainer(self):
trainer = QuestionAnsweringTrainer(
model=self.model,
args=self.args.train, # training_args
custom_args=self.args,
train_dataset=self.train_dataset,
eval_dataset=self.eval_dataset,
eval_examples=self.eval_examples,
tokenizer=self.tokenizer,
data_collator=self.data_collator,
post_process_function=self._post_processing_function,
compute_metrics=self._compute_metrics,
)
return trainer
# predict.py (예시)
def predict(args):
strategies = args.strategies
for idx, strategy in enumerate(strategies):
args = update_args(args, strategy) # auto add args.save_path, args.base_path
args.strategy = strategy
args.train.output_dir = p.join(args.path.checkpoint, strategy)
datasets = get_dataset(args, is_train=False)
retriever = get_retriever(args)
eval_dataset = retriever.retrieve(datasets["validation"], topk=args.retriever.topk)['validation']
reader = get_reader(args)
reader.set_dataset(eval_dataset=eval_dataset)
# run_*.py의 경우 reader.set_dataset(train_dataset=datasets['train'], eval_dataset=eval_dataset)
피드백은 언제나 환영입니다. ^^
다 해놓고 보니 유의미한지 저조차 의문입니다ㅋㅋ;
(수행 전) 핵심 문장(1개 or nbest concat)과 질문간의 관계 파악을 통해 정답을 추출하는 BERT 모델을 구현하고자 합니다.
(수행 후) 결과는 어땠는지
==========
pororo branch merge 이후 python-mecab-ko가 설치되어 있음에도 불구하고 python 인식하지 못하는 문제
==========
pip install pororo
pip install fairseq
pip install python-mecab-ko
를 수행해보시고, 오류가 안뜨면 그대로 사용하시고 설치 중 오류가 나서 설치가 안된다면 다음을 따라해주세요.opt/conda/bin
디렉토리 하위에 mecab-config 디렉토리가 있는지 확인해봅니다./usr/local/bin
디렉토리 하위에 mecab-config 디렉토리가 있을 겁니다.sudo ln -s /usr/local/bin/mecab-config /opt/conda/bin/mecab-config
pip install python-mecab-ko
를 수행하시면 됩니다.혹시 문제가 있을 경우 noti해주세요!
(수행 전) ETRI 데이터 셋 EDA한 다음 MRC Dataset에 분포를 맞춰서 Sampling을 할 예정입니다.
(수행 후) 결과는 어땠는지
xlm-roberta-base
로 성능 측정하였습니다.사실 아직 모델 하나 돌린거라 큰 의미는 없지만 xlm-roberta-large
가 오류로 안돌아가서 xlm-roberta-base
로 측정한 결과 먼저 공유드립니다. evaluation.py로 평가된 지표 기준입니다.
먼저 문서는 정답 문서로 고정시켜놓고 MRC 모델만 돌렸을 때의 성능입니다.
{
"EM": {
"value": "47.08%",
"rank": true,
"decs": true
},
"F1": {
"value": "67.94%",
"rank": false,
"decs": true
}
}
다음으로 MRC 모델 + Retriever 모델 모두 돌렸을 때 기준입니다.
현재 validation 및 predict에서 top-k개를 가져오지 않기 때문에 top-1로 생각하시면 될 것 같고 Retriever는 TF-IDF 사용했습니다.
{
"EM": {
"value": "21.67%",
"rank": true,
"decs": true
},
"F1": {
"value": "36.00%",
"rank": false,
"decs": true
}
}
문서만 어느정도 잘 가져온다면 EM 40% 정도는 넘을 수 있을 것 같습니다.
또한 이 모델로 prediction(LB 제출) 진행한 결과 EM 23.75%, F1 38.74% 얻었습니다.
이전에 튜닝 없이 진행했을 때 동일 백본(xlm-roberta-base)으로 EM 12.92% F1 20.26% 얻었던거 생각해보면 TF-IDF에서 max_features 없앤게 역시 주효했다고 볼 수 있을 것 같습니다.
지금 당장 이전과 다른게 TF-IDF의 max_features 없앤거밖에 생각이 안나서 이렇게 생각했는데 혹시 다른거 달라진게 있다면 댓글로 부탁드립니다!
그리고 지금 validation의 score와 LB score가 거의 비슷한 것 같은데, 지금 당장 여러 모델을 돌려보지는 못해서 확신할 수는 없지만, validation score도 의미있다고 생각할 수 있을 것 같습니다.
이건 추후에 모델 더 돌려보고 관련한 정보 더 공유드릴게요!
지금까지 나온 스코어들을 보고 드는 생각은
2번 문제의 경우 제가 읽기로한 논문 읽어보고 개선 방향 생각해보겠습니다.
LB | Eval-MRC+RT | Eval-MRC | |
---|---|---|---|
base | 23.75/38.74 | 21.67/36.00 | 47.08/67.94 |
large | 27.92/44.63 | 21.25/37.48 | 50.83/74.25 |
Hi, your project odqa_baseline_code(commit id: 45954be) requires "fuzzywuzzy==0.18.0" in its dependency. After analyzing the source code, we found that the following versions of fuzzywuzzy can also be suitable, i.e., fuzzywuzzy 0.7.0, 0.8.0, 0.8.1, 0.8.2, 0.9.0, 0.10.0, 0.11.0, 0.11.1, 0.12.0, 0.13.0, 0.14.0, 0.15.0, 0.15.1, 0.16.0, 0.17.0, since all functions that you directly (1 APIs: fuzzywuzzy.fuzz.ratio) or indirectly (propagate to 5 fuzzywuzzy's internal APIs and 3 outsider APIs) used from the package have not been changed in these versions, thus not affecting your usage.
Therefore, we believe that it is quite safe to loose your dependency on fuzzywuzzy from "fuzzywuzzy==0.18.0" to "fuzzywuzzy>=0.7.0,<=0.18.0". This will improve the applicability of odqa_baseline_code and reduce the possibility of any further dependency conflict with other projects.
May I pull a request to further loosen the dependency on fuzzywuzzy?
By the way, could you please tell us whether such an automatic tool for dependency analysis may be potentially helpful for maintaining dependencies easier during your development?
python -m run_mrc --strategies ST01 --debug True --report False --run_cnt 1
로 실행==========
if __name__ == "__main__":
# 생략
args.train.do_predict = True # <- 여기서 실행 된 이후로 update_args에서 do_predict가 False로 초기화됩니다.
for idx, strategy in enumerate(strategies):
args = update_args(args, strategy) # auto add args.save_path, args.base_path
args.strategy = strategy
args.train.output_dir = p.join(args.path.checkpoint, strategy)
args.train.do_predict = True
datasets = get_dataset(args, is_train=False)
do_predict를 main 함수의 반복문 안에서 호출하도록 변경하겠습니다!
predict.py는 코드 리팩토링이 좀 필요한 코드이기도 합니다만.. 하나의 모델만 predict 하도록 유의하면서 코드를 사용하시면 괜찮습니다!!
run
모듈은 오직 validation을 위한 모듈이라 train dataset을 사용하지 않는데, prepare.py
의 get_dataset()
을 가져올 때 train dataset의 크기까지 출력해줍니다. run
의 경우 train 폴더의 validation set을 활용해야하기 때문에, is_train=True
로 들어가서 발생하는 현상입니다.
run
에서는 train을 하지 않기 때문에 debug 및 report가 필요 없는 것 같습니다.
bm25.py
에 sparse_base.py
에 구현되어있는 get_embedding()
메소드가 똑같이 구현되어있습니다.BM25Retriever
에서 생성되는 embedding.bin
과 BM25.bin
이 BM25/
디렉토리에 들어가지 않습니다.prepare.py
에 BM25Retriever
을 불러오기 위한 코드 구현이 안되어있습니다.model_args.py
의 retriever_name의 default 값이 tfidf
인데 현재는 tfidf를 TFIDF
라는 이름으로 사용중입니다.bm25.py
의 get_embedding
메소드 구현 삭제args.path.embed = p.join(args.data_path, "embed")
이고 self.embed_path = p.join(args.path.embed, "embedding.bin")
로 들어가는 형태라서 이 부분을 self.embed_path = p.join([args.path.embed, self.name, "embedding.bin"])
뭐 이런식으로 들어가야 할 것 같습니다.prepare.py
의 RETRIEVER
에 BM25Retrieval 추가하고 BM25Retrieval 모듈 import하면 됩니다.config/model_args.py
고치면 됩니다.다른건 다 고쳤는데 4번 이슈만 아직 못 고쳤습니다! 확인해주시면 해당사항 반영하여 PR 넣겠습니다.
odqa_baseline_code/retrieval/sparse/base_retrieval.py
Lines 116 to 127 in 392dab0
122, 123 번 째 줄을 보면 여러 개의 문서를 반환해도 한 개의 문서만 사용하는 코드인 것을 확인할 수 있습니다.
수정 건의 사항
(수행 전) Kobert Tokenizer, PretrainedFastTokenizer랑 기능 맞추기
(수행 후) Kobert, Distillkobert를 사용하지 않는 방향으로 결정했습니다.
def get_retriever(args):
if args.model.retriever_name == "tfidf":
from konlpy.tag import Mecab
mecab = Mecab()
retriever = SparseRetrieval(args, tokenize_fn=mecab.morphs)
return retriever
위와 같이 함수 내 분기에 따라 module을 import 하는 방식에 대한 의견을 여쭙고 싶습니다!
모듈 상단에서만 import할 시
모듈 내 분기에 따라 import할 시
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.