본문 바로가기
고민의 흔적../AI Agent 행동예측 해커톤

(연구일지 #3 Transformer stacking)Dacon AI Agent 행동 예측 대회

by sungjinp0805 2026. 7. 4.

고전 ML 이후, 트랜스포머를 도입해보기

이전 글에서는 고전 ML 접근을 정리했다.

고전 ML 기반으로는 다음 점수까지 도달했다.

holdout: 0.6089
LB:      0.6179
 

baseline이 약 0.43 수준이었던 것을 생각하면 꽤 큰 개선이었다.


하지만 v5 이후부터는 점수 상승폭이 점점 작아졌다.

특히 read_file, grep_search, glob_pattern, list_directory 같은 탐색 계열 클래스에서 혼동이 계속 남았다.
이 클래스들은 모두 “무언가를 찾거나 확인하는 행동”이라는 점에서 표현이 비슷했다.

 

예를 들어 사용자가 “파일 확인해줘”라고 말했을 때, 실제 다음 행동은 상황에 따라 달라질 수 있다.
이미 파일이 열려 있다면 read_file일 수 있고, 파일명을 찾아야 하는 상황이면 glob_pattern, 디렉터리 구조부터 봐야 한다면 list_directory, 코드 안의 참조 위치를 찾아야 한다면 grep_search일 수 있다.

 

고전 ML에서는 이런 차이를 구분하기 위해 정규식 기반 피처, 열린 파일 정보, action sequence 등을 추가했지만 개선폭은 제한적이었다.
이 시점에서 단어 빈도와 수작업 피처만으로는 세션의 문맥을 충분히 반영하기 어렵다고 판단했다.

 

그래서 다음 단계로 트랜스포머를 실험해보기로 했다.
목표는 이전 대화와 현재 요청을 하나의 문맥으로 보고 탐색 계열 클래스의 혼동을 줄일 수 있는지 확인하는 것이었다.


실험 로그

고전 ML 이후 트랜스포머를 처음 도입한 구간이다.

버전               구성                                                                      holdout      LB               주요 내용
초기 시도 텍스트만 트랜스포머 실패 - 로컬 CPU 환경에서 학습·수렴 어려움
v10 klue/roberta-base + meta concat 0.6519 0.6334 트랜스포머 표현과 메타 피처 결합
v11 고전 ML 3모델 + v10 하이브리드 스태킹 0.7006 0.6849 서로 다른 모델의 예측 확률 결합

이 구간의 실험 목표는 고전 ML에서 정체된 부분을 트랜스포머가 보완할 수 있는지 확인하는 것이었다.


첫 시도: history와 current_prompt를 텍스트로 입력하기

고전 ML 접근에서는 TF-IDF를 사용했다. TF-IDF는 특정 단어가 등장했는지, 얼마나 중요한 단어인지 반영하는 데는 효과적이었지만, 대화의 흐름을 직접 이해하는 방식은 아니었다.

 

특히 이번 문제에서는 현재 요청만으로는 다음 행동을 판단하기 어려운 경우가 많았다. 예를 들어 사용자가 “다시 확인해줘”라고 말했을 때, 현재 문장만 보면 무엇을 다시 확인하라는 것인지 알기 어렵다. 앞선 대화에서 어떤 파일을 언급했는지, 직전에 어떤 작업을 했는지까지 함께 봐야 다음 행동을 더 잘 예측할 수 있다.

 

그래서 고전 ML 이후 첫 번째 방향은 history와 current_prompt를 하나의 텍스트로 이어 붙여 트랜스포머에 입력하는 것이었다. 트랜스포머는 attention 구조를 통해 입력 토큰들 사이의 관계를 함께 학습할 수 있기 때문에, 이전 발화와 현재 요청 사이의 연결을 TF-IDF보다 더 잘 반영할 수 있을 것이라고 기대했다.

 

이 실험에서는 별도의 메타 피처 없이, 대화 history와 current_prompt를 텍스트로 직렬화한 뒤 14개 행동 클래스를 예측하도록 구성했다. 즉, 먼저 “대화 흐름을 텍스트로만 넣어도 고전 ML의 한계를 넘을 수 있는가”를 확인해보려는 실험이었다.


초기 결과와 문제점

초기 결과는 기대만큼 좋지 않았다.

텍스트만 사용한 트랜스포머는 고전 ML 최고점인 0.61을 넘지 못했다.

초기 실험에서는 약 0.50 수준에 머물렀고, 로컬 CPU 환경에서는 학습 속도도 너무 느려 실험을 안정적으로 이어가기 어려웠다.

 

고전 ML 단계에서 성능 향상에 크게 기여했던 것은 메타 피처였다.

텍스트만 넣은 트랜스포머는 이 정보들을 사용하지 않았다.
결국 문맥 모델을 도입했지만, 이전 실험에서 중요하다고 확인한 상태 정보를 다시 잃어버린 셈이었다.

 

그래서 다음 실험에서는 방향을 조금 바꿨다.

트랜스포머가 텍스트 문맥을 담당하게 하고, 고전 ML에서 효과가 있었던 메타 피처는 별도로 유지하기로 했다.

 

이번 문제에서 다음 행동은 “무슨 말을 했는가”뿐 아니라 “지금 어떤 상태인가”에 따라 결정된다.

예를 들어 같은 “확인해줘”라는 요청이라도, 직전에 파일을 열었다면 read_file일 수 있고, 테스트 실패 직후라면 run_tests나 run_bash로 이어질 수 있다.

아직 파일 위치를 모르는 상황이라면 glob_pattern이나 list_directory가 될 수도 있다.

따라서 텍스트 문맥과 세션 상태를 함께 사용해야 한다고 봤다.


v10: RoBERTa 표현에 메타 피처 결합

v10에서는 klue/roberta-base를 사용했다.

이는 한국어 문장을 이해하도록 사전학습된 RoBERTa 계열 트랜스포머 모델이다. 

구조는 다음과 같다.

입력 텍스트
   ↓
klue/roberta-base
   ↓
CLS 벡터
   ↓
메타 피처 concat
   ↓
분류 head
   ↓
14개 행동 클래스 예측
 

여기서 CLS 벡터는 트랜스포머가 입력 텍스트 전체를 요약한 표현이라고 볼 수 있다.
klue/roberta-base의 CLS 벡터는 768차원이다.

여기에 고전 ML에서 사용했던 메타 피처를 붙였다.

즉, 모델이 다음 두 종류의 정보를 함께 보도록 구성했다.

트랜스포머 표현: history와 current_prompt의 문맥
메타 피처: 세션 상태, action 통계, 열린 파일, 키워드 신호
 

결과는 다음과 같았다.

v10 holdout: 0.6519
v10 LB:      0.6334
 

고전 ML 최고 LB였던 0.6179를 넘겼다.

즉, 메타 피처와 함께 맥락을 활용하는 접근이 제일 유효했던 것으로 어느 정도 예측했던 결과였다.


v11: 고전 ML 모델들과 함께 사용하기

v10에서 트랜스포머와 메타 피처를 결합한 하이브리드 모델이 고전 ML 최고점을 넘었다.

v7 고전 ML blend LB: 0.6179
v10 hybrid LB:      0.6334
 

다음으로 확인하고 싶었던 것은 단순했다.


v10 하이브리드 모델이 기존 고전 ML 모델을 완전히 대체할 수 있는지, 아니면 둘을 함께 사용할 여지가 있는지였다.

고전 ML 단계에서 사용하던 모델은 다음 세 가지였다.

HistGradientBoosting
LogisticRegression
ComplementNB
 

이 모델들은 TF-IDF, action 통계, 메타 피처처럼 비교적 명시적인 신호에 강했다.
반면 v10 하이브리드 모델은 RoBERTa를 통해 history와 current_prompt의 문맥을 더 직접적으로 반영할 수 있었다.

 

두 모델 계열이 보는 정보가 다르기 때문에, 틀리는 샘플도 다를 가능성이 있다고 봤다.
그래서 먼저 holdout 14,000개를 기준으로 고전 3모델 블렌드와 v10 하이브리드 모델의 정답 여부가 얼마나 겹치는지 확인했다.

결과는 다음과 같았다.

구분                                                                                                                                     비율
둘 다 맞음 53.5%
둘 다 틀림 24.7%
고전 ML만 맞음 8.9%
하이브리드만 맞음 12.9%

여기서 중요한 부분은 고전 ML만 맞음과 하이브리드만 맞음이었다.

하이브리드 모델이 고전 ML보다 전체적으로 더 강했지만, 고전 ML만 맞힌 샘플도 8.9% 존재했다.
반대로 하이브리드만 맞힌 샘플은 12.9%였다.

 

즉, v10 하이브리드가 고전 ML을 완전히 대체한 것은 아니었다.

이 결과를 보고 두 모델 계열을 결합해볼 근거가 있다고 판단했다.

 

v11에서는 고전 ML 모델들의 예측 확률과 v10 하이브리드 모델의 예측 확률을 다시 입력으로 사용했다.
최종 예측은 LogisticRegression 메타러너가 수행하도록 구성했다.

 

구조는 대략 다음과 같다.

고전 ML 모델들의 예측 확률
+
하이브리드 트랜스포머의 예측 확률
        ↓
LogisticRegression 메타러너
        ↓
최종 예측
 

결과는 다음과 같았다.

v11 holdout: 0.7006
v11 LB:      0.6849
 

v10 단일 모델보다 큰 폭으로 상승했다.

 

이 결과는 두 모델 계열이 서로 다른 강점을 가지고 있었기 때문으로 해석했다.
고전 ML은 명시적인 키워드, action 통계, 상태 피처에 강했고, 하이브리드 트랜스포머는 대화 문맥을 더 잘 반영했다.

실제 holdout에서도 두 모델이 서로 다른 샘플을 맞히는 영역이 확인되었고, 스태킹은 그 차이를 활용하는 방식이었다.


정리

고전 ML 기반 최고 기록은 다음과 같았다.

v7 holdout: 0.6089
v7 LB:      0.6179

트랜스포머를 도입한 첫 목표는 고전 ML에서 정체된 탐색 계열 클래스의 문맥 문제를 더 잘 다루는 것이었다.

처음에는 텍스트만 입력하는 방식으로 시작했지만, 기대만큼 성능이 나오지 않았다.
이후 고전 ML에서 효과가 있었던 메타 피처를 다시 결합했고, v10에서 성능이 개선되었다.

v10 holdout: 0.6519
v10 LB:      0.6334

이후 고전 ML 모델들과 하이브리드 트랜스포머를 스태킹하면서 더 큰 상승이 있었다.

v11 holdout: 0.7006
v11 LB:      0.6849

 

고전 ML에서 얻은 교훈은 트랜스포머 단계에서도 그대로 이어졌다.


이번 문제는 문장 의미만 보는 문제가 아니라, 세션의 흐름과 상태를 함께 봐야 하는 문제였다.

다음 글에서는 모델 성능과 별개로, 실제 대회 서버에서 제출 코드가 끝까지 실행되도록 만들기 위해 겪었던 문제들을 정리할 예정이다.