다중 실행 평가
다중 실행 평가 (Multi-Run Evaluation)
각 케이스를 여러 번 실행해서 변동성을 측정하고 더 신뢰할 수 있는 집계 결과를 얻어요.
AI 시스템은 본질적으로 확률적이에요. 같은 입력이 실행마다 다른 출력을 만들 수 있죠. repeat 매개변수를 쓰면 각 케이스를 여러 번 실행하고 결과를 자동으로 집계해서, 시스템의 전형적인 동작을 더 명확하게 볼 수 있어요.
출처: 문서
본문
기본 사용법
evaluate() 또는 evaluate_sync()에 repeat를 전달해요:
from pydantic_evals import Case, Dataset
dataset = Dataset(
name='multi_run_basic',
cases=[
Case(name='greeting', inputs='Say hello'),
Case(name='farewell', inputs='Say goodbye'),
]
)
def task(inputs: str) -> str:
return inputs.upper()
# 각 케이스를 5번 실행
report = dataset.evaluate_sync(task, repeat=5)
# 2 케이스 × 5 반복 = 총 10회 실행
print(len(report.cases))
#> 10
repeat > 1이면 각 실행은 greeting [1/5], greeting [2/5] 등과 같은 인덱스 이름을 얻고, 원래 케이스 이름은 그룹핑을 위해 source_case_name에 보존돼요.
그룹화된 결과 접근
case_groups()를 사용해 원래 케이스별로 구성된 실행에 접근하고, 그룹별 집계 통계를 얻어요:
from pydantic_evals import Case, Dataset
dataset = Dataset(
name='grouped_results',
cases=[
Case(name='greeting', inputs='Say hello'),
Case(name='farewell', inputs='Say goodbye'),
]
)
def task(inputs: str) -> str:
return inputs.upper()
report = dataset.evaluate_sync(task, repeat=3)
groups = report.case_groups()
assert groups is not None # 단일 실행(repeat=1)에서는 None
print(len(groups))
#> 2
group_names = [g.name for g in groups]
print(group_names)
#> ['greeting', 'farewell']
# 각 그룹에는 3번의 실행과 집계 통계가 있음
for group in groups:
assert len(group.runs) == 3
assert len(group.failures) == 0
assert group.summary.task_duration > 0
각 ReportCaseGroup은 다음을 담아요:
name-- 원래 케이스 이름runs-- 개별ReportCase결과들failures-- 예외를 던진 실행들summary-- 평균 점수, 메트릭, 라벨, 판정, 기간을 담은ReportCaseAggregate
집계
repeat > 1이면 보고서의 averages()는 두 수준 집계 전략을 사용해요:
- 그룹별 평균: 각 케이스의 실행들이 그룹 요약으로 평균화돼요
- 그룹 간 평균: 그룹 요약들이 평균화되어 최종 결과를 만들어요
이렇게 하면 성공하거나 실패한 실행 수와 관계없이 각 원래 케이스가 전체 평균에 동등하게 기여해요.
from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import EqualsExpected
dataset = Dataset(
name='aggregation',
cases=[
Case(name='easy', inputs='hello', expected_output='HELLO'),
Case(name='hard', inputs='world', expected_output='WORLD'),
],
evaluators=[EqualsExpected()],
)
def task(inputs: str) -> str:
return inputs.upper()
report = dataset.evaluate_sync(task, repeat=3)
averages = report.averages()
assert averages is not None
print(f'Overall assertion rate: {averages.assertions}')
#> Overall assertion rate: 1.0
기본 동작
repeat=1(기본값)이면 동작은 표준 평가와 동일해요. 실행 인덱싱도, source_case_name도 없고 case_groups()는 None을 반환해요:
from pydantic_evals import Case, Dataset
dataset = Dataset(name='default_behavior', cases=[Case(name='test', inputs='hello')])
def task(inputs: str) -> str:
return inputs.upper()
report = dataset.evaluate_sync(task) # 기본적으로 repeat=1
assert report.case_groups() is None
assert all(c.source_case_name is None for c in report.cases)
다음 단계
- 동시성 & 성능 -
max_concurrency로 병렬 실행 제어 - 메트릭 & 속성 - 실행 전반에 걸쳐 커스텀 메트릭 추적
- Logfire 통합 - 다중 실행 결과 시각화
더 알아보기 (Learn more)
- Pydantic Evals 문서: 다중 실행 평가