최종 결과
public leaderboard: 9th (0.9341)
private leaderboard: 6th (0.9391)
최종 등수가 3등이나 올랐다..!
프로젝트 진행 과정
09/10 ~ 09/26
프로젝트는 추석연휴(09/13~09/19)를 포함한 3주 동안 진행되었다.
GPU 서버 문제로 인해 09/12 부터 GPU 서버를 할당받을 수 있었다.
프로젝트 시작 전
사전 조사
프로젝트에서 가장 아쉬웠던 점은 다름 아닌 프로젝트가 시작하기도 전에 있었던 일이었다.
프로젝트에 대한 걱정이 앞섰던 우리 조는 이전 기수 레포지토리 및 wrap-up report 등을 조사했었다.
근데 이게 정말 최악의 선택이었던 것 같다. 마치 빨간약을 먹은 네오가 된 것 같았다.
조사하는 도중에는 몰랐는데, 막상 프로젝트를 시작할 시점이 되니까 결국 어떤 데이터 증강이나 어떤 모델이 프로젝트에 잘 적용되는지 다 알아버리니 결국 우리가 프로젝트를 통해 얻을 수 있는 경험을 빼앗긴 것 같다고 생각했다.
만약 이 글을 읽고 있는 부스트캠프 후배님이 있으시면 창을 닫는 것을 권장드린다.
개인 목표 설정
그래도 잘했던 점은 개인 목표를 설정해둔 것이었다.
나만 설정한 건 아니고 멘토님의 추천으로 프로젝트 동안 이루고 싶은 개인 목표같은 걸 세우면 좋을 것 같다고 하셔서 팀원 모두가 개인 목표를 세웠다.
내 개인 목표 달성 여부는 후술할 예정
09/10 ~ 09/13
강의 보기
프로젝트 주간임에도 불구하고 강의량이 꽤 많았다.
권고사항에 강의를 모두 시청하고 프로젝트를 진행해달라고 해서 그렇게 했더니만 다른 조는 강의를 보면서 제출하는 것 같기도 해서 살짝 서운했다…
아무튼 강의를 4일 안에 다보고 과제는… 추석을 이용해서 진행해보는 걸로 계획을 세웠고 실제로도 그렇게 할 수 있었다.
너무 좋은 강의가 많았는데, 4일 만에 다 보는 걸 목표로 하다보니 거의 한 귀로 듣고 한 귀로 흘리는 느낌이라서 살짝 아쉬웠다.
서버 설정
ssh로 서버를 설정하는데에도 시간을 좀 투자했다.
Windows 환경에서 서버로 접속이 잘 안되어서, WSL에 있는 pem 파일을 이용해서 로그인하고 싶어서 온갖 난리를 치다가 결국 실패해버렸다
이에 대한 이야기는 개인회고 0912 에 자세히 풀어놨으니 내 삽질이 궁금하다면 참고.
프로젝트 그라운드 룰 설정
가장 먼저 팀 공동의 프로젝트 목표를 설정하였다.
전체적인 테마는 대회에서의 성적보다도 협업과 성장 에 가깝다.
역시 팀 목표 달성 여부는 개인 목표와 함께 후술하겠다.
협업 도구나 어떻게 프로젝트를 진행할지에 대한 이야기를 나누었다: 개인회고 0913 참고
09/14 ~ 09/19
baseline 코드 정리
추석이 거의 다 끝나갈 무렵, 추석 동안 아무것도 안하고 쉬면 큰일나지 않을까 하는 불안감에 뭐라도 해야겠다 싶어서 진행했다.
다음과 같이 진행했다.
일단 baseline 코드에 있는 class를 기준으로 파일을 분리하였다.
그리고 쪼개진 파일들을 폴더로 옮기는데, 폴더명을 어떻게 할지 심히 고민이 많이 되었다.
주로 이 레포지토리 와 챗GPT의 도움을 많이 받았다.
그리고 argparser 라이브러리를 이용해서 여러 개의 인자를 받을 수 있게 되어 있던 부분을 config.yaml 파일의 형태로 관리하려고 하였다.
일단 기존 방식은 CLI에 입력해야 해서 1차원 구조인데, 이는 구조적인 정보를 담기 어렵고 매번 인자를 기억하고 입력해야 하는 건 좀 귀찮을 것 같다고 생각했다.
가장 이상적인 그림은 config.yaml 파일의 내부 설정만 건들면 실험 세팅을 완벽하게 통제할 수 있는 것이라고 생각해서 이런 식으로 바꾸었다.
너무 마음대로 바꿨나 싶었는데 팀원분들도 좋다고 해주셔서 고마웠다.
간단한 EDA
훈련용 데이터셋의 label 분포가 어떤지를 시각화하는 작업을 했다.
그리고 훈련용 데이터셋을 tokenizer에 넣고 난 이후의 길이 분포도 확인해보았다.
streamlit을 배운 김에 한번 써먹어보고 싶었는데 시각화는 그냥 노트북 파일로 하는 게 짱인 것 같다…
그래도 streamlit을 하면서 만들어 놓은 시각화 함수를 훗날 노트북에서 불러와서 사용할 수 있어서 좋았으니 오히려 럭키비키가 아닐까?
그 외
그러고는 과제하고서는 계속 놀았다…
놀면서도 양심의 가책을 느끼느라 힘들었다.
아마 내 기억상 이미 이때 리더보드에 12개의 팀이 제출한 기록이 남아있었다.
09/20 ~ 09/24
모델 탐색
추석 동안 팀원분이 알아보신 여러 개의 모델을 실험해볼 수 있는지 확인해보는 시간을 가졌다.
어떻게 찾았는지 궁금하다… 난 잘 못 찾겠던데…
모델 리스트는 notion에 정리한 후, 3 epochs 정도 실험을 돌린 뒤의 검증용 데이터셋과의 피어슨 상관계수를 구하고 적어둔 다음, 실험이 끝난 모델은 취소선 처리를 해서 서로 겹치지 않게끔 했다.
성능이 좋았던 모델로 꼽혔던 건 snunlp/KR-ELECTRA-discriminator, jhgan/ko-sbert-nli, BM-K/KoSimCSE-roberta, jhgan/ko-sroberta-multitask, KDHyun08/TAACO_STS가 있다.
그 중 제일 성능이 좋았던 snunlp/KR-ELECTRA-discriminator를 시험삼아 20 epochs 정도 학습시키고 제출해봤는데 엄청난 퍼포먼스 향상을 보여서 이걸 앞으로의 프로젝트 기간 동안 base model로 삼았다. (앞으로 베이스모델이라고 하면 이 모델을 얘기하는 것이다.)
데이터 증강 및 전처리
팀원 모두가 달라붙어서 함께 데이터 증강 및 전처리 실험을 정말 많이 진행해보았다.
그 중에서 내가 시도해본 방법이랑 최종적으로 적용한 방법들을 소개하겠다.
내가 시도했던 것
K-TACC이라는 BERT 모델을 이용한 데이터 증강을 구현한 깃헙 레포지토리 가 있다.
이 중에서 bert_mask_insertion이라는 작업이 있는데, 간단히 말하자면 문장에 맥락상 맞는 단어를 임의의 위치에 삽입해주는 것이다.
이를 훈련용 데이터셋에 적용하는 방법을 하고자 하였다.
label을 어떻게 설정할지 많은 고민을 했는데, 내가 해보고자 했던 방법은 단어를 많이 삽입을 할 수록 라벨을 더 낮게 측정하는 것이었다.
결과적으로는 실험 결과가 그렇게 유의미하게 좋아지지 않아져서 폐기했다.
근데 이것도 알고보니 부스트캠프 선배님의 작품이셨다. 마치 영화 파이널 데스티네이션을 보는 것 같았다. 어딜 가도 선배님의 품에서 벗어날 수 없다니…
아 그리고 데이터 증강 기법을 조금 더 확장성있게 적용하고 싶어서 객체 지향적으로 바꾸는 작업을 했다.
이를 진행한 이유는 더 복잡한 데이터 증강 함수를 추가할 때를 대비 하기 위함이었다.
보조 함수가 필요한 데이터 증강의 경우
함수 내부 설정을 다루기 위한 추가적인 파라미터가 필요한 경우 등
최종적으로 적용한 방법
swap_sentences
단순히 훈련 데이터셋의 1번 문장과 2번 문장을 바꾼 데이터를 증강하는 방법이다.
심플하지만 데이터셋이 2배 가까이 늘어서 훈련에 도움이 되었다고 생각한다.
참고로 이미 label=0인 데이터가 너무 많기 때문에 label=0인 데이터 대해서는 적용하지 않았다.
regex-sub
2글자 이상 반복되는 데이터를 2글자로 줄이는 데이터 전처리 방법이다.
ex. !!!! -> !!
한글 특유의 초성체나, 문장 부호 등을 줄일 수 있어서 큰 효과를 볼 수 있었던 것 같다.
이를 적용한 베이스 모델의 public score는 0.9198 에서 0.9239 로 잘 올랐다.
프로젝트가 끝나고 다시 확인해보니 private score는 떨어졌었다… 허허…
english-normalization
영어가 포함되면 그 단어를 한글로 번역하는 데이터 전처리 방법이다.
특정 고유 명사가 영어로 포함된 데이터셋을 확인하였고 이에 대한 예측이 잘 안되어 이렇게 하면 좋지 않을까해서 시도해보았다.
처음에는 너무 오래 걸리고 public score도 너무 안나왔다.
그래서 여기서 디버깅을 해보면서 왜 오래 걸리는지 확인해보고 다음과 같은 결론을 얻었다.
영어 단어가 내장된 데이터가 은근 많았다.
slack 데이터셋 같은 경우에는 <PERSON>과 같은 스페셜 토큰? 같은 게 있었다.
KBS나 KT같은 단어는 번역하면 오히려 문맥을 파악하기 어려울 수 있겠다고 생각했다.
따라서, 대문자로만 이루어진 영단어나 길이가 4 이하인 영단어에 대해서는 번역을 진행하지 않도록 하였다.
이를 적용하니 public score가 0.9239 에서 0.9241 로 올랐다! (private score에서는 더 큰 폭으로 올랐다: 0.9291 → 0.9308 )
09/25 ~ 09/26
앙상블
한때 감히 앙상블을 의심하던 때가 있었다.
“어떻게 가장 좋은 모델에 성능이 더 떨어지는 모델들을 끼는데 더 성능이 좋아지지?”
그러나 앙상블은 그걸 해내고야 말았다.
그냥 가볍게 3개 정도 모델을 섞어서 제출해보니 바로 0.9241 에서 0.9295 로 급상승 해버렸다!
그리고 성능이 가장 잘 나온 베이스 모델들을 섞어보니 이건 성능이 별로 잘 나오지 않아서, 최대한 베이스가 다른 모델을 섞는 게 좋다는 결론을 내렸다.
이때부터 계속 새로운 모델을 찾고 20 epochs 씩 돌리면서 앙상블을 하기 위한 재료를 찾는 여정을 시작했다.
아마 앙상블이 좋아지는 이유는 여러 가지 모델의 평균을 내어서 사용하니 결과가 조금 더 안정적인 모양이 되는 것이 아닐까 추측해본다. (서로의 아웃라이어를 억제하므로)
하이퍼파라미터 튜닝
wandb sweep을 이용한 하이퍼파라미터 튜닝도 진행하면서 새로운 모델의 성능을 최대한 끌어올려 보기로 하였다.
이에 대한 코드는 한 팀원분이 전담해서 맡아주셔서 디테일한 건 잘 모르겠지만 그래도 한번 써봤으니 이걸로 오케이라고 생각해본다.
sweep 관련 코드는 한번 다시 봐야 할 것 같다.
프로젝트 종료
우린 마지막날에 주어진 10번의 제출을 모두 앙상블을 하는데 투자하였다.
그 중 6개의 모델의 출력을 단순 평균으로 구한 것이 가장 높은 성적을 보였고 6등으로 마무리할 수 있었다.
앙상블을 더 잘 하고 싶어서 나름대로 상관계수도 보면서 분석을 했는데, 그냥 거의 마지막에는 신앙의 문제가 되어버린 것 같아서 이걸 어떻게 하면 더 잘할 수 있을지 궁금하긴 하다.
좋았던 점과 아쉬웠던 점
좋았던 점
처음으로 제대로 진행한 협업이라는 느낌이었다.
Github도 되게 열심히 쓰고, 특히 issue나 PR을 나름대로 잘 활용했다고 생각한다.
각 일을 분담하지 않고 각자 지금 상황에 맞는 필요한 일을 생각해서 해오고 그걸 합치는데 무언가 구멍나는 부분이 없어서 굉장히 신기했다.
그리고 혼자였다면 이 긴 시간동안 계속 집중을 유지하지 못했을 것이라고 생각한다.
다양한 도구를 써볼 수 있어서 좋았다.
특히 Slack과 봇들을 연동하니까 굉장히 프로젝트 관리가 쉬워진다는 느낌을 받았다.
다음에는 아싸리 우리끼리 slack 서버를 따로 파버리는 것도 괜찮지 않을까 하는 생각이 들었다.
프로젝트 시작 전에 방향성을 잡아서 좋았다.
사실 점수가 0.01 정도 차이나는 게 결국 무슨 의미인가 싶기도 했다. 고작 그만큼 올리려고 노력하고 있는데 그마저도 잘 올라가지 않던 게 정말 스트레스 받기도 했다.
결국에는 누가 더 좋은 모델을 찾는지에 대한 운빨 테스트 같기도 했다.
그런데 그렇게 힘들 때마다 내 목표가 뭐였는지 되새김하고 내가 잘하고 있다고 날 다잡을 수 있었다.
이로인해 목표와 방향성의 중요성에 대해서 많이 느꼈던 것 같다. 멘토님 감사합니다…!
제대로 성장할 수 있었던 것 같다.
다른 사람 코드 보면서 디버깅하고, 데이터셋을 보면서 왜 안되는지 분석하고…, 이런 과정들을 통해 더 성장할 수 있지 않았나 생각한다.
그리고 후술할 아쉬웠던 점이 상당히 많은데(ㅋㅋ), 또 아쉬운 게 많은 만큼 앞으로 더 성장할 여지가 있는 것 같아서 좋다.
오히려 프로젝트를 하면서 보다 끝나고 나서 성장을 더 많이 하는 기분인 것 같다.
아쉬웠던 점
이전 기수 레포지토리를 봤던 것
성적을 올리는 데에는 도움이 됐을지는 모르겠지만, 이것 때문에 우리가 직접 고민해보고 실험할 수 있었던 것들을 너무 많이 뺏긴 기분이었다.
생각해보면 너무 당연한건데, 너무 프로젝트에 대한 조바심이 앞섰던 것 같다.
베이스라인 코드 정리를 더 빨리 시작하지 않은 것
아예 첫날에 모여서 다 같이 베이스라인 코드를 읽어보고 하나씩 분리하면서 폴더구조를 만든 후 커밋을 하고 시작하는 것이 제일 이상적이지 않았을까 생각한다.
깃허브 레포지토리가 아예 비어있으니까 뭔갈 하고싶어도 하지 못하는 상황이었어서… 이게 너무 아쉬운 것 같다.
강의도 그냥 추석때 다같이 몰아서 보고 오는 게 어떨까 싶기도 하고… 이건 너무 갔나?
데이터 EDA의 중요성을 몰랐던 것
무언가에 홀린 듯 프로젝트 초반에만 데이터 EDA를 간단히 진행하고 그 이후로는 더 이상 진행하지 않았던 게 정말 크게 아쉽다.
데이터 증강 및 전처리를 하는데 그 결과를 분석하지 않는다? 이건 그냥 정말 운에 맡기는 것이다.
그러다가 데이터 증강에 오류가 생겨 디버깅을 하다가 그 중요성을 깨달아버렸다… 다음에는 EDA를 통해 데이터를 최대한 많이, 자주 분석해보고 싶다.
하이퍼파라미터 튜닝을 늦게 시작한 것
데이터 증강 및 전처리로 인한 모델 성능의 변화를 확인하기 위해 변수를 최소화하려고 하이퍼파라미터를 계속 고정시켜놨었다.
근데 생각해보니까 최적의 하이퍼파라미터를 먼저 찾고 데이터 증강 및 전처리에 대한 효과를 보는 게 맞는 것 같다는 생각이 들었다.
WandB를 늦게 사용한 것
실험 로깅이 홈페이지로 되니까 진짜 편하다 생각했다…
특히 다른 팀원의 실험도 같이 보고 분석할 수 있어서 진짜 편했다…
빠르게 wandb를 적용했어야 했는데 이게 sweep만을 위한 도구라고 생각해서 도입이 늦어졌다… 다음에는 바로 wandb 연동부터 시작하고 프로젝트를 시작하면 좋을 것 같다.
Jira 말고 Notion 쓴 것
그냥 노션만으로도 프로젝트 관리가 쉬울 줄 알았다…
근데 되게 메모가 이곳저곳 중구난방으로 되어있어서 너무 관리하기 어려웠다.
서로 메모해둔 곳이 달라서 실험 내용이 공유가 안되거나 하는 등의 문제가 있었다.
그냥 굳이 일 벌리지 말고 간단하게 노션쓰자고 생각했었는데, 그게 더 큰 일이 되었다. 결국 멘토님 말을 믿고 따라가는 게 맞았다… 흑흑. 죄송합니다.
Validation 데이터셋의 점수를 믿지 않은 것
당장 찍히는 public score랑 검증 데이터셋의 score랑 너무 gap이 심하니까 그냥 public score를 믿어버린 것 같다.
근데 사실 그러면 당연히 안된다는 걸 공개된 public score를 보면서 깨달았다.
물론 public score도 중요하지만, 검증 데이터셋 score가 잘 나오는데 당장 public score에 점수가 안나온다고 해서 포기해버린 데이터 증강들이 머리에 아른아른거린다…
그리고 검증 데이터셋으로는 inference도 안해봤는데, 이게 정말 바보짓이었던 것 같다.
다음에는 검증 데이터셋으로부터 얻은 지표를 믿어보기로 하자.
목표 review
개인 목표
✅ 프로젝트가 끝나고도 재현이 가능하도록 메모의 습관화
지금 쓰고 있는 블로그도 메모의 일종이다.
그리고 Issue랑 PR로 열심히 메모를 많이 남겼으므로 시간만 넉넉하다면 재현가능할 것 같다.
❓ 의사 결정할 때 충분한 이유로 뒷받침하기
Issue랑 PR 이용해서 ‘왜?‘에 대한 이유를 많이 남겼다고는 생각한다.
하지만 너무 지표(ex. public score) 위주의 결정이 많았던 것 같다.
잘 되어야 한다고 생각했던 데이터 전처리 방법이 지표가 안나오니까 그냥 포기해버리는… 그런 아쉬운 판단을 많이 했던 것 같다.
이게 성적은 중요하지 않다고 생각을 해야되긴 한데, 우리의 방법이 맞았는지 틀렸는지 확인하려면 지표가 올라야 하니까… 이게 좀 딜레마인 것 같다.
그러니 이거는 0.5점 정도로 치도록 하겠다.
✅ 이론을 코드로 구현하여 프로젝트의 전체 흐름을 이해 및 기타 도구의 필요성에 대한 인지
그래도 “이렇게 고치면 더 잘되겠지?”가 성공한 사례가 있어서 일단 이론을 코드로 구현하기는 성공이라고 본다.
프로젝트의 흐름 이해는 하긴 했는데, 뭔가 좀 더 개선할 여지가 있는 것 같다. 다음에 하면 더 잘할 수 있을 것 같은 느낌? 그것까지 파악했으니까 그냥 성공으로 치면 어떨까?
도구의 필요성에 대한 인지는 너무 많이 했다. WandB랑 slack 봇은 진짜 신이다. 다음에는 Jira도 써보고 싶다.
팀 목표
✅ 협업 경험해보기
그래도 다른 조에 비해서는 깃헙을 되게 잘 쓴 편이 아닐까? 그래도 상위 10% 안에 들 것 같다.
✅ 다양한 모델 써보기
앙상블하느라 다양한 모델을 찾고 써보기도 하였다.
다른 조들만의 모델을 잘 찾는 방법이 궁금해진다.
❌ 데이터 전처리 경험
이건 과감하게 실패했다고 생각한다. (물론 나만)
EDA를 잘 살리지 못한 데이터 전처리는 그냥 기도메타가 아닌가 하는 생각이 들어서 이건 다소 아쉬웠던 것 같다.
종합 평가
전체 6점 만점에 4.5점
너무 완벽하지 않으면서도 적당히 완료한 것이 딱 아쉬움을 남겨서 다음 프로젝트는 더 잘하고 싶다는 열의를 끌어 올리는 것 같아서 좋다고 생각한다.
개인 소감
프로젝트 하면서 성적은 신경쓰지 않기로 했지만, 그래도 0.93xx는 너무 넘고 싶었는데 마지막에 앙상블로 넘을 수 있어서 좋았다.
그리고 private score에서 위로 치고 올라간 것도 굉장히 기분은 좋았다.
목표가 진짜 중요하다는 걸 알았다. 목표가 없으면 멀리 못갈 것 같다. 다음 프로젝트 때도 목표를 잘 세워봐야 할 것 같다.
NLP-01 아이즈원 수고 많으셨습니다!