[2023 국방 AI 경진대회 후기] (2) 본선 준비~본선 당일

b0neh3ad·2024년 11월 13일
0

maicon

목록 보기
2/2

본 시리즈에서는 필자가 'RokafNet'이라는 팀으로 운좋게 준우승을 했던 2023년 국방 AI 경진대회(MAICON)의 후기를 다룬다.

본선 대비 교육

1편에서 가볍게 언급했지만, 당시 공군에서는 MAICON 본선 진출자들을 대상으로 대회 직전까지 3주 간의 집체교육을 진행했다. 아마 22년 대회에서 육해군에 비해 실적이 부진하여 이런 교육을 마련했던 것 같은데, 내 입장에선 말년을 녹일 더할 나위 없이 좋은 기회였다..ㅎㅎ 그렇게 부대 사람들에게 교육 참석에 대한 양해를 구한 뒤, 함께 본선에 진출한 부대원이자 팀원들과 함께 교육이 진행되는 평택의 모 부대로 출장을 떠났다.

부대 환경은 생각보다 너무 좋았다! AI 교육장이 2군데 설치되어 있었는데, 싸제 시설 같은 분위기에 인터넷 이용 가능 노트북을 자유롭게 이용할 수 있었다. 노트북 대수도 교육장 당 30대 가량 있던 걸로 기억해서, 모자라는 일은 거의 없었다. 게다가, 교육을 관리하는 간부님들의 이런저런 배려 덕에 거의 하루 내내 교육과 공부에만 집중할 수 있었다. 현역병 입장에서는 말도 안 되는 환경이었어서, 교육받는 병사들끼리 좋아했던 기억이 아직도 난다.

교육은 외부의 AI 교육 업체에 계신 강사분들과 기타 연사님들이 돌아가면서 진행하는 형태로 이루어졌다. 우선 AI와 ML/DL에 대한 이론을 빠르게 훑었다. 그런 다음엔 CV 분야의 세부 task들(Image Segmentation 등)에 대한 팁을 배웠다. 왜 CV만 하냐면.. 지난 대회의 task가 Change Detection, Object Tracking, Image Super-Resolution 등 전부 그쪽이었기 때문이다.

당장 대회에 써먹을 스킬이 필요했던 입장에서, 초반 강의는 다소 시간 아깝게 느껴지기도 했지만 기초를 다지기엔 괜찮았다. 다만 며칠이 지나니 좀 초조해졌다. kaggle, DACON 등에서 열린 대회에 제출할 코드를 짜보려고 하면 되는 게 하나도 없었기 때문이다. 그런데 때마침 업체 측에서 직접 Segmentation 대회를 개최해주었고, 우리 팀은 실전적인 연습을 할 좋은 기회라고 생각했다.

하지만..

대회 일주일 전, "오디오" 관련 task가 주어질 것이라 공지되었다!

CV 공부에만 집중해왔던 모든 교육생들이 당황했다.. 모의 대회는 별 의미가 없게 되었고, 서둘러 오디오 관련 task와 model을 찾아보았다. 다행히 새로 알아야 하는 내용이 그렇게까지 많진 않았다.
오디오 데이터는 주로 스펙트로그램(Spectrogram), MFCC 등의 형태로 변환되어 model의 input으로 쓰인다. 간단히 말해, 이들은 시간-주파수 축으로 구성된 2D 데이터다. 따라서 이미지랑 비슷한 면이 많았고, audio model을 이해하는 데에도 기존에 공부했던 내용이 많은 도움이 되었다.

뿐만 아니라, 감사하게도 교육 업체 측에서 이에 맞추어 급하게 커리큘럼을 수정해 주었다. 마지막 일주일 간의 교육 내용은 다음과 같았다.

  • 오디오 딥러닝의 주요/세부 task와 model에 대한 개괄적 이해
  • 경진대회 발표 자료 구성 팁
  • ASR(Automatic Search Recognition) 학습 방법론
  • 경진대회 진행 전반에 대한 팁: 학습 전략, 실험 관리, 발표 준비, 재현성 이슈 등

특히, 당시 교육을 통해 ASR task의 SOTA model인 Whisper에 대해 알게 되었는데, 그 덕에 실제 대회에서 빠르게 baseline model으로 선택할 수 있었다.

실전 전략 구축

대회가 다가오자 개발 환경 등 여러 공지가 대회 홈페이지에 올라왔다. 우리 팀은 해당 공지 내용과 교육에서 들었던 여러 팁을 토대로, 대회 며칠 전부터 실전 전략을 구축했다.
구체적으로, 아래와 같이 개발 환경, 코드 작성, 평가의 3개 측면에서 전략을 세웠다.

개발 환경

홈페이지에 공지되었던 개발 환경은 아래와 같다.

이를 바탕으로 각 PC의 역할을 다음과 같이 정했다.

  • 노트북 - GPU가 없으나 3대씩 있으므로 GPU를 쓰지 않는 모든 일을 수행
    : EDA, 데이터 전/후처리
  • 데스크톱 - 괜찮은 GPU가 탑재되어 있으므로 training을 보조하는 역할
    : 데이터 전/후처리, (필요한 경우) 간단한 ML model training, Inference
  • 서버: training만 수행. GPU 계속 돌리기.
    : Training

또한 원활한 대회 진행을 위해, 본격적인 대회 시작 전 아래의 사항을 체크하기로 했다.

  • python 관련 환경변수 설정
    : 정상적인 코드 실행을 위해 반드시 확인해봐야 한다.
  • vscode git 설정
    : 전체 코드의 버전 관리를 위해, 우리 팀은 github에 private repo를 만들어 코드를 업로드하기로 했다. 이에 따라 git 설치, github 계정 정보 저장 및 로그인이 필요했다.
  • vscode 내 extension(python, jupyter notebook 설치 여부)
  • 노트북, 데스크톱과 서버의 연결 가능 여부 및 방식

코드 작성

당시 공지되었던 유의사항은 아래와 같다.

  • 과제 수행 시간: 09시~21시 / 야간 개발: 21시~09시
    (취침희망자의 경우 21시에만 숙소 이동)
  • Baseline 제공
  • Pretrained Model: weights, architecture 사용 가능(public하게 공개된 경우 한정)
  • pseudo labeling, 외부 데이터 사용 금지
  • Colab, 개인 GPU 서버 등 외부 개발자원 사용 금지
  • 제출 횟수: 총 60회 제한
  • 최종 제출 코드: 가장 마지막 제출 코드
  • 정해진 파일 이름, 확장자로 제출해야 함

baseline이 제공된다는 점, pretrained model은 허용되나 외부 data나 pseudo labeling은 금지된다는 점이 눈에 띄었다. 이를 주로 고려하여, 대회 중 시기에 따른 분업 전략을 아래와 같이 세웠다.

0. 초기 코드 세팅
어떠한 코드 작성보다도 우선시 되어야 하는 작업들이다.

- random seed 고정
: 사후 검증 시 성능 불일치로 인한 불이익을 막기 위해 반드시 seed를 고정하고 시작한다.

- Wandb setting
: 실험 관리를 위해 wandb에 필요한 내용이 모두 저장되도록 준비한다. 구체적으로, wandb.init() 호출, metrics logging, weight file 저장 등이 있다.

- 파일 분할
: 전체 작업 흐름을 단계별로 쪼개 분업하고, 마지막에 제출할 때만 하나로 합치는 게 훨씬 효율적이다. 따라서 EDA / preprocess / train / inference / postprocess의 다섯 단계별로 파일을 하나씩 만들어 여러 단계를 동시에 진행한다.

1. 대회 시작 후
다음의 세 역할을 팀원 간 적절히 분배한다.

- Baseline의 train/inference 코드 실행 및 분석
: 다 떠나서 일단 돌아가는 코드가 없으면 끝이다. Baseline을 실행시켜 완전한 형식을 갖춘 inference 결과를 얻는 것을 최우선 목표로 한다. 이를 마쳤다면 코드를 분석해보며 발전시킬 부분을 탐색한다.

- 문제 & 데이터 분석
: 결국 주어진 datatarget metric을 최적화하는 게 중요하다. 심도 있는 EDA 수행을 통해 주어진 data의 주요 특징을 분석하고, metric 값 향상에 도움이 되는 특징을 정리해야 한다. 한편, 동일한 task라도 target metric이 무엇이냐에 따라 fine-tuning을 위한 세부 전략이 달라질 수 있으므로 metric의 특징도 분석한다.

- model, 논문 검색
: 성능 향상을 위해서는 주어진 dataset, task, metric에 대해 더 나은 model을 계속해서 찾아야 한다. model뿐만 아니라 train & inference 전략에 대한 논문을 찾아봄으로써 추가적인 성능 향상을 도모할 수 있을 것이다.

2. Baseline 분석 후(1, 2일차 주간)
Baseline 분석이 끝났다면 이제 실험 설계 및 수행을 거듭할 차례이다. 따라서 아래의 역할을 팀원 간 분배한다.

  • model, 논문 등 검색(노트북 이용)
  • train & inference 과정 분석 및 실험 설계(노트북 이용)
  • 코드 수정 및 실행(데스크톱 & 서버 이용)

3. 1, 2일차 야간
주간에 설계한 실험 중 마저 못 돌린 실험을 돌리는 것에 집중한다. 야간에는 피곤해서 머리를 쓰기 힘드므로, 추가적인 실험 설계보다는 수행에 집중하는 것이다. 이때 반드시 WandB에 계속 기록되는지 확인한다. 피로를 호소하는 팀원이 있다면 일부 인원만 남아서 돌리는 것도 방법이다.

4. 최종 제출 직전(3일차 새벽~아침)
이때부터는 최종 제출물 마무리 작업과 동시에 발표 준비를 해야한다. 따라서 아래와 같이 역할을 재분배한다.

- 코드 수정 및 실행
: 마지막 성능 영끌을 하는 역할이다. 이떄는 hyperparameter tuning 등 성능을 올리기 위한 최후의 실험들을 돌린다.

- PPT 제작
: 대회 측에서 요구하는 조건과 양식에 맞게 자료를 제작한다. 이때 다른 팀원들과 계속 소통하며(특히 발표 담당과) 발표 자료와 작업 현황을 계속 동기화한다.

- 사후 검증 파일 정리
: 사후 검증을 위해 대회 측에서 요구한 파일들을 정리한다. 이때 model의 코드나 weights가 변경되었을 경우 이를 즉각 반영한다.

평가

당시 공지되었던 평가 방식 및 기준은 아래와 같다.

  • 정량평가(performance) : 정성평가(발표) = 7:3
  • 정량평가 - Public score : Private score = 7:3
  • 사후 검증 자료 제출 필수
    : 별도의 수정 없이 재현 가능한 코드 1부, 가중치 파일 1부, 결과 파일 1부, 코드 설명 자료
  • 발표 순서: 1일차 오리엔테이션 시 랜덤 지정
  • 발표 5분(ppt 양식 제공), 질의응답 5분
    양식: 표지, 팀 소개, 문제 이해도, 데이터 활용, 모델 완성도, 수행 프로세스, 소감 한마디

보통 정량평가에서 public보다 private의 비중이 큰데, public의 비중이 훨씬 큰 게 눈에 띄었다. 이에 따라 우리 팀은 public data에 대한 overfitting 등의 문제는 신경쓰지 않고, 무조건 public score를 올리는 데에 집중하기로 했다.
그 외에 평가에서 발생 가능한 불이익을 막고, 정성평가를 무난히 넘기기 위해 다음의 사항을 반드시 체크하기로 했다.

  • 사후 검증 대비 Wandb 이용 코드 백업
  • pytorch 기반 코드 작성
  • 발표 시 모델 선택, fine-tuning 전략에 대한 이유 및 성능과의 인과 관계 설명

본선 대회

대회 당일 오전, 병사들은 교육장에서 다 같이 버스를 타고 대회 장소인 KT인재개발원으로 이동했다. (간부들은 개인 차량으로 이동했다.) 모든 참가자들은 1시까지 대회장으로 모여야 했고, 이후 일정은 아래 표와 같았다.

일자시간내용
1일차 - 11/29(수)~13:00대회 참가자 입소
13:05~13:10개회사
13:10~13:40오리엔테이션
13:40~14:00문제 및 데이터 설명
14:00~17:00환경 세팅 및 과제 수행
17:30~19:00석식
19:00~21:00과제 수행
2일차 - 11/30(목)09:00~21:00과제 수행(조식, 중식, 석식 포함)
3일차 - 12/1(금)~09:00결과물 제출
09:00~12:30발표 평가
12:30~14:00중식
14:00~15:00참가자 참여 프로그램
15:00~15:50우수자 발표 및 시상식
15:50~퇴소식 및 마무리

식사는 인재개발원 내 식당을 이용했다. 도시락이 아닌 것만으로도 행복했는데 음식이 너무 잘 나와서 더욱 좋았다! 짬밥만 먹다가 고급진 싸제 음식을 먹었을 때의 기분은..

1일차

대회장 풍경 (출처: MAICON 홈페이지 > 지난 대회 > 2023)

개회사와 오리엔테이션을 지나, 대망의 "문제 및 데이터 설명" 시간이 되었다. 공개된 문제는 다음과 같았다.

음성인식 기술을 활용한 효과적인 지휘관의 전술 명령 전달

문제를 보고 ASR임을 깨달은 순간 쉽지 않겠다는 생각이 들었다. 관련 코드를 작성하며 어려움을 겪었던 적이 많았기 때문이다. 그래도 뭐 어쩌겠는가, 해야지..

Metric은 CER(Character Error Rate)이었다. 구체적으로, 공백과 문장 부호를 고려하지 않고 계산한 CER 값에 대해 max(0,1CER)max(0, 1-CER) 값이 score가 되었다.

제출 방식에 대한 설명이 이어졌다.
예선과 마찬가지로 Elice 플랫폼으로 코드를 제출해야 했는데, 예선과 달리 플랫폼 내부에서 코드를 돌리지 않고 파일만 업로드하는 방식이었다. 이때, 파일 형식은 .py 가 아닌, .ipynb였다. (음...)

이렇게 앞에서 설명하는 내용을 들으며, 팀원들끼리 데이터 분석과 model 탐색을 어떻게 할지 고민했다. 그리고, 얼마 안 가 대회가 시작되었다.
곧바로 baseline 코드로 추정되는 .ipynb 파일을 까봤는데..

baseline이 없다!

분명히 대회에서 baseline을 준다고 했는데, 막상 까보니 주어진 데이터를 불러오는 코드 정도만 있었다. 설마 이걸 baseline이라고 준 건가 했는데 그 설마가 맞았다;; 그래도 일단 계획했던 대로 역할을 나누어 baseline model을 찾기 시작했다.

대회 시작 후 얼마 뒤, model 검색을 맡았던 팀원이 whisper-tiny를 fine-tuning하여 한국어 음성인식에 쓰는 코드를 발견했다! 대회 환경에서 써먹기에 아주 좋은 구조였고, 약간의 수정을 거친 뒤 fine-tuning 및 inference를 진행했다. 문제없이 결과물을 얻었고 곧바로 제출했다. (score: 0.2916)

한편, 코드를 작성 및 제출하는 동안 EDA를 담당하는 쪽에서도 아래와 같이 유의미한 분석 결과를 만들어 냈다.

  • train dataset의 크기가 14000개인 반면, distinct label text는 4447개에 불과했다. 즉, 같은 텍스트가 서로 다른 화자에 의해 녹음되었다는 것.
  • 7.5초 이상의 데이터에는 label이 겹치는 data가 없었으며, label text의 성격도 달랐다. 짧은 데이터는 명령어, 안내 위주인 데에 반해 긴 데이터는 자기소개, 발표 위주의 발화였다. 따라서 긴 데이터와 짧은 데이터 간 다른 접근이 필요하다.
  • 잡음이 매우 심하고, 사람이 듣기에 목소리 볼륨이 매우 작았다. Denoising을 거친 뒤 ASR model에 넣는 방법도 고려해야 할 것.
  • 대부분의 영어, 숫자는 한국어로 표현되어 있다. 따라서 여러 언어를 고려할 필요없이 한국어에 집중적으로 학습시켜야 효과적으로 성능이 향상될 것.

이제 이걸 코드에 반영할 아이디어를 낼 차례인데...
이때 잠깐 대회가 중단되고 모든 팀이 숙소로 돌아가야 했던 걸로 기억한다. 아마 숙소 배정 등의 이슈였던 거 같다. 우리 팀은 숙소로 가는 길에도, 숙소 안에서도 계속 의견을 나누며 돌아가서 할 일을 정리했었다. EDA를 정말 잘 해냈다고 생각했던 터라, 이때까지만 해도 다들 집중해서 성능을 올릴 생각만 하고 있었다. (그 뒤에 벌어질 일은 알지 못한 채...)

대회장에 돌아와서 모델을 돌리던 중, 대회장의 불안정한 인터넷을 무선에서 유선으로 바꾸는 작업이 이루어졌다. 이로 인해 모델을 학습시키던 중 SSH 연결을 끊고, 유선 인터넷 설치 후 다시 연결을 했다. 그런데...

"학습이 아예 안 되는데? VRAM이 그냥 터져버려;;"

모델 학습이 불가능한 상황이 되었다! 학습 코드를 실행시키면 얼마 지나지 않아 VRAM 점유율이 치솟더니 터져버렸다. 이 같은 일이 반복되자 우리 팀은 큰 당황에 빠졌다. 성능 향상이고 자시고 아무것도 못하게 생겼으니 말이다.

고심 끝에 나를 포함한 2명이 남아 다음날 아침까지 환경을 정상화하는 걸 목표로 하고, 나머지 2명은 컨디션 조절을 위해 자러 갔다.

2일차

그러나... 아무 소득도 없이 아침이 되었다.
물론 아무것도 안 한 건 아니다. 새벽 내내 온갖 방법을 써서 한번이라도 돌려보려고 애를 썼으나 나아지는 것 하나 없었다. 일단 pip library 의존성 문제인가 싶어 python 가상 환경(venv)에서 돌려봤지만 여전했다. 설마 GPU 서버 문제인건가 싶기도 해서 SW기술팀에 문의했고, 재할당 받은 서버에서 돌려봤지만 여전히 안 돌아갔다! 풀뿌리라도 붙잡는 심정으로 SW기술팀 분들께 구체적인 문제 상황을 말씀드리며 몇 차례씩 문의드렸지만, 나아지는 건 아무것도 없었다. (그때 번거롭게 해드려서 죄송했습니다 ㅠㅠ)

그 사이 다른 팀들은 열심히 돌려서 점수 올리고, 우리 팀 순위는 쭉쭉 떨어지고, 새벽이라 피곤한데 쪼들리기까지 하고.. 참 미칠 노릇이었다.

그래도, 뭐라도 진척이 있어야하지 않겠냐는 마음에 지금 당장 할 수 있는 EDA, Data pre/postprocess에 집중했다. 한두명 정도만 서버를 건드려보고, 나머지 인원들은 전부 이쪽에 매달렸다. 이때 한 팀원은 1일차부터 EDA를 위해 14000개의 음성 파일을 하나하나(!) 들어보고 있었는데, 그 과정에서 5479번째 오디오 데이터의 길이가 label text의 길이에 비해 현저하게 길다는 것을 발견했다! 다같이 들어보니 발화 녹음 후 약 1분 간 녹음을 종료하지 않아 순수 noise만이 녹음되어 있음을 확인했다. 해당 noise는 백색 소음처럼 조용히 '치이-' 거리는 소리였는데, 대부분의 train data가 이와 (사람이 듣기에) 비슷한 noise를 갖고 있음을 확인했다. (총소리, 공공장소 내 대화소리 등 시끄러운 noise를 가진 data는 몇 개만 존재했다.)

그렇다면, 해당 noise만을 crop하여 denoising에 이용한다면 input data의 품질은 더 올라가지 않을까? 이를 구현하기 위한 방법을 모색하다가 noisereduce라는 적절한 library를 찾았다! 그렇게 dataset의 noise 분포를 활용한 denoising의 구현이 가능해졌고, 이를 포함한 Pre-process 과정은 다음과 같다.

  1. Denoising: input data에서 crop한 noise를 이용해 denoising을 수행한다.
  2. label text 정제: 평가 지표로 계산되는 CER 값에는 공백, 문장 부호가 영향을 주지 않으므로 이를 label text에서 제거한다.

그렇게 preprocess 아이디어가 어느 정도 정리되었고, 어차피 모델도 못 돌리는 김에 일단 내가 맡아서 구현해뒀다.

어느덧 점심시간이 지나 오후가 되었고, 여전히 GPU 의문사의 해법을 찾지 못했던 우리 팀은 조금씩 체념해가고 있었다... 어제 일 때문에 밤을 꼴딱 샜던 나는 팀원들의 허락을 맡고 2~3시간 가량 낮잠을 자기도 했다. 그렇게 오후 4시쯤 되었을까, 팀원 중 한 명이 모니터를 향해 나지막이 외쳤다.

???: "어 된다"

그 한 마디에 다들 정신이 번쩍 들어 모니터 앞으로 몰려들었는데, 진짜로 학습이 잘 되고 있었다! 온갖 조치를 해도 해결되지 않던 문제였는데...
원인을 알고 보니 허무하기도, 착잡하기도 했다. .ipynb 파일에서 돌리려 했던 게 문제였다. 똑같은 코드를 전부 .py 파일에 옮겨 돌리니 아주 잘 돌아가는 것이었다. 오만 감정이 다 들었다. 이 간단한 걸 왜 안 해봤나 싶기도 했고, 굳이 .ipynb 파일로 제출하라고 한 대회 측에 원망이 들기도 했고, 또 거기에만 갇혀있던 스스로가 답답하기도 했고...

하지만 그런 잡생각도 잠시, 우리에겐 남은 시간이 별로 없었다! 이제 반나절 남짓 남은 시간 동안 지금까지의 아이디어를 모두 쏟아부어 성능을 끌어올려야만 했다. 일단 아까 짰던 preprocess의 output을 model에 넣었는데, score가 매우 큰 폭으로 뛰었다! (0.2916 -> 0.53)

한편, 이렇게 얻은 model의 output을 보니 model이 내놓은 text의 마지막 1~2단어가 반복되는 것을 알 수 있었다. (예: '... 숙소에서 할인 할인 할인 할인 ...', '... 예약 시간 예약 시간 예약 시간 ...') 일단 post-process로 이걸 잘라내는 rule-based logic을 추가했다.
각 단어의 자잘한 오타들도 눈에 띄었는데, 이를 교정하기 위한 logic도 만들기로 했다. 먼저, train data의 label에서 추출한 단어들로 corpus를 만든다. 이후 model의 output에 포함된 각 단어를 순회하며 이와 cosine similarity가 가장 높은 corpus의 단어로 치환하는 것이다. 적어도 우리의 EDA 결과에 따르면 이는 큰 폭의 성능 향상을 만들어 낼 것으로 기대되었다.
post-process 과정을 정리하면 다음과 같다.

  1. 반복 문자 제거: 끝부분의 1~2단어 주기 반복 패턴을 없애기
  2. 철자 오류 수정: train data를 활용한 corpus에서, 가장 높은 유사도를 가진 단어가 threshold 값을 넘는 유사도를 가졌다면 해당 단어로 치환. 이를 model output의 모든 단어에 대해 반복.

이를 토대로 한 post-process 코드도 금세 완성했고, 앞선 결과물을 넣어 제출해보니 또 다시 큰 폭으로 성능이 향상되었다! (0.53 -> 0.633) 스코어보드에서 순위가 쭉쭉 오르는 걸 보며 우리 팀은 매우 흥분했고, 곧장 model을 건드리는 단계로 넘어갔다.

원래의 계획으로는 769M param 규모의 whisper-medium까지 돌려보려고 했으나, 촉박한 시간 동안 실험을 거듭하며 학습시키기에 이는 너무 컸다. 따라서 차선책으로 244M param 규모의 whisper-small을 택했다. huggingface를 뒤져보니 한국어로 fine-tuning된 공개 model이 이미 있었어서 곧바로 들고 왔다.

먼저 pre-process를 거친 input data를 model에 넣어 학습시켰고, 해당 model의 raw inference를 일단 제출해봤더니 0.7642의 score를 얻었다;; 아직 post-process도 안 했는데 말이다! 솔직히 이때는 '1일차에 문제가 생기지 않았더라면..' 하는 아쉬움도 정말 많이 느꼈다. 하지만 앞서 말했듯 그럴 여유는 없었고 곧바로 post-process를 진행했다. 역시나, 이번엔 0.8499까지 치솟았다. 당시 scoreboard 기준 1위 점수였다!

눈앞에 1등 상금 2000만원이 아른거리기 시작했다..

그렇게 밤이 되었고, 나는 최종 발표를 담당했었기 때문에 컨디션 관리 차 숙소로 자러 갔다. 남은 팀원들은 대회 전 계획했던 대로 '최종 제출 직전' 시기에 맞는 역할을 각자 나누어 맡아 밤을 지새웠다.

3일차

6시쯤 눈을 떴던 것 같다. 간단히 씻고 나오는 길에, 혹여라도 우리 팀이 극적인 성능 향상을 또 이뤄내진 않았을까 하는 기대감에 폰으로 scoreboard를 봤다. 하지만 역시나, 큰 향상은 없었다. 하지만 등수는 계속 1~2위에 머물러 있었다.

내가 자러간 뒤 이루어진 성능 향상은 크게 두 지점에서 있었다.

이를 통해 0.86xx 수준까지 score를 올렸다. 그래도 발전이 있었으니 다행이었다.

발표 자료도 거의 마무리되고 있었다. 다만 지금도 아쉬움으로 남는 게, 이때 내가 발표 자료 수정에 적극적이었어야 했다는 것이다. 기왕 잠까지 자고 온 거 배점이 뭐 크든 작든 후회없이 준비했어야 맞는 건데, '무난하기만 하면 된다'라는 생각에 안일해졌던 건지 너무 대충 준비했다. 발표 자료를 만들었던 팀원은 EDA를 위주로 했었기 때문에, 모델 train 및 inference의 pipeline에 대해서는 내가 적극적으로 자료 제작에 관여했어야 했다. 그렇지 않았다보니 내 생각에 매력적이었던 포인트가 충분히 발표에 담기지 않았었다고 생각한다.

그렇게 9시가 되었고, 우리 팀은 마감 9분 전에 마지막 제출을 한 뒤 제출할 파일 정리를 마무리지었다. 이후 발표를 위해 심사 장소로 이동했다. 발표는 1일차 오리엔테이션 때 뽑았던 순서대로 진행했는데, 내 기억에 우리 팀은 꽤 뒤쪽이었다. 그래서 다른 팀들의 장단점을 보고 갈 수 있어 나름 괜찮았다.
우리 팀 발표는 뭐.. 그냥 무난했다. 특별히 못한 건 아니었지만, 장점이나 매력 포인트를 잘 부각시키지도 못했다고 생각한다. 오죽하면 집체교육을 담당하셨던 중령님도 발표가 끝난 뒤 우리 팀이 충분히 어필을 못 한 것 같다는 말씀을 하셨을까 싶다.

그렇게 모든 팀의 발표가 마무리되고, 참가자들은 대회장에서의 마지막 식사를 위해 다 같이 이동했다.
사실 앞서 발표했던 것 때문도 그렇고, 배가 그닥 고프지 않았다. 그러나 마지막답게 성대하게 차려졌던 뷔페식은 현역병 입장에서 결코 놓칠 수 없는 메뉴였고, 배가 안 고파도 일단 입에 꽤 많이 밀어넣었던 것 같다...ㅎㅎ 식사 중간중간 다른 참가자 분들이 1등 축하한다는 말씀을 해주시곤 했었는데, public scoreboard 기준으로 틀린 말은 아니었지만 최종 결과가 나오기 전이라 불안불안했다.

그렇게 식사가 끝나고 간단한 이벤트가 진행된 뒤, 마침내 순위 발표의 시간이 다가왔다. 가장 낮은 순위부터 역순으로 쭉 발표했고, 마침내 1, 2위 발표만을 남겨둔 상황이었다. 지금까지는 그냥저냥 멘트로만 쭉쭉 이어서 발표하더니, 갑자기 웅장한 음악이 울려퍼지기 시작했다; 가뜩이나 무대 위에 서 있는 것도 떨리고 부담스러운데 말이다. 곧이어 대형 스크린에 위 사진처럼 20세기 폭스를 연상케하는 거대한 트로피 모형이 등장하더니..

다른 팀의 사진이 스크린에 등장했다.

그래도 뭐 둘 다 공군팀이고, 서로 열심히 한 것도 알기에 진심으로 축하해드렸지만 그와는 별개로 아쉽긴 참 아쉬웠다. 억까란 억까는 죄다 당하면서 끝까지 올라왔기에 더 그랬던 것 같다.

그렇게 국방 AI 경진대회를 향한 약 두 달 간의 나의 여정은 마무리되었다.
이 대회가 아니었더라면, ML/DL 코드라고는 한 줄도 못 짜던, Pytorch랑 Tensorflow가 뭔지도 몰랐던 내가 두 달만에 이렇게 발전할 수는 없었을 것 같다. 여러모로 뜻깊었던 대회였고, 군생활을 의미있게 만들어 준 순간들 중 하나였다.

2024 MAICON에 대한 조언..?

올해 본선 대회가 22, 23년이랑은 또 상당히 다른 기조라고 들었다. 무슨 로봇을 쓴다던데... 그래서 사실 내 조언이 직접적인 도움은 안 될 것 같다. 그럼에도, 포괄적으로 먹힐 만한 것들을 간단히만 적어보면 이렇다.

  • 팀원별 역할 분배
  • 할 수 있는 거 먼저 다 해 두기
    : 위에서 우리 팀이 당했던 억까와 그에 대한 대응을 보면 뭘 말하려는지 대강 알 수 있을 것이다.
  • 팀원 간 교대 스케줄 설정
    : 2박 3일 간의 오프라인 대회인 MAICON 본선에서, 팀원 간 교대 스케줄은 컨디션 관리에 있어 매우 중요하다. 이에 문제가 없기 위해서는 반드시! 운영진에게 숙소 복귀 가능 시간대, 수면 가능 시간대 등을 확실히 알아오도록 하자.
    (사실... 1일차에서 2일차로 넘어가는 밤을 샌 나랑 팀원 한 명은 2일차 낮에 숙소로 돌아가서 잘 생각이었다. 그리고 실제로 숙소로 돌아갔다. 근데 어찌된 건지 1일차 때는 '그래도 된다'고 했던 운영진들이 난데없이 숙소에 들어와서 우릴 깨우는 거다! 우리 팀 같은 불상사가 없도록, 대회 운영진과 거듭 소통하며 팀원 간의 교대 스케줄을 정해야 한다.)
  • 체계적인 모델 버전 관리, 실험 관리
  • 발표 자료 구성

(이 부분은 나중에 시간 나면 더 채울 예정이다.)

profile
뭐라도 쓰다보면 뭐든 남겠지

4개의 댓글

comment-user-thumbnail
2024년 11월 14일

재밌어요 :)

1개의 답글
comment-user-thumbnail
2025년 8월 2일

글 잘 읽었습니다!! 867기입니다.. ML, DL 경험 외 알고리즘 등 기본 코딩 실력이 얼마나 필요한지 궁금합니다.

1개의 답글