IR 경진대회 회고

2024. 12. 21. 12:34Upstage AI Lab

프로젝트 진행 기간 (12월 16일 - 12월 19일)

프로젝트 주제

주제 : 과학 질문과 이전 대화 히스토리를 보고 참고할 문서를 검색엔진에서 추출 후 이를 활용하여 질문에 적합한 대답을 생성하는 태스크(RAG)

목표 : MAP, MRR 점수 최적화

대화 메시지가 과학 상식에 대한 질문일 수도 있고 아닐수도 있기 때문에 과학 상식 질문이 아닌 경우는 문서를 추출할 필요가 없음.

검색이 필요없는 ground truth 항목에 대해서는 검색 결과가 없는 경우를 1점으로 주고 그렇지 않는 경우는 0점으로 계산하게 로직이 추가 됨.

 

학습과 평가시 사용한 데이터

  • documents.jsonl : 과학 상식 정보를 담고 있는 순수 색인 대상 문서 4200여개
    (Open Ko LLM Leaderboard에 들어가는 Ko-H4 데이터 중 MMLU, ARC 데이터를 기반으로 생성)
  • eval.jsonl : 220개의 메시지이며 이중 20개는 멀티턴 대화를 포함

팀 개발 문화

이번엔 팀장으로 프로젝트를 진행했다.

이번 IR대회랑 RecSys대회는 팀을 짜주는게 아니라 팀을 직접짜는건데

늦게 움직이면 열심히 하는 분들과 함께하지 못할 가능성이 높아서 먼저 빠르게 움직였다.

 

대회가 아닌 주간에는 주당 두 번 모여서 약 1시간 동안 각자가 공부한 내용들 이야기 하고

대회 기간에는 매일 모여서 한 시간 동안 이야기하고 실험 전략 공유하고 하루동안 실험하고 실험 결과에 대해 이야기했다.

 

짧은 시간에 생각보다 많은 시도를 할 수 있었다.

진행 과정

평가 방식 파악

평가가 어떤 식으로 이루어지는지 먼저 파악해야 했다.

최종 제출 파일 일부

baseline code를 실행하면 이렇게 나온다. 평가가 standalone_query로 이루어지는지, topk로 이루어지는지, Answer로 이루어지는지 score로 이루어지는지 파악해야 했다.

 

baseline code돌려서 몇번 제출해보니까 topK 기준으로 평가가 이루어진다는 것을 알았다. 즉, 사용자의 대화가 들어오면 LLM이 과학 대화라고 판단한 경우 search api를 통해 standalone_query를 만들고 그걸 기준으로 정보가 모여 있는 document.jsonl파일에서 retrieve를 진행한 다음 유사한 문서를 끌어오는거다.

 

그리고 그걸 기반으로 답변을 생성하는거다.

 

처음에는 이걸 잘 몰라서 topK들을 불러오면 불러온 문서들을 다시 배치하는 reranking부터 생각했다.

하지만 삽질

 

다행히 이걸 빠르게 알아서 reranking보다는 최대한 LLM이 search api를 호출하도록 하기 위해서 prompt를 수정했다.

팀원 중 한 분이 그걸 잘 해주셔서 그걸 기반으로 나만의 prompt를 만들었다.

 

이전보다는 topK를 잘 불러왔다. 하지만 문제가 있었다. 모델에 따라 불러오는 topK의 개수가 차이가 많이 났다.

CV 설정

어떤 대회든 대회에서 가장 중요한 것 중 하나가 Cross Validation dataset을 설정하는 것이다.

이전 대회들에서는 그걸 잘 몰랐다가 최근에 캐글 행사를 다녀와서

그마분의 조언도 생각났고 우리팀에서 잘 하시는 분 중 한 분이 처음부터 CV설정에 대한 말씀을 주셔서 CV설정에 대한논의를 했다.

 

우리팀은 CV설정을 팀 SOTA모델 기준 결과 파일의 유사도가 60-70%정도 되면 제출하기로 했다.

모델 선정

4o-mini(왼) / 4-turbo(오)
3.5-turbo

처음 주어진 모델이 4o-mini였는데 심각하게 topK를 못 불러와서 변인 통제하고 모델 실험만 했는데 비용적인 면과 topK를 불러오는 것을 보았을 때 3.5-turbo 성능이 가장 좋았다.

 

4o-mini는 topK를 못 불러오고 4-turbo는 잘 불러오고 답변도 적절히 잘 하는데 문제는 속도가 느리고 비용도 많이 든다.

3.5-turbo는 4o-mini보다는 느리지만 거의 비슷한 속도고 가격은 나름대로 합리적이었다.

 

4-turbo는 이때 실험하고 돌리고 이후로는 한 번도 돌리지 않음.

(뉴욕 개발자 털보씨 너무 비싸)

이후 실험들

내가 이런 실험을 하고 있을 동안에 다른 분은 임베딩 모델을 바꾸는 실험을 하셨다.

baseline code로 주어진 snunlp/KR-SBERT-V40K-klueNLI-augSTS모델 말고 dragonkue/bge-m3-ko를 이용하고 검증된 prompt로만 실험을 했는데 팀 SOTA점수가 0.7점대에서 0.8점대 초반으로 점수가 빠르게 점프했다.

 

이걸 하면서 느낀거는 역시 영어가 중요하다... 허깅페이스 등 여러 AI관련 오픈소스는 대부분 영어로 되어 있어서...

그리고 이미 다른 사람들이 해놓은 것들을 search하는 실력도 중요하다는 것을 배웠다.

 

사용한 모델 주소를 걸어 놓는다.


https://huggingface.co/dragonkue/BGE-m3-ko

 

dragonkue/BGE-m3-ko · Hugging Face

SentenceTransformer This is a sentence-transformers model trained on the train_set dataset. It maps sentences & paragraphs to a 1024-dimensional dense vector space and can be used for semantic textual similarity, semantic search, paraphrase mining, text cl

huggingface.co

 

이후에는 여기에서 좀 막혔다.

뭘 어떻게 해야할지, 그리고 강의에서 추천받은 여러 실험 방법론들을 실험해봤지만 잘 되지 않았다.

 

이쯔음에서 멘토링을 받았다.

추천 받은 방법은 

  1. Query Routing
  2. Chunking
  3. 단일 sparse/dense retrieval 방법을 개선한 hybrid retrieval 방법
  4. reranking
  5. filtering

추천 받았는데 팀에서 시간 이슈로 5번 빼고 다 시도해봤다.

나는 Query Routing을 했다. logical routing과 semantic routing으로 나뉘었는데 데이터 셋 자체가 너무 의미적으로 함유하고 있는게 잘 구분되지 않기도 하고 시간이 부족해서 logical은 포기하고 바로 semantic으로 시도했다.

 

근데 문제는 4200개가 되는 데이터 셋을 어떻게 의미가 비슷한 것끼리 묶느냐는 거였다. 3가지 시도를 했는데 첫번째는 이미 라벨링이 되어 있는 데이터 셋의 범주 안에 그러지 않은 데이터 셋을 LLM을 통해 분류하도록 했고 나머지 두 방법은 데이터셋 전체를 임베딩 공간에 표현을 하고 유사도를 기준으로 클러스터링을 진행해서 묶인 군집끼리 새로운 데이터 셋을 형성하도록 했다.

 

첫번째 방법은 LLM이 잘못한것도 있어서 내가 다시 라벨링 했었는데 약 500개 정도는 하다가 시간도 부족하고 지쳐서 안했다.

두 번째 방법은 dragonkue/bge-m3-ko이걸 이용해서 했고 세 번째 방법은 OpenAI임베딩 모델 이용해서 했다.

 

근데 첫번째와 두번째 방법의 성능이 비슷했다.

이걸 보면서 느낀거는 휴먼라벨링 실패하지 않았구나... 세번째거는 성능 태스트을 잘 해보지는 못했다. 그러나 하나 확실한 거는 우리팀 SOTA모델보다 뛰어나지 않다는 걸 알았고, 제출기회가 한 번 밖에 남지를 않아서 정확히 측정하는 것을 포기했다.

 

이렇게 실험하고 느낀거는 semantic routing으로만 검색을 하면 안된다는 거다.

실험을 아직 해보진 않았지만 예상해보기로는 semantic routing을 진행한다면 이 방법과 reranking을 결합해야 한다. 그리고 dataset을 나누었으면 search를 할 때 같은 그룹에서 정보를 가져오기보다는 다른 그룹에서 정보를 가져오도록 해야 한다.(한 그룹안에 데이터 개수가 적다면. 많다면 한 그룹안에서 많이 가져오도록 해도 괜찮겠지만...)

 

암튼 나의 시도는 팀의 점수를 높이진 못했다.

 

그래도 다른 분들의 실험이 성공해서 좋은 결과를 얻을 수 있었다.

우리팀에서 최종적으로 가장 점수가 좋았던 시도는 reranking과 hybrid search를 결합한 방식이 성능이 가장 좋았다.

reranking과 hybrid search를 할 때도 좋은 모델과 적절한 비율을 찾는데 많은 실험들이 들어갔다.

 

결과

Public(왼) Private(오)

 
 

Public 기준 2등, Private 기준 1등

좋은 결과였다.

다른 팀들의 좋은 시도들

이번 대회에는 트릭이 숨어있었다.

사실 과학 질문이라고 했지만 실제는 그렇지 않았고 상식 질문이 들어오면 관련된 문서는 다 retrieval해야 했다.

(일상 대화가 들어오면 topK를 찾으면 안되는 구조. 이때 topK가 있으면 점수가 깎임)

 

근데 다른 팀에서는 일부러 topK를 다 지우고 결과를 제출해서 topK가 필요 없는 대화 개수를 대충 파악하고 대회조건에 맞춰 eval.jsonl 파일에서 topK가 나오면 안되는 대화들 개수를 비교했는데 일치했다는 것을 통해 대회에서 말하는 과학의 의미를 파악했다.

 

또 다른 팀에서는 RAG구조나 모델링적으로 특별한 기법을 시도하지는 않았는데 data 전처리를 통해 점수를 높인 팀도 있었다.

eval.jsonl데이터 셋의 query의 의미를 손상시키지 않으면서 간결하게 query를 다듬는 작업, document.jsonl의 정보들도 반복되는 문구들을 제거하고 문맥적 의미는 그대로 남겨두고 글을 다듬는 전처리를 했다.

 

이거랑 적절한 임베딩 모델을 사용했는데 점수가 엄청 높았다. 그 팀이 Private LB의 2등 팀인데 2명이서 2등이라니 효율 미쳤다.

 

Data-Centric AI의 중요성을 실제로 느끼는 순간이었다.

마무리하며 + 하고 싶은 프로젝트

발표를 할 때 멘토님께서 RAG를 진행할 때는 다이어그램을 그리라고 하셨다.

어떤 과정을 통해 IR과 RAG가 진행되는 절차를 한 눈에 알아야 좋다고 하셨고, 발표할 때는 다이어그램이 필수라고 하셨다.

잊지 말자!!!!

 

그리고 이번 프로젝트에서는 나름대로 실험 기록도 하고 관리도 했는데 실험이 체계적으로 진행되어서 좋았다.

다만 아쉬운 것은 기간이 짧았다는 거다. 기간이 짧을때는 창의적인 시도를 해보는 것도 도움이 많이 된다는 것을 느꼈다.

 

팀 단위로 진행할 때는 일부는 창의적으로,

일부는 체계적으로 가져가서 최소 결과는 보장되도록 하고 성능의 점핑을 기대하는 방식으로 가도 좋지 않을까 생각해본다.

 

꼭 하고 싶은 프로젝트가 있고 그건 IR, RecSys, RAG를 종합적으로 사용해야 하는데 마무리하면서 실용적인거 많이 배워가는 것 같다.

 

오늘은 여기까지!

끝-

 

힘들었는데 끝나고 돌아보니 다 기도대로 되고 있었네.

감사합니다. 하나님.

'Upstage AI Lab' 카테고리의 다른 글

Data Centric AI 학습 회고  (5) 2024.12.15
LM to LLM 학습 일지 + Kaggle 연말 행사 회고  (4) 2024.12.09
NLP 경진대회 회고  (3) 2024.12.02
CV 경진대회 회고  (1) 2024.11.10
Pytorch, DL 공부  (3) 2024.11.09