지난 글에서 회귀를 세려면 문제별 결과를 짝지어야 한다고 했다. 그 짝의 왼쪽에 놓이는 것이 골든 데이터셋이다 — 정답과 채점 기준까지 붙여 두고, 모델이나 프롬프트를 바꿀 때마다 같은 자로 쓰는 문제 묶음을 그렇게 부른다.
여기에는 좀 불편한 사실이 하나 있다. 평가 세트의 품질이 평가의 상한이라는 것. 세트가 실제 사용자와 안 닮았으면 그 위에서 아무리 정교하게 재도 재는 것은 다른 세계다. 그래서 이 일은 스크립트를 짜는 일이 아니라 사람이 읽고 정하는 일이 된다.
어디서 뽑나
출처는 셋이고 값이 다르다.
| 출처 | 좋은 점 | 조심할 것 |
|---|---|---|
| 운영 로그 | 진짜 분포다. 인터넷에 없어 오염되지 않았다 | 개인정보를 지워야 하고, 정답이 없다 |
| 사람이 쓴 문제 | 드문 상황을 일부러 만들 수 있다 | 실제로 안 오는 질문을 지어내기 쉽다 |
| 모델이 만든 문제 | 싸고 빠르게 늘릴 수 있다 | 그 모델이 잘하는 쪽으로 치우친다 |
기본은 운영 로그다. 아직 서비스를 안 열어 로그가 없다면 사람이 쓰되, 그 세트는 문을 연 뒤에 반드시 갈아 끼운다고 적어 둔다. 지어낸 질문과 실제로 오는 질문은 늘 다르고, 그 차이는 로그를 보고 나서야 알게 된다.
모델이 만든 문제는 세트를 처음 만들 때보다 이미 있는 갈래를 늘릴 때 쓸 만하다. 실제 질문 다섯 개를 주고 같은 성격의 변형을 만들게 하는 식이다. 처음부터 모델에게 다 맡기면, 그 모델이 상상하는 사용자상이 그대로 평가 세트가 된다.
로그에서 세트까지
40만 건짜리 로그가 있다고 하자. 여기서 300건을 고르는 길은 네 단계다.
첫 단계에서 지우는 것은 개인정보, 그리고 평가에 못 쓰는 대화다. 「안녕하세요」 한 줄, 오타를 고쳐 다시 물은 같은 질문, 사용자가 도중에 나가 버려 무엇을 원했는지 알 수 없는 것들이다. 원본을 지우지 말고 거른 결과를 따로 쓰는 것이 중요하다. 거르는 조건은 나중에 반드시 한 번 이상 바뀐다.
중복 제거가 두 번째다. 실무에서 이 단계를 건너뛰면 세트가 조용히 망가진다. 「배송 언제 와요」 같은 질문은 수천 벌이 거의 같은 문장으로 들어와 있어서, 그대로 무작위로 뽑으면 300건 중 200건이 그 질문의 변형이 된다.
비율을 그대로 베끼지 않는다
세 번째가 이 일의 핵심이다. 로그의 갈래 비율을 그대로 옮기면 드문 갈래가 사실상 사라진다.
층화 표집은 데이터를 갈래로 나눈 뒤 갈래마다 정해진 수만큼 뽑는 방법이다. 위 그림에서 규정 문의는 로그의 3%인데 골든셋에서는 20%를 차지한다. 자주 오는 질문이라서가 아니라 틀렸을 때 비싼 질문이기 때문이다.
자리를 나누는 기준으로 셋을 함께 본다.
- 얼마나 자주 오는가 — 흔한 갈래를 아예 빼면 평균 점수가 현실과 멀어진다
- 틀리면 얼마나 비싼가 — 환불 규정을 잘못 말하는 것과 인사말이 어색한 것은 무게가 다르다
- 지금 얼마나 못하는가 — 이미 100점인 갈래에 60자리를 주면 그 60자리는 아무것도 못 잰다
세 번째 기준이 자주 빠진다. 평가 세트는 모델이 흔들리는 자리에 자리를 많이 줘야 정보가 나온다. 전부 맞히는 문제와 전부 틀리는 문제는 어느 쪽도 변화를 감지하지 못한다.
다만 이렇게 뽑고 나면 전체 평균은 실제 서비스 품질이 아니게 된다. 어려운 문제를 일부러 많이 넣었으니 당연하다. 그래서 골든셋 점수는 갈래별로 읽고, 서비스 전체 품질이 궁금하면 비율을 안 건드린 별도 표본을 작게 하나 더 둔다.
정답을 붙인다
마지막 단계가 가장 비싸고 가장 자주 대충 넘어간다. 사람이 한 건씩 읽고 붙여야 하기 때문이다.
정답의 모양은 문제 성격이 정한다.
| 문제 성격 | 정답으로 저장하는 것 | 채점 |
|---|---|---|
| 분류·추출 | 정해진 값 하나 | 문자열 비교 |
| 사실 질의 | 반드시 들어가야 할 사실 목록 | 항목별 포함 여부 |
| 긴 답변 | 모범 답안 + 채점 기준 | 사람 또는 모델 채점 |
| 도구 호출 | 불러야 할 도구와 인자 | 호출 기록 비교 |
세 번째 줄이 어렵다. 긴 답변에는 정답이 하나가 아니라서 모범 답안 한 벌만 저장하면 그것과 다른 좋은 답이 전부 오답이 된다. 그래서 모범 답안 옆에 무엇이 있어야 맞는 답인지를 항목으로 적어 둔다.
한 사람이 혼자 다 붙이지 않는 것도 중요하다. 적어도 일부는 두 사람이 각자 붙여 보고 얼마나 갈리는지 센다. 두 사람이 30%에서 갈린다면 그 문제는 모델이 못 맞히는 것이 아니라 애초에 답이 정해지지 않은 것이다. 그런 문제는 기준을 다시 쓰거나 세트에서 뺀다.
얼마나 커야 하나
「몇 개면 되나」라는 질문에는 세트 전체가 아니라 갈래 하나에 몇 개인가로 답해야 한다. 갈래별 점수를 보고 판단할 것이므로 의미 있는 단위는 갈래다.
- 갈래당 30건 아래면 점수가 몇 점씩 튀어 회귀와 잡음을 못 가른다
- 갈래당 50~100건이면 대부분의 판단에 쓸 만하다
- 갈래 여덟 개면 전체가 400~800건이 되고, 사람이 정답을 붙이기에 이미 큰 일이다
작게 시작해서 늘리는 편이 낫다. 갈래 다섯에 갈래당 40건, 총 200건이면 첫 세트로 충분하다. 여기서 갈래별 점수를 보면 어느 갈래에 자리가 더 필요한지가 저절로 드러난다.
동결하고, 가끔 갈아 끼운다
세트가 완성되면 버전을 붙이고 더는 손대지 않는다. 문제를 조용히 더하거나 빼면 어제 점수와 오늘 점수를 견줄 수 없게 되고, 그러면 회귀 테스트가 성립하지 않는다.
그렇다고 영원히 그대로 두면 지난 글에서 본 절차 오염이 쌓인다. 같은 200문제를 반년 보면 사람이 그 200문제에 맞춰 프롬프트를 고르게 된다. 그래서 두 가지를 함께 한다.
- 분기마다 새 버전을 낸다. 30%쯤을 최근 로그에서 뽑은 새 문제로 갈아 끼우고, 버전 번호를 올린다
- 갈아 끼우는 날 두 버전을 함께 돌린다. 점수 차이가 얼마인지 기록해 두면 예전 숫자와 이어 읽을 수 있다
정답도 시간이 지나면 틀린다. 반품 기한이 7일에서 14일로 바뀌면 그 갈래의 정답이 전부 오답이 된다. 그래서 정답에 근거를 함께 저장한다 — 어느 규정 문서의 몇 조를 보고 붙였는지. 규정이 바뀔 때 고쳐야 할 문제를 찾아낼 수 있는 유일한 방법이다.
정리
골든 데이터셋을 만드는 일은 데이터 처리가 아니라 판단이다. 무엇을 갈래로 볼지, 어느 갈래에 자리를 얼마나 줄지, 무엇을 맞는 답으로 칠지가 전부 사람이 정하는 것이고, 그 판단이 이후 모든 점수의 뜻을 정한다.
그러니 세트를 만들 때 결정을 함께 적어 둔다. 반년 뒤에 점수가 이상할 때 들여다볼 곳은 모델이 아니라 그 기록이다.
읽어주셔서 감사합니다. 😊

