LLM 서빙 · 평가와 회귀 방지 · 실습
응답 품질 회귀 테스트 하네스 만들기
목표
평가 하네스를 처음부터 만들어 품질·지연을 함께 재고, 기준선 대비 회귀를 자동으로 판정하는 CI 게이트까지 완성한다.
왜 중요한가
평가 하네스 없이 모델이나 프롬프트를 바꾸는 것은 테스트 없이 리팩터링하는 것과 같습니다. 몇 개 물어보고 "좋아진 것 같다"로 결정한 뒤, 2주 지나 특정 유형에서 품질이 떨어졌다는 문의를 받고, 되돌릴지 판단할 근거가 없는 상황이 반복됩니다. LLM 출력이 결정적이지 않아 완벽한 평가는 불가능하지만, 회귀를 잡을 만큼은 충분히 잴 수 있습니다. 이 실습에서 특히 중요한 것이 5번 스텝입니다 — 품질만 재면 절반입니다. 품질이 2퍼센트포인트 좋아졌는데 지연이 두 배가 됐다면 그것은 개선이 아닙니다. 그리고 7번 스텝의 CI 게이트가 이 모든 것을 실제로 작동하게 만듭니다. 사람이 기억해서 돌리는 평가는 결국 안 돌아갑니다.
단계
1. /opt/fixtures/llms/evalset.jsonl(40건, 각 줄에 id, prompt, expected, grader)를 읽어 /root/ev/loaded.txt 에 cases=40 graders=<쉼표로 이은 종류> 를 적는다.
2. /root/ev/run.py 로 전 케이스를 8170 서버에 실행해 /root/ev/results.jsonl 을 만든다. 각 줄에 id, output, latency_ms 가 있어야 하고 40줄이어야 한다.
3. grader 가 exact 인 케이스를 정확 일치로 채점한다. /root/ev/exact.txt 에 cases=<n> passed=<n> score=<0~1 소수> 를 적는다.
4. grader 가 contains 인 케이스를 키워드 포함 비율로 채점한다. /root/ev/contains.txt 에 같은 형식으로 적고 score 는 0 이상 1 이하여야 한다.
5. 지연 SLO 를 800ms 로 두고 위반 건수를 센다. /root/ev/latency.txt 에 slo_ms=800 violations=<n> p99_ms=<수> 를 적는다.
6. 전체 점수를 /root/ev/baseline.json 에 {"score":<수>,"p99_ms":<수>,"cases":40} 로 저장한다. 그다음 /root/ev/compare.py 로 새 실행 결과를 기준선과 비교해 /root/ev/regression.txt 에 baseline=<수> current=<수> delta=<부호 있는 수> verdict=<PASS|FAIL> 을 적는다. 임계는 -0.03 이다.
7. /root/ev/gate.sh 는 회귀면 종료 코드 1, 아니면 0 으로 끝난다. 두 경우를 모두 시험해 /root/ev/gate.out 에 pass_exit=0 fail_exit=1 을 적는다.
참고
- 127.0.0.1:8170 의 백엔드는 이 파드에 미리 떠 있지 않습니다.
POST /generate에{"prompt":..., "max_tokens":n}을 받아{"text":..., "usage":{...}}를 돌려주면 되므로, 앞선 토큰 스트리밍 실습에서 만든 서버를 그대로 쓰거나 같은 계약의 최소 서버를 직접 띄우고 시작하세요. 회귀를 만들어 보려면 품질을 바깥에서 바꿀 수 있는 손잡이를 하나 두는 편이 편합니다. - 평가셋은 실제 트래픽 분포를 반영해야 합니다. 잘 되는 케이스만 모으면 회귀를 못 잡습니다.
- 임계는 노이즈보다 커야 합니다. 3퍼센트포인트가 출발점이고 평가셋이 작으면 더 커야 합니다.
- 사용자 문의로 발견된 실패 케이스를 평가셋에 추가하는 루프를 만들면 같은 실패가 두 번 나지 않습니다.
- 흔한 실수 1: 품질만 재고 지연과 비용을 빼먹는 것.
- 흔한 실수 2: 하네스를 만들어 두고 CI 에 넣지 않는 것 — 사람이 기억해서 돌리는 평가는 결국 안 돌아갑니다.
단계 7개
- 평가셋 불러오기
- 러너로 전 케이스 실행하기
- 정확 일치 채점하기
- 부분 점수 채점하기
- 지연 SLO 위반 세기
- 기준선 저장하고 회귀 판정하기
- CI 게이트 스크립트 만들기