guest@jyi.app:~/blog— bash
--:--:-- KST
$ cat ./posts/69.md
IT 2026.07.01 · 11 min read

번역·요약 자동 채점, 돌리기 전에 알았어야 했던 것들 (feat. BLEU·ROUGE)

자동 채점: 얼마나 겹치나 참조(reference) vs 가설(hypothesis) 참조 정답지 가설 모델 출력 겹침 공유 단어 BLEU · 정밀도 = 겹침 ÷ 가설 ROUGE · 재현율 = 겹침 ÷ 참조
BLEU는 정밀도(겹침÷가설), ROUGE는 재현율(겹침÷참조) — 같은 겹침을 서로 다른 쪽에서 본다

요즘 번역이든 요약이든 웬만한 건 LLM한테 맡긴다. 문제는 그다음이다. 프롬프트를 한 번 손봤는데, 이게 진짜 좋아진 건지 아니면 그냥 내 기분 탓인지 알 수가 없다. 그렇다고 결과물 수백 건을 사람이 일일이 읽고 점수를 매길 수는 없는 노릇이고. 결국 자동 채점인데, 막상 들여다보니 그냥 돌리면 되는 물건이 아니었다. 어디에 끼우고, 무엇과 비교하고, 나온 숫자를 어떻게 읽어야 하는지 — 삽질하며 배운 것들을 정리한다.

자동 채점은 회귀 테스트 자리에 놓는 물건이다

내가 자동 채점을 두는 자리는 코드의 회귀 테스트와 같은 자리다. 프롬프트나 모델을 바꾸면, 반영하기 전에 정답셋 전체를 채점기에 통과시킨다. 이유는 단순하다. 사람 평가는 느리고 비싸서 변경할 때마다 돌릴 수 없지만, 자동 지표는 몇 분이면 끝나고 언제 돌려도 같은 결과가 나온다. 이 재현성 덕분에 "이번 수정은 좋아진 것 같다"는 느낌이 "점수가 몇 점에서 몇 점이 됐다"는 기록으로 바뀐다.

용어부터 정리하면, 기준이 되는 모범 답안을 참조(reference), 모델이 뱉은 결과물을 가설(hypothesis)이라고 부른다. 원리는 허무할 정도로 단순하다. 이 둘이 n-gram(연속된 단어 묶음)을 얼마나 공유하는지 세는 것이다. 겹치면 고득점, 그게 전부다. 무식해 보이지만 이 단순함이 곧 장점이다. 겹침은 셀 수 있고, 셀 수 있으면 재현되고, 재현되면 비교가 된다.

지표 고르기 — 이 작업에서 최악의 실패는 무엇인가

실무에서 마주치는 두 대장은 BLEU와 ROUGE다. 번역이면 BLEU, 요약이면 ROUGE가 기본값인데, 방향이 갈리는 이유는 작업마다 치명적인 실수가 다르기 때문이다. 번역은 없는 말을 덧붙이는 게 죄니까 정밀도를, 요약은 있는 말을 빠뜨리는 게 죄니까 재현율을 본다. 이 한 문장이 지표 선택의 절반이다.

BLEU — 번역용, 정밀도(precision)

BLEU는 "모델이 뱉은 단어 중에 정답에도 있는 게 얼마나 되나"를 본다. 보통 1~4gram의 수정된 정밀도를 기하평균으로 묶고, 짧게 뱉어서 점수만 챙기는 꼼수를 막으려고 길이 페널티(brevity penalty)를 곱한다. 조심할 점 하나 — BLEU는 코퍼스 단위 지표라서 문장 하나의 점수는 심하게 출렁인다. 문장 하나 점수가 떨어졌다고 프롬프트를 갈아엎는 건, 체중이 아침저녁으로 다르다고 다이어트 방법을 바꾸는 짓이다.

ROUGE — 요약용, 재현율(recall)

ROUGE는 반대로 "정답의 단어 중에 모델이 건진 게 얼마나 되나"를 본다. 요약은 중요한 내용을 빠뜨리지 않는 게 생명이니, 얼마나 많이 건져 올렸는지(재현율)를 보는 게 말이 된다. n-gram 겹침을 보는 ROUGE-N, 최장 공통 부분수열을 보는 ROUGE-L 같은 변형이 있고, 실무에서는 정밀도까지 묶은 F1을 같이 보는 경우도 흔하다.

구분BLEUROUGE
주 용도기계번역요약
핵심 관점정밀도 — 내가 쓴 단어가 정답에 있나재현율 — 정답 단어를 내가 얼마나 건졌나
계산1~4gram 수정 정밀도의 기하평균 × 길이 페널티ROUGE-N(n-gram 겹침)·ROUGE-L(최장 공통 부분수열)
주의코퍼스 단위 — 문장 하나 점수는 불안정재현율만 보면 길수록 유리 → F1 병행

그럼 F1 하나로 묶으면 되지 않나

여기서 찔리는 기억이 하나 있다. 예전에 지원사업을 준비하면서 평가 지표를 찾아볼 때, 다들 F1을 많이 쓴다길래 F1 하나만 알면 되는 줄 알았다. 정밀도와 재현율을 조화평균으로 묶은 게 F1이니 굳이 갈라 볼 이유가 있나 싶었던 것이다. 그런데 작업마다 최악의 실패가 다르다는 걸 알고 나니 거꾸로 보인다. F1은 두 관점을 대등한 무게로 섞겠다는 하나의 선택이지, 선택을 면제해 주는 만능 지표가 아니었다.

그렇다면 번역·요약에 F1을 들이대면 의미 없는 평가일까? 오히려 반대다. 이미 그렇게들 쓴다. ROUGE를 F1으로 보고하는 관행이 그것이고(길게 쓸수록 점수가 오르는 재현율의 편향을 정밀도가 잡아준다), 번역 쪽에도 문자 n-gram의 F-score로 채점하는 chrF 같은 지표가 있다. 다만 조건이 둘 붙는다. 첫째, 무엇에 대한 F1인가. 낱개 단어만 세면 순서가 뒤죽박죽인 문장도 만점이 나오니, n-gram이나 최장 공통 부분수열(LCS)처럼 순서가 반영되는 단위로 세어야 한다. 둘째, F1은 두 방향의 실패를 한 숫자로 뭉갠다. 점수가 떨어졌을 때 없는 말을 지어낸 건지(정밀도 하락) 중요한 걸 빠뜨린 건지(재현율 하락)는 성분을 갈라 봐야 안다. 결국 F1은 두 실패가 비슷하게 치명적인 작업에 쓰는 선택지고, 진단할 때는 정밀도·재현율로 되돌아오게 된다.

같은 자로 재야 비교다 — 조건 못 박기

여기가 제일 많이 틀리는 지점이다. 이 점수들은 같은 조건 안에서의 상대 비교로만 의미가 있다. 토크나이저(한국어라면 형태소 분석기)가 바뀌거나 참조셋이 바뀌면 점수 자체가 달라지기 때문이다. 그래서 프롬프트 v1과 v2를 비교할 때는 참조셋·토크나이저·평가 코드를 전부 고정하고 프롬프트만 바꿔야 한다. 변수를 하나만 남기는 것. 실험의 기본인데, 지표 앞에서는 이상하게 자주 잊는다.

이런 비교판정이유
같은 참조셋·같은 형태소 분석기에서 프롬프트 v1 대 v2의미 있음변수가 프롬프트 하나뿐이다
내 BLEU 32 대 어느 논문의 BLEU 38무의미데이터셋·토크나이저가 다르면 다른 자로 잰 값이다
참조셋을 통째로 바꾸기 전과 후의 점수무의미시험 문제가 바뀌었는데 점수를 이어서 볼 수는 없다

기준선도 여기서 나온다. 절대 점수가 아니라 베이스라인 대비 등락이다. 첫 배포 버전이든 프롬프트 v1이든 기준점을 하나 박아두고, 이후의 모든 변경은 같은 조건에서 채점해 등락만 읽는다. "BLEU 30 넘으면 합격" 같은 절대 기준은 조건마다 의미가 달라져서 세울 수가 없다. 숫자 자체가 아니라 방향과 폭이 정보다.

숫자를 읽을 때 조심할 것

조건을 다 고정해도 남는 한계가 있다. 이 지표들이 보는 건 어디까지나 표면적인 단어 겹침이라서다. 뜻이 같아도 단어가 다르면(동의어·의역) 점수가 짜게 나오고, 반대로 단어만 겹치면 어색한 문장도 점수를 챙겨간다. 점수 하락이 곧 품질 하락이 아니고, 점수 상승이 곧 품질 상승도 아니라는 얘기다.

함정증상대처
동의어·의역 저평가공들인 의역이 감점당한다점수가 급락한 표본은 버리기 전에 직접 읽는다
표면 겹침 과대평가어색한 문장이 점수를 챙긴다고득점 쪽도 표본을 뽑아 스팟체크한다
문장 단위 BLEU문장 하나 점수가 널뛴다코퍼스 단위로만 집계해 읽는다
조건 변경 후 비교이전 점수와 비교가 안 된다조건을 바꿨으면 베이스라인부터 다시 잰다

그래서 나는 점수를 합격 판정이 아니라 회귀 알람으로 쓴다. 점수가 떨어지면 어느 표본에서 떨어졌는지 열어보고, 올랐어도 좋아졌다고 바로 단정하지 않고 표본을 뽑아 눈으로 확인한다. 숫자는 어디를 봐야 하는지 알려주는 표지판이지, 판결문이 아니다.

선 긋기 — 최종 판단은 지표의 몫이 아니다

자동 지표는 빠르고 재현 가능한 1차 필터다. 딱 거기까지다. 최종 품질 판단은 사람 스팟체크나 LLM 심판(LLM-as-judge)을 병행해서 내린다. 순서를 이렇게 두는 이유는 비용 구조 때문이다. 싸고 빠른 지표로 후보를 거르고, 비싸고 느린 사람 평가는 걸러진 소수에만 쓴다. 반대로 두면 사람이 먼저 지치고, 지표만 믿으면 겹침의 함정에 빠진다.

정리 — 결국은 세 가지 결정이다

결정내 기준
지표 선택번역은 BLEU, 요약은 ROUGE(F1 병행)번역은 안 지어내는 게, 요약은 안 빠뜨리는 게 본질이라서
비교 방식조건 고정 + 베이스라인 대비 등락절대 점수는 조건에 종속 — 상대 비교만 유효해서
선 긋기하락 없음 + 스팟체크 통과 후 반영자동 지표는 1차 필터일 뿐, 최종 판단은 사람 몫이라서

자동 채점은 만능 심판이 아니라 빠르고 일관된 1차 필터다. 그래도 나처럼 프롬프트를 계속 갈아엎는 사람한테는, 같은 조건에서 재현되는 숫자 하나가 있느냐 없느냐가 삽질 시간을 꽤 좌우한다. 느낌은 배신해도 기록은 남는다. 고백하자면 나도 처음 점수를 뽑자마자 "그래서 이거, 높은 거야?"부터 물었다. 😅

UTF-8  ·  LF ·  정화된 밤 (Verklärte Nacht) Op.4