최종 결과
- public leaderboard: 12th (0.7005)
- private leaderboard: 12th (0.6460)
- 점수 차이가 바로 위 팀이랑 꽤 격차가 났다. 한 0.06점 정도?
- 그래서 도대체 무엇이 저들과 우리의 차이를 가르는지 계속 궁금했었는데, 아마 위에 있는 팀들은 32B 모델을 사용했던 것 같다.
- 그걸 프로젝트 끝날 때까지 찾지 못한 것이 좀 아쉽지만, 그래도 그렇게 방법론이 틀리진 않았던 것 같다는 반증으로 생각되어서 좀 위로가 된다.
프로젝트 소개
- ‘수능 문제 풀이 모델 생성’이 아니라 ‘수능형 문제 풀이 모델 생성’인 만큼 실제 데이터셋이 수능 문제는 아니다.
- 강의 주제가 ‘Generation for NLP’이라 아마 생성형 모델을 써야 되지 않을까 싶었고? 실제로 생성형 모델로 Task를 진행했다.
- Encoder 계열은 받을 수 있는 문장의 길이가 아무래도 제한적이다보니 Decoder 계열로 가는 게 맞는 것 같다.
- 데이터에는 문제 지문, 질문, 선지, 정답, 추가 보기와 같은 정보로 구성되어 있으며, 리더보드 점수는 accuracy로 계산한다.
프로젝트 진행 과정
11/11 ~ 11/13
강의 보기
- 늘 그렇듯, 프로젝트를 시작하기 전에 강의를 보는 시간을 가졌다.
- 근데 역대급으로 강의랑 과제 빨리 끝낸 것 같다.
- 새로 만난 팀원이 페이스를 잘 잡아줘서 그럴 수 있었던 게 아닌가 하는 생각이 들었다.
프로젝트 사전 설정
- 아무래도 새롭게 합쳐진 팀이다 보니까, 깃헙 브랜치 컨벤션이라든지, 이슈를 어떻게 쓸 것인지… 그런 협업방식에 대해 많은 논의를 나누었다.
- 언어공방만의 새로운 시도는 깃헙 디스커션을 활용해보는 것이었다. 근데 나름 재미있게 잘 쓴 것 같다. 하지만 아직 더 잘 활용해볼 여지가 충분히 남지 않았나….
11/14 ~ 11/20
CoT 도전
- CoT(Chain-of-Thoughts)란?
- 모델한테 단순히 정답을 내놓으라고 하는 것보다 단계 별로 생각하면서 정답을 내놓도록 유도하면 정답을 맞출 확률이 더 올라간다는… 뭐 그런거다.
- 이게 먹히는 이유는 자신이 하나 하나 말하는 근거들에 최대한 위배하지 않고 말하려고 하는 경향이 생겨서 더 잘 푸는 게 아닐까 생각한다.
- 위에서 설명한 CoT를 우리 모델에도 적용하면 어려운 문제에 대해서 더 잘 풀지 않을까 생각을 했다.
- 팀에서 3명 정도가 CoT에 붙어서 각각 다른 방법을 했는데 내 방법은 바로 이거였다.
- 요약하자면 유료 API를 사용해서 미리 CoT를 뽑아 이를 학습시켜서 모델이 CoT를 더 잘 만들 수 있도록 일종의 knowledge distillation을 진행한다.
- 테스트셋에 CoT를 붙여서 다시 정답을 맞히도록 학습한 모델에 대해서 logit을 뽑아 1~5 중 하나로 답을 맞추게 하는 것이다.
- 구현이 이렇게 오래 걸릴 건 아니었는데… 손이 너무 느려진 것 같다… 백준 재활 운동이 필요할 것 같기도 하고…
그래서 잘 됐나요?
- 아뇨. (ㅋㅋ…)
- 유료 API를 써보다가 느낀 건데
gpt-4o-mini정도 크기에서도 할루시에이션을 일으키던데, 그보다 훨씬 더 작고 귀여운 우리 모델이 CoT를 한다는 게 말이 되나 싶었다.
- 그래서 CoT를 처음 제안한 논문을 읽어봤는데 (간단한 리뷰), 오히려 10B 이하의 모델은 대부분 CoT가 성능을 해친다는 연구가 있었다는 걸 확인했다….
- 처음부터 논문을 읽고 근거를 확보한 다음 했어야 했는데… 너무 무지성으로 강의에 나온 거니까 성능이 오르겠지라는 안일한 마인드로 프로젝트를 진행했던 것 같다.
11/21 ~ 11/25
베이스라인 코드 모듈화
- 원래 기존 베이스라인 코드는 노트북 파일로 되어있었다.
- 그래서 서 모 캠퍼님꼐서 노트북 파일을 파이썬 파일로 리팩토링을 해주셨는데, 쓰다 보니
(제가 깐깐한 사람이라…) 불편한 점을 느꼈다.
- 모델 하나를 학습하고 추론하는데 각각
MyTrainer랑 MyInference라는 2가지의 클래스를 만들어야 하는데, 이게 좀 응집도 면에서 떨어지지 않나 생각했다.
- 그래서 클래스 하나에
train()과 inference() 함수를 동시에 담아둘 수 있도록 모듈화를 진행하고자 했다.
- 그러다가 “그러면 모델A, 모델B, 방법론C, 방법론D가 있으면
A-C, A-D, B-C, B-D 총 4개의 클래스를 만들어야 하나?”와 같은 생각이 들어서 이 둘을 분리하여 다시 2개의 클래스로 쪼갰다.
- 최종적으로는 학습 방법에 관련된 클래스
Pipeline 과 모델에 종속된 부분에 관련된 클래스 Manager로 베이스라인 코드를 모듈화하는데 성공했다.
- 어떻게 바뀌었는지 궁금하면 해당 토론을 참고하자.
- 근데 프롬프트 부분도 따로 모듈화할 걸 그랬다.
- … 그치만 이게 너무 오래걸려서…, 프로젝트 도중에 main 브랜치로 병합되면 혼돈의 도가니일 것 같아 끝나고 병합하기로 했다.
- 즉, 프로젝트 기간 내에는 팀적으로는 도움된 것이 없으니 자기만족으로 끝나버린 것 같아서 아쉬웠다….
- 여기서 얻을 수 있는 교훈이 리팩토링이 길어지면 길어질수록 그게 적용될 확률은 점점 줄어든다는 것이다….
1-step CoT
- 멘토링때 멘토님께서 2-step으로 CoT 따로 정답 따로 예측하게 하지말고 한꺼번에 해보는 게 어떠냐해서 모듈화가 끝나자마자 바로 진행해봤다.
- 근데 2-step이 점수가 더 높았다. 아마 1-step으로 하면 정답을 추출하는 post-processing을 rule-base로 해야하는데 그걸 2-step으로 해서 모델이 예측하게 하는 것이 더 유효했기 때문이 아닐까 생각해본다.
11/26 ~ 11/28
앙상블
- 솔직히 해볼 수 있는 건 다 해봤고, 아예 새로운 걸 하기에는 또 시간이 애매해서 앙상블을 비교적 일찍 준비했다.
- 앙상블을 validation 데이터셋에 대한 점수로 평가를 할 생각이었는데, 문제가 모델이 학습된 데이터셋이 필터링 문제로 다 다른 상황이라 이미 학습시켜놓은 모델을 사용할 수 없는 상황이었다.
- 기존 베이스라인에서는 토크나이징 과정이 일어나서 길이가 너무 긴 데이터는 필터링을 하고
train_test_split()이 일어나는데, 그러면 시드값이 고정되어 있더라도 토크나이저가 모델마다 달라서 validation 데이터셋이 달라지게 된다.
- 여기서도 미리 soft voting까지 고려해서 logit을 뽑을 수 있도록 코드를 만들어서 그 코드로 돌릴 수 있도록 했어야 했는데 그러지 못해 아쉬웠다.
- 그래서 마지막날을 제외하고는 validation 데이터셋을 고정시키고 모델을 훈련시킨 다음 validation 데이터셋과 test 데이터셋에 대하여 logit 값을 뽑는 작업에 열중했던 것 같다.
…그러나 이 데이터셋이

- 그렇게 열심히 validation 데이터셋에 대한 logit 값을 뽑아보니 모든 모델이 비슷한 경향을 보이는 걸 확인했다….
- 신기한 건 test 데이터셋에 대해서는 정답을 제시하는 게 엄청 다르게 나오던데… validation 데이터셋과 test 데이터셋이 비슷한 경향을 갖고 있지 않은 것 같았다.
- 그러다보니 validation 데이터셋에서 점수가 높게 나온 앙상블을 내도 public 점수는 따라주지 않았고… 결국엔 무속 신앙의 힘을 빌리면서 거의 기도하다시피 앙상블을 진행했다.
- 이런 경향성을 미리미리 알았으면 더 보이는 게 많았을 것 같다는 생각이 들어서 아쉬움이 많이 남았다.
자체평가
잘한 점
Github Discussion
- 확실히 노션에 정리하는 것보다 깃헙 디스커션이 더 접근성이 좋은 것 같다.
- 나중에 프로젝트를 re-cap할때도 솔직히 노션은 뒤져보기 귀찮을 것 같은데 깃허브에 몰아놓으면 한꺼번에 보기 편할 것 같다.
- 도중도중에 작업 내역을 공유할 수 있어서 되게 괜찮았던 것 같다.
- 그럼에도 불구하고 다음 프로젝트에서는 좀 더 잘 써볼 여지가 있을 것 같다.
- 매일매일 자기가 한 거 정리해서 피어세션때 이야기하기 등 → 너무 급진적인가?
적극적인 코드리뷰
- 박 모 캠퍼님께서 확실히 현업에 계신 경험이 있다보니 이런 걸 좀 더 잘 할 수 있지 않았나 하는 생각이 든다.
- 이전 팀에서는 그냥 merge할까요? → merge할게요~ 같은 흐름으로 진행했었는데, 본격적으로 코드 리뷰를 하면서 3명 이상의 approve가 나와야 한다는 규칙을 마련하면서 코드리뷰를 활성화시키려는 시도가 좋았던 것 같다.
- 근데 확실히 좀 LGTM 딸깍하고 넘어가는 경우가 대다수인 것 같아서… 이것도 무조건 하나는 코드에 대해서 궁금한 걸 질문하도록 강제해야 하나….
아쉬운 점
활발하지 못했던 PR
- 이전 팀에서는 기능 추가가 있었으면 바로바로 PR을 날리고 merge를 하는 과정이 일반적이었다.
- 근데 아마 다른 팀 출신의 팀원분들은 한꺼번에 merge하시는 성향이었는지 새로운 기능이 추가되어도 브랜치로만 코드를 공유하고 PR을 자주 안하신 것 같다.
- 노트북 파일 위주로 작업을 하시는 것 또한 PR이 활발하지 못했던 원인이었던 것 같기도 하다. 임시 파일이라 괜히 PR하고 싶지 않은… 기분은 이해하지만….
- 이건 팀원들이랑 이야기를 해봐야 할 것 같다. PR이 자주자주 일어나서 코드가 좀 더 공유가 잘 되었으면 좋을 것 같다는 게 내 입장이라….
not Data-centric
- 일단 고정된 validation 데이터셋 확보를 너무 늦게 하지 않았나 생각이 든다.
- validation 데이터셋을 고정시켜놓고 훈련용 데이터셋으로 학습한 다음 추론을 할 때 어떤 경향으로 문제를 푸는지 직접 확인할 수 있는 기회를 의식적으로 가졌어야 했는데 그러지 못했던 것 같다.
- 데이터 분석도 베이스라인 코드에 어느정도 EDA가 되어있어서 그것만 보고 그냥 뭘 더 안했던 것 같다. (다른 분들이 하신 것도 있긴 하지만… 일단 난 안했다.)
- 발표한 팀들을 보니 데이터의 출처 또한 알아보고, 데이터 하나하나마다 손수 라벨링을 다시 해주는 걸 보고 정말 대단하다고 느꼈다.
- 한편으로는 그렇게까지 해야하나 싶기도 했지만… 일단은 주어진 데이터를 최대한 활용하는 게 맞았던 것 같기도 하고… 너무 현업스럽지 않다고 넘겨짚고 그냥 pass했던 것 같다.
걍 ㄱ
- 위에서 말한 not Data-centric과도 일맥상통한 이야기같은데, 너무 근거가 없이 방법론을 골라서 해봤던 것 같다.
- 좀 더 데이터 기반으로 의사결정을 하던가, 직접 시도해보기 전에 관련 논문을 간단히라도 research해봤어야 하지 않았을까 생각한다.
- 그리고 너무 다 “저 이거 해보겠습니다.” 하면 “그래용 ㅎㅎ” 하면서 너무 쉽게 허가를 내준 건 아닌가 하는 생각이 들었다.
PM의 부재
- 역시 위에서 말한 걍 ㄱ에서 이어지는 이야기인데, 결과적으로는 PM이 없으니까 이런 일이 일어나는 것 같다.
- 누군가 총대를 메고 일을 잘 뜯어서 하나의 목표를 바라보고 협업을 할 수 있도록 유도했어야 했다.
- PM이 없으니 일정 관리도 안되고… 걍 6명이 다 제각각 하고 싶은 일만 하다가 나중에 모여서 “으라챠챠 앙상블~!” 하는데… 이건 진정한 의미의 협업은 아닌 것 같다는 생각이 들었다.
Zoom의 이점을 잘 못 살림
- 10시부터 17시까지 Zoom에 다같이 들어와있는데, 이러한 이점을 잘 살리지 못한 것 같다.
- 혼자 문제를 맞닥뜨리면 계속 끙끙 앓다가 피어세션 때나 말을 꺼내거나, 방법론 A를 한다고 했다가 잘 안되는 것 같아서 혼자서 방법론 B로 선회해버리는… 그런 문제가 있었던 것 같다.
- 사실 이걸 문제라고 봐야하냐가 좀 애매할 수는 있겠지만, 결국 팀 공동의 목표를 향해 달리는데 이런 사소한 것들부터 공유를 시작해야 병목이 해결되지 않을까 생각한다.
- 이것도 그냥 PM이 없어서 생기는 문제 같기도 하고?
- 다 Zoom에 들어와 있는 만큼 무언가 공유할 내용이 생기면 바로바로 마이크 켜서 이야기를 해보는 게 어땠을까?
- 해결방법 1: 점심 먹고 간단 스크럼?
- 해결방법 2: 화이트보드 켜놓기?
후기
- 사실 내 입장에서는 성능 향상에 도움이 되는 뭔가가 딱히 없었어서 기여가 그렇게 크지 않은 것 같다.
- 새로운 팀이다보니 협업 과정이 아직 파인튜닝할 게 더 많은 것 같아서 이번 프로젝트는 해커톤을 위한 발판이었다고 생각하자….
- 프로젝트 자체가 32B 모델을 안올렸으면 성능이 크게 떨어지는 느낌이라, 사실 12등이긴 하지만 그렇게 못했다는 느낌은 안든다. ㅎㅎ.
- 근데 이러고 바로 해커톤 들어가는 게 살짝 아쉽다. 간단한 프로젝트라도 같이 해보자고 할까? (ㅋㅋ 그러나 이 제안이…)