모델은 프롬프트를 지켰는데 점수가 깎일 때
TL;DR
- SFT 오답의 일부는 학습 실패가 아니라 프롬프트 ↔ 채점기 계약 불일치다.
- 기대 스키마 / 시스템 프롬프트 / 채점기 세 장치가 같은 말을 해야 한다.
- 출력이 프롬프트에 충실하면, 먼저 점수를 고치지 말고 계약을 고친다.
- 그다음에야 데이터·재학습이다. 순서를 뒤집으면 실험을 태운다.
들어가며
1편에서 시험지를 갈랐고, 2편에서 라벨 축을 봤다.
그래도 남는 “억울한” 케이스가 있다. 모델 출력을 보면 프롬프트 그대로인데, 채점표에선 감점이다.
이 글의 결론을 먼저 말하면: 그건 종종 모델 문제가 아니다.
1. 세 장치가 같아야 한다
| 장치 | 역할 |
|---|---|
| 기대 스키마 | “무엇이 정답 형태인가” (문서·표) |
| 시스템 프롬프트 | 모델에게 주는 규칙 |
| 채점기 | 자동 점수 (F1, 규칙위반 등) |
셋 중 하나만 다른 세대를 쓰면, “학습이 망했다” 착각이 난다.
2. 불일치 예시 (설명용)
| 상황 | 프롬프트 | 채점 기대 | 모델 출력 | 누가 틀렸나 |
|---|---|---|---|---|
| 특수 표현 A | free_text로 남겨라 |
구조화 type이어야 함 | free_text |
채점/스키마 |
| 기간 없는 “신규 사용자” | 기간 없으면 free_text |
다른 구조화 type | free_text |
계약 |
| 금지 축 | E-* 쓰지 마라 |
E-*면 형식위반 |
E-* |
모델(또는 라벨 #2) |
표에서 보이듯, 위 두 줄은 재학습보다 한 줄 합의가 먼저다.
3. 판별법 (30분짜리)
- 실패 케이스의 시스템 프롬프트 원문을 연다.
- 모델 출력이 그 문장을 문자 그대로 따르는지 표시한다.
- 채점기 규칙(또는 기대 JSON)과 충돌 문장을 하이라이트한다.
- 충돌이 있으면 → 스키마 문서에 “정답 정의”를 한 줄로 고정한다.
- 그 한 줄에 맞춰 프롬프트·라벨·채점기를 같은 커밋/같은 날에 맞춘다.
출력이 프롬프트를 어겼으면 #1·#2로 돌아간다.
출력이 프롬프트를 지켰으면 재학습 티켓을 열지 않는다.
4. 고치는 순서
기대 스키마 합의
→ 프롬프트 수정
→ 라벨 재생성/패치 (필요 시)
→ 채점기 동기화
→ 같은 세트로 재측정
→ (그제야) 재학습
| 먼저 | 나중 |
|---|---|
| 용어·타입 라우팅 표 | epoch, lr, 데이터 10배 |
| 채점기 fixture 업데이트 | 새 베이스 모델 |
| “이 표현은 free_text” 문서화 | 어댑터 이름만 바꾸기 |
5. 시리즈 마무리
| 편 | 한 줄 |
|---|---|
| #1 | 시험지와 loss로 원인을 가른다 |
| #2 | 라벨 slot 축을 감사하고 마이그레이션한다 |
| #3 | 프롬프트·채점기·스키마 계약을 맞춘 뒤 학습한다 |
SFT는 “더 돌리면” 나아지기 전에, 무엇을 정답이라 부르는지가 같아야 한다.
계약이 흔들리면 GPU만 돈다.
시리즈
- SFT 결과가 이상할 때 — holdout·스트레스·loss로 먼저 가르기
- 학습 라벨의 slot 축이 추론을 다시 발명한다
- 모델은 프롬프트를 지켰는데 점수가 깎일 때 (이번 글)
Comments