Level 2의 마지막 대회인 Open-domain Question Answering 대회가 끝났다. 👏👏👏
Question Answering(질의응답)은 정답이 들어있는 지문(context)과 질문(question)이 주어지면 질문에 대한 정답(answer)을 찾는 task이다. 정답을 찾을 때 지문 내에 들어있는 문장으로만 정답을 구성하는 extractive 방식과 문단에 없는 어휘로 구성하는 generative 방식이 있다. 이번 대회는 extractive 방식이었으며, 모델이 지문을 읽고 이해해야 하므로 MRC(Machine Reading Comprehension)라고 부르기도 한다.
여기서 앞에 open-domain이 붙으면 정답을 찾을 특정 지문이 주어지지 않고, 수 많은 문서 중에 정답을 찾아야 한다. 구글과 같은 검색 엔진에서 “아이유 생일"이라고 검색하면, 아이유의 인물 정보가 들어있는 문서를 먼저 찾고(retrieve), 해당 문서에서 아이유의 생일을 찾는다(mrc).
NLP 분야를 처음 알게되었을 때 질의응답(Question Answering)이 재밌어보였던지라 시작 전부터 이번 대회에 대한 기대가 컸다!!
프로젝트 정리 링크
이번 대회에서 내 목표는 3가지였다.
1) 성능 개선에 도움이 되지 않더라도 정리해 팀원들과 공유하기 → Keep
2) 강의 내용을 최대한 이해하고 해당 내용을 대회 코드에 녹이기 → Problem
3) 어려워 보인다고 지레 겁먹지 말고 공부하고 싶은 task를 맡아서 구현 및 실험하기 → Try
성능 개선에 도움이 되지 않더라도 정리해 팀원들과 공유하기
나는 대회 초반에 huggingface에 공개된 모델을 사용해 reader 모델 실험을 진행했다. 이번 대회는 Retriever(문서 검색) + Reader(MRC) 구조로 강의를 듣고 베이스라인 코드를 이해하는데 시간이 꽤 걸려서 실험을 돌려 놓고 공부를 했다. 이번 task와 동일한 QA task인 KorQuAD로 학습된 모델과, 한국어라는 제한사항을 빼면 활용할 수 있는 모델이 많아진다고 생각해 multilingual 모델 실험을 진행했다. (이번 대회에서는 외부 데이터셋 활용은 허용이었지만, MRC 데이터셋으로 fine-tuning하는건 금지였다.)
KorQuAD로 학습된 모델은 bert-base 또는 koeletra-base로 기준이 되는 roberta-large보다는 작은 모델이라 낮은 성능을 보였다. Multilingual 모델은 실험 결과를 보고나서야 너무나 당연하다는 것을 깨달았는데, 한국어에 적용하기에는 영어로 학습된 모델 < multilingual 모델 < 한국어로 학습된 모델 순서로 성능이 높아진다. pre-training에 사용되는 언어와 동일해야 해당 언어만의 특징을 학습해 성능이 더 좋아지고, 이러한 이유 때문에 KLUE benchmark 데이터셋이 공개된 것이다!!
bert-base
< multilingual bert-base
< klue bert-base
순서로 성능이 좋다.
우리 팀은 각자 진행한 실험을 issue로 열어서 결과를 기록했는데, 기록하면서 팀원들간의 공유 뿐만 아니라 스스로도 왜 해당 방법을 시도했는지, 어떠한 방법으로 구현했는지 다시 한 번 정리하는 시간이 되었다. 또한, 진행한 대부분의 내용을 기록했기 때문에 마지막에 wrap-up report를 작성하는데도 큰 도움이 되었다.
강의 내용을 최대한 이해하고 해당 내용을 대회 코드에 녹이기
베이스라인 코드와 Elasticsearch는 sparse embedding을 사용하지만, 강의에서는 dense embedding을 다루었다. 이번 대회에서 공부할 것들이 너무 많아서 선택한 부분을 완성시킨건 잘 한 점이지만, 간단히 개념만이라도 짚고 넘어갈 필요가 있어 보인다.
내가 맡은 부분을 완료하기 위해 이번 대회에서는 선택과 집중을 했는데 dense embedding은 나에게 선택받지 못한 친구이다….
어려워 보인다고 지레 겁먹지 말고 공부하고 싶은 task를 맡아서 구현 및 실험하기
어찌 보면 치팅일수도 있지만 대회 시작하고 얼마 안 지나서 저번 부캠을 들었던 친구와 연락하다가 Elasticsearch가 retreiver의 성능을 엄청 높여준다는 정보를 얻었다. 지금까지 사용한 모델을 바꾸거나 데이터를 증강하는 방법이랑은 달라 새로워서 내가 맡는다고 선언했는데, 너무 쉽게 봐서 처음에 세팅하는 데만 며칠이 걸렸다. 팀원분들이 내가 Elasticsearch 오류 해결에만 집중할 수 있도록 도와주셔서 성공했고, 팀 내 SOTA를 갱신하면서 리더보드에 제출하는 맛을 처음으로 느꼈다.
설치, 공식 문서를 읽고 내 상황에 적용하는 부분에서 많이 막혔다. pip 명령어 한 줄로 설치할 수 있는게 아니라서 우분투에 설치하는 포스팅을 여러 개 따라했는데, 아무 생각없이 명령어를 따라한 것과 서로 다른 설치 방법을 섞어서 사용해서 원인 파악을 하는데 어려움이 있었다. 이 과정에서 서버를 2번 초기화시키고 할당받았다….ㅎㅎ
Elasticsearch 라고 포괄적으로 검색했을 때는 관련 정보를 얻을 수 없었지만, 파라미터별로 하나씩 검색했더니 해당 파라미터의 설명과 예시 등 자세한 내용을 알 수 있었다. 마지막에는 결국 처음에 봤는 공식 문서로 돌아가 “아 이 파라미터가 이런 역할을 하는구나!”라고 이해했다. 아직 새로운 방법을 시도할 때 “이건 처음 사용하는거라서 새로운데 기존과 어떤 점이 다른지 궁금하다!”라는 마음보다는 “여러번 읽어도 모르겠는데 이건 대체 뭘까?”라는 생각을 하게되는것 같다.
결과적으로는 이번 대회에서 우리 팀이 1등을 했지만, 나는 조금은 찝찝한 1등이라고 느꼈다. 다른 팀들과 비교해 특출나게 좋은 방법을 적용했다기 보다는 서로 중복되는 역할이 없고, 성능 향상에는 도움되지 않지만 구현하는데 시간이 오래 걸리는 방법들을 적용하지 않아 시간을 효율적으로 사용했기 때문이다. 대회 주제와 코드가 이해되지 않더라도 일단 빠르게 실험하고 튜닝을 진행한게 도움이 되긴 했다.
대회는 잘 마무리했지만, 아직도 Elasticsearch와 ODQA는 미지의 영역이다. 지금까지 배웠던 task 중에 가장 재밌지만 그만큼 어려웠던 대회라 아쉬움이 많이 남는다. 기회가 된다면 이 주제를 좀 더 공부하고 싶다.
마지막으로 이번 대회 중에는 부캠 후반부라 지쳐서 대회에 집중하지 못하는 팀원도 있었다. 처음에는 “내가 어떻게든 다시 힘을 낼 수 있게 cheer up 해줘야겠다!” 라고 생각했지만 내가 팀원의 상황을 잘 모르기도 하고, 이미 지쳐있는 사람한테 “힘내!!!!!!!!!!!”라고 말하는건 더 힘이 빠질 것 같아서 스스로 회복할 수 있도록 기다렸다. 팀 프로젝트에서는 혼자 앞으로 달리지 않고 팀원과 속도를 맞춰서 함께 가는게 중요하다는걸 느꼈다.