개념
왜 응답 시간 하나로는 안 되는가
모듈 16 레슨 2~3에서 부하 테스트를 배웠다. 요청을 보내고 응답까지 걸린 시간의 백분위수를 보는 방식이었다. LLM 추론 엔드포인트에 그대로 쓰면 결함을 놓친다. LLM 응답은 스트리밍 으로 토큰이 하나씩 나오고, 요청마다 입력 길이와 출력 길이가 크게 다르다. 출력 1,000토큰짜리 요청이 20초 걸린 것과 출력 20토큰짜리가 20초 걸린 것은 전혀 다른 성능이다.
그래서 추론 성능은 단계별 지표 로 나눠 본다.
| 지표 | 정의 | 사용자 체감 | 주로 좌우하는 것 |
|---|---|---|---|
| TTFT (Time To First Token) | 요청 전송부터 첫 토큰 도착까지 | "답이 시작되기까지 기다림" | 대기열, 입력 처리(prefill), 콜드 스타트 |
| TPOT (Time Per Output Token) | 첫 토큰 이후, 출력 토큰 하나당 평균 시간. 요청마다 계산 후 집계 | "글이 써지는 속도" | 디코드 단계 배치 크기, 메모리 대역폭 |
| ITL (Inter-Token Latency) | 연속된 두 토큰 사이 지연 (토큰마다) | "중간에 멈칫함" | 배치에 새 요청이 끼어들 때의 간섭 |
| E2EL (End-to-End Latency) | 요청 전송부터 마지막 토큰까지 | 전체 대기 | 위 모두 + 출력 길이 |
| 처리량 | 초당 출력 토큰 수, 초당 완료 요청 수 | (운영 비용) | 배치 효율 |
TPOT와 ITL의 차이가 중요하다. TPOT는 요청 하나의 평균 이라 중간에 2초 멈춘 요청도 평균에 묻힐 수 있다. ITL 백분위수는 그 멈춤을 드러낸다. 채팅형 서비스에서 사용자가 "끊긴다"고 느끼는 것은 대개 ITL 꼬리다.
goodput — SLO를 지킨 요청만 센다
처리량을 올리는 가장 쉬운 방법은 배치를 키우는 것이다. 그러면 TTFT와 ITL이 나빠진다. 처리량 하나만 기준으로 두면 사용자가 못 견디는 속도로 많이 처리하는 설정이 최고 점수를 받는다.
goodput 은 이 문제를 막는다. 정해 둔 지연 기준(예: TTFT 800ms 이하 그리고 TPOT 50ms 이하)을 모두 만족한 요청만 세서 초당 몇 건인지 본다.
vLLM의 벤치마크 도구는 --goodput ttft:800 tpot:50 처럼 지표별 밀리초 기준을 받아 goodput을 계산한다.
[같은 GPU, 두 설정 비교 — 요청률 12 req/s]
처리량(tok/s) TTFT p95 TPOT p95 goodput(req/s, TTFT≤800 & TPOT≤50)
설정 A (큰 배치) 4,900 2,300ms 41ms 6.1
설정 B (작은 배치) 4,100 610ms 38ms 11.4처리량만 보면 A가 이기고, goodput으로 보면 B가 거의 두 배다. 추론 성능 기준은 goodput을 1차 지표로 쓰고 처리량은 비용 참고로 둔다. 모듈 14 레슨 7의 SLI·SLO가 성능 시험 설계에 그대로 들어온다.
부하의 모양을 설계한다
추론 성능 결과는 부하 모양에 극도로 민감하다. 같은 서버도 부하를 어떻게 보내느냐에 따라 결과가 몇 배 달라진다. 설계할 축은 넷이다.
| 축 | 선택지 | 결과에 주는 영향 |
|---|---|---|
| 도착 방식 | 한 번에 모두 / 일정 간격 / 포아송 / 폭주(burst) | 한 번에 모두 보내면 TTFT가 대기열 시간으로 폭증 |
| 요청률 vs 동시성 | 초당 N건 도착 / 동시 N개 유지 | 요청률 방식은 서버가 느려지면 대기열이 쌓이고, 동시성 방식은 서버 속도에 맞춰 자동으로 늦춰져 과부하를 숨긴다 |
| 입력·출력 길이 분포 | 고정 길이 / 실제 로그 분포 | 긴 입력 몇 개가 TTFT 꼬리를 만든다 |
| 데이터 | 무작위 토큰 / 실제 대화 데이터셋 | 무작위 토큰은 접두사 캐시 효과를 없애 실제보다 나쁘거나, 출력이 조기 종료되어 실제보다 좋게 나온다 |
vLLM 벤치마크 도구에서 이 축들은 옵션으로 나온다. --request-rate 에 무한대를 주면 모든 요청을 0초에 보내고, --burstiness 가 1이면 포아송 도착,
1보다 작으면 더 몰리고 크면 더 고르게 도착한다. --max-concurrency 로 동시성 상한을 걸고, --percentile-metrics 로 백분위수를 볼 지표를 고른다.
요청률 방식과 동시성 방식의 차이 는 반드시 기준 문서에 적는다. 동시성 고정 시험은 "서버가 버틸 만큼만 보낸다"는 뜻이라 운영의 급증을 재현하지 못한다. 사용자는 서버 속도에 맞춰 요청을 늦춰 주지 않는다. 용량 판정은 요청률 방식으로, 특정 동시 사용자 수의 체감 확인은 동시성 방식으로 나눈다.
GuideLLM은 이 탐색을 자동화한다. 스윕(sweep) 프로필은 먼저 요청을 하나씩 보내는 동기 기준선을 재고, 모든 요청을 병렬로 보내 최대 처리량을 추정한 뒤, 그 사이를 일정 간격의 고정 요청률 여러 단계로 나눠 각각의 지연을 측정한다. 결과는 "요청률이 올라갈 때 TTFT·ITL이 어디서 꺾이는가"를 보여주는 곡선이다.
[스윕 결과 읽기 — 개념]
요청률(req/s) 1 4 7 10 13 16
TTFT p95(ms) 210 240 300 520 1,900 6,800 ← 13 에서 꺾임
ITL p95(ms) 22 24 27 33 61 140
goodput 1 4 7 9.8 6.2 1.1
판정: SLO(TTFT≤800, ITL≤50)를 지키는 최대 요청률 ≈ 10 req/s → 이 인스턴스의 용량 기준이 용량 숫자가 오토스케일 기준과 쿼터 판매 기준의 입력이 된다.
MLPerf 결과를 읽는 법
AI 인프라 영업·조달 자료에는 MLPerf Inference 결과가 자주 등장한다. MLCommons가 운영하는 업계 표준 벤치마크이고, 2026년 4월 v6.0 결과가 발표됐다. QA가 알아야 할 것은 결과가 어떤 조건의 숫자인가 다.
| 시나리오 | 부하 | 판정 지표 |
|---|---|---|
| Offline | 데이터 전체를 한 번에, 지연 제약 없음 | 최대 처리량 |
| Server | 포아송 도착, 지연 제약 있음 (LLM이면 TTFT·TPOT 기준) | 지연 제약을 지키는 최대 처리량 |
Offline 숫자는 배치 처리 용량이고 대화형 서비스 용량이 아니다. 고객 제안서에 Offline 숫자로 대화형 엔드포인트 용량을 약속하면 운영에서 SLO를 못 지킨다. 또 MLPerf는 정해진 모델·데이터셋·정확도 목표 에서의 결과라, 고객이 올릴 모델과 입력 분포에서는 우리 시험으로 다시 재야 한다. 벤더 발표를 그대로 옮기지 않는다는 이 커리큘럼의 원칙이 여기서도 적용된다.
추론 성능 기준을 판정 가능하게 쓰기
모듈 38 레슨 1의 다섯 칸으로 쓰면 이렇다.
대상: 추론 엔드포인트 템플릿 llm-8b-instruct, gpu.h100.1, 서빙 런타임 버전 고정
조건: 입력 길이 실제 로그 분포(중앙 900, p95 3,800 토큰), 출력 최대 512
포아송 도착 10 req/s, 10분 유지, 워밍업 2분 제외
관찰: 클라이언트 측 TTFT·ITL·E2EL 백분위수, 서버 측 대기열 길이·KV 캐시 사용률, 오류 응답
판정: 통과 = TTFT p95 ≤ 800ms, ITL p95 ≤ 50ms, 오류율 ≤ 0.1%, goodput ≥ 9.5 req/s
실패 = 하나라도 벗어남
근거: 상품 사양서 v2 §3 (8B 모델 표준 엔드포인트 SLO), 용량 스윕 2026-09-10 결과클라이언트 측과 서버 측을 모두 관찰하는 이유가 있다. 서버 지표만 보면 게이트웨이·인증·네트워크 구간의 지연이 빠진다. 클라이언트 지표만 보면 느려진 원인이 대기열인지 연산인지 모른다. 부하 생성기 자체가 병목이 되지 않았는지도 확인한다. 부하 생성기의 CPU가 가득 차면 도착 간격이 늘어져 실제보다 좋은 결과가 나온다.
오토스케일과 콜드 스타트
추론 플랫폼은 트래픽에 따라 복제본을 늘리고 줄인다. 오토스케일은 성능 결함의 새 원천이다.
| 검증 | 기준 예 |
|---|---|
| 확장 반응 시간 | 요청률이 용량의 150%로 급증한 뒤 새 복제본이 트래픽을 받기까지 N분 이하 |
| 확장 중 SLO | 확장 완료까지의 구간에서 오류율·TTFT 꼬리가 허용 한도 안 (대기열 한도·빠른 거절 정책 확인) |
| 콜드 스타트 | 0에서 1로 늘 때 첫 요청 TTFT — 모델 가중치 다운로드·GPU 로딩 시간 포함, 문서 값과 일치 |
| 준비 판정 | 모델 로딩이 끝나기 전에 준비(readiness)로 표시되어 트래픽을 받지 않는가 |
| 축소 | 축소 시 진행 중인 스트리밍 응답이 끊기지 않는다 (종료 유예 시간 안에 완료) |
| 진동 | 부하가 기준선 근처에서 오르내릴 때 복제본이 반복해서 늘었다 줄었다 하지 않는다 |
| 지표 선택 | 확장 기준이 GPU 사용률만이 아니라 대기열 길이·동시 요청 수 같은 사용자 영향 지표를 반영 |
준비 판정 은 가장 흔한 결함이다. 컨테이너가 떴다고 준비로 표시하면 모델을 로딩 중인 복제본이 요청을 받아 몇십 초씩 첫 토큰을 못 준다. 레슨 2의 "status를 믿어도 되는 시점"이 추론 서빙에서는 준비 프로브가 무엇을 확인하는가 로 바뀐다.
GPU 사용률만으로 오토스케일하면 LLM 서빙에서 오동작하기 쉽다. 연속 배치(continuous batching)를 쓰는 서버는 사용률이 높게 유지되면서도 대기열이 쌓일 수 있고, 반대로 사용률이 여유 있어도 KV 캐시 메모리가 한계일 수 있다.
모델·런타임 교체 회귀
추론 플랫폼은 서빙 런타임 버전, 양자화 방식, 모델 버전이 자주 바뀐다. 교체마다 성능과 품질 두 축 의 회귀를 판정한다.
[런타임 업그레이드 회귀 판정 — 템플릿별]
성능 같은 부하 모양·같은 데이터로 이전·새 버전 측정
goodput 5% 이상 하락 → 실패 / TTFT·ITL p95 10% 이상 악화 → 실패
측정은 교대로 3회씩, 차이가 측정 변동보다 큰지 확인 (모듈 31 레슨 4)
품질 같은 프롬프트 세트에서 출력 비교
결정적 판정: 구조화 출력(JSON) 파싱 성공률, 도구 호출 형식, 최대 길이 준수
해석 판정: 기준 답변 대비 품질 — 보정된 판정자 (모듈 38 레슨 3)
양자화 변경 시: 과제 정확도 지표를 이전 대비 허용 하락폭 안성능만 보고 교체하면 양자화로 빨라졌지만 JSON 출력이 깨지는 회귀를 놓친다. 품질만 보면 같은 답을 내지만 ITL 꼬리가 두 배가 된 회귀를 놓친다. 모듈 18b 레슨 5의 비결정적 출력 통계 검증과 모듈 36 레슨 3의 분류 성능 평가가 품질 축의 도구다.
실무에서 왜 필요한가
AI 추론 플랫폼의 고객은 "초당 토큰 수"가 아니라 "우리 서비스 사용자가 답을 기다리는 시간"으로 품질을 느낀다. 처리량만 보고 설정을 고르거나, 동시성 고정 시험으로 용량을 약속하거나, 준비 프로브가 모델 로딩을 확인하지 않는 결함은 모든 기능 테스트를 통과한 상태로 고객 SLO 위반을 만든다.
우대사항의 "성능/부하/신뢰성 테스트 경험"은 AI 플랫폼에서 이 지표 체계로 다시 해석된다. k6·JMeter 경험이 있는 QA는 부하 설계 감각이 이미 있으므로, TTFT·ITL·goodput과 요청률·동시성의 차이만 익히면 빠르게 전환할 수 있다. 면접에서는 "처리량이 좋은 설정을 goodput으로 다시 비교해 기각했다", "오토스케일 중 준비 프로브 결함으로 TTFT 꼬리가 폭증한 것을 찾았다" 같은 이야기가 힘을 갖는다.