벤치마크 방법¶
TL;DR
인코더 모델에는 TTFT와 TPOT가 정의되지 않습니다. 이 벤치마크는 종단 간 지연 시간, 처리량, 배치 효율과 정확도를 함께 측정합니다. 실제 워크로드의 입력 길이가 512로 고정되어 있다면 --pad-to-max 옵션을 사용해야 합니다.
인코더 전용 벤치마크가 필요한 이유¶
sm-endpoint-bmt는 vLLM 기반 디코더 LLM을 대상으로 합니다. 디코더 모델의 생성 과정을 측정하는 지표는 고정 크기 출력을 한 번에 반환하는 인코더 모델에 적용할 수 없습니다.
| 디코더 지표 | 인코더 모델에서의 의미 |
|---|---|
| TTFT (time to first token) | 최초 출력 토큰이 없으므로 정의할 수 없음 |
| TPOT (time per output token) | 출력 토큰을 순차 생성하지 않으므로 정의할 수 없음 |
| ITL (inter-token latency) | 토큰 사이의 간격이 없으므로 정의할 수 없음 |
| Output token throughput | 출력이 고정 크기 logit이므로 정의할 수 없음 |
| E2E latency | 요청부터 응답까지의 종단 간 지연 시간 |
| Request throughput | 초당 처리한 요청 수 |
| Batch efficiency | 배치 크기 증가에 따른 처리량 확장 효율 |
원본 도구는 디코더의 스트리밍 응답을 측정하기 위해 invoke_endpoint_with_response_stream을 사용합니다. 인코더는 스트리밍할 출력이 없으므로 invoke_endpoint를 사용합니다.
부하 생성 로직은 원본 도구의 방식을 유지했습니다. 감마 분포 기반 요청 간격, 요청률 재정규화, 세마포어 기반 동시성 제어는 실행 엔진이나 모델 종류와 관계없이 사용할 수 있습니다.
배치 효율¶
배치 크기 1을 기준으로 샘플 처리량이 얼마나 증가하는지 측정합니다.
배치 효율이 1.0이면 처리량이 배치 크기에 비례해 증가한다는 뜻입니다. 값이 낮아지기 시작하면 연산 자원이 포화되고 있는 것이므로, 이 지점을 배치 정책의 상한을 정하는 기준으로 사용할 수 있습니다.
다음은 mDeBERTa를 GPU에서 실행하고 입력을 실제 문장 길이로 유지한 측정 결과입니다.
| 배치 크기 | samples/s | 배치 크기 1 대비 | 배치 효율 |
|---|---|---|---|
| 1 | 55.2 | 1.00x | 1.00 |
| 8 | 408.6 | 7.40x | 0.93 |
| 32 | 1280.8 | 23.21x | 0.73 |
입력 길이 고정¶
--pad-to-max로 입력 길이 고정
실제 워크로드의 최대 시퀀스 길이가 512로 고정되어 있다면 벤치마크도 같은 조건으로 실행해야 합니다. 실제 문장 길이만 사용하면 워크로드보다 지나치게 낙관적인 결과를 얻을 수 있습니다.
다음은 동일한 03 Inference Component 엔드포인트를 두 조건에서 측정한 결과입니다.
| 조건 | b=1 p50 | b=8 p50 | b=8 samples/s |
|---|---|---|---|
| 실제 입력 길이(토큰 59개) | 23.2 ms | 23.9 ms | 330/s |
max_len=512 고정 |
25.8 ms | 102.8 ms | 78/s |
배치 크기 1에서는 지연 시간 차이가 1.1배지만, 배치 크기 8에서는 처리량 차이가 4.3배로 커집니다. 배치에 포함된 패딩 토큰도 모두 연산하기 때문입니다. 실제 입력 길이로만 측정한 결과를 기준으로 배치 정책을 정하면 필요한 자원을 과소평가할 수 있습니다.
compare_cohost.py는 기본적으로 입력 길이를 512로 고정합니다. benchmark.run에서는 --pad-to-max 옵션을 명시해야 합니다.
정확도 검증¶
지연 시간만 비교하면 정확도가 낮은 구성을 더 좋은 구성으로 판단할 수 있습니다. 실제 측정에서 MiniLM은 mDeBERTa보다 4.5배 빨랐지만 NLI 검증 정확도는 낮았습니다.
| 모델 | 파라미터 | p50 | NLI 정확도 |
|---|---|---|---|
| mDeBERTa | 278M | 15.1 ms | 4/4 |
| MiniLM | 107M | 3.3 ms | 3/4 |
| XLM-R Large | 560M | 10.9 ms | 3/4 |
벤치마크는 성능 지표와 함께 정확도 검증 결과를 출력합니다. 같은 모델이라면 배포 방식이 달라도 판정 결과가 같아야 합니다. 결과가 달라지면 토큰화 또는 요청 페이로드 구성을 확인해야 합니다.
정확도 샘플의 한계
NLI 샘플 4건만으로 모델 품질을 판단할 수는 없습니다. 이 샘플은 배포 방식이 모델의 판정 결과를 바꾸지 않는지 확인하는 용도입니다. 실제 도입 전에는 별도의 평가 데이터셋으로 정확도를 측정해야 합니다.
사용법¶
로컬 실행¶
bash 01_single_endpoint/scripts/serve_local.sh
uv run python -m benchmark.run --mode local --pad-to-max --sweep-batch
uv run python -m benchmark.run --mode local --pad-to-max --sweep-concurrency
bash 01_single_endpoint/scripts/cleanup_local.sh
SageMaker 엔드포인트¶
# 단일 엔드포인트
uv run python -m benchmark.run --mode cloud --endpoint <ep> --pad-to-max --sweep-batch
# 공동 호스팅: 배포 방식에 따라 대상 지정 옵션이 다릅니다.
uv run python -m benchmark.run --mode cloud --endpoint <ep> --target-container mdeberta # 02
uv run python -m benchmark.run --mode cloud --endpoint <ep> --inference-component <ic> # 03
uv run python -m benchmark.run --mode cloud --endpoint <ep> --target-model mdeberta.tar.gz # 04
Triton 엔드포인트¶
Triton 모델은 텍스트가 아니라 텐서를 입력으로 받으므로 --engine triton 옵션이 필요합니다. 이 방식에서는 클라이언트의 토큰화 시간도 종단 간 지연 시간에 포함됩니다.
uv run python -m benchmark.run --mode cloud --endpoint <ep> \
--engine triton --pad-to-max --warmup 20
배치 형태마다 워밍업이 필요합니다. 이 저장소의 TensorRT 구성에서는 새로운 배치 형태를 처음 처리할 때 컴파일이 발생합니다. 배치 크기 1로 워밍업을 마쳐도 배치 크기 8의 첫 요청은 다시 컴파일될 수 있으며, 이때 호출 제한 시간 60초를 초과할 수 있습니다. 자세한 구성은 Triton과 TensorRT를 참고하세요.
Triton 앙상블 구성은 서버에서 토큰화를 수행하므로 다른 시나리오와 같은 페이로드 형식인 --engine hf를 사용합니다.
공동 호스팅 방식 비교¶
uv run python -m benchmark.compare_cohost \
--mc encoder-serving-02-mc-ep \
--ic encoder-serving-03-ic-ep \
--lmi encoder-serving-04-lmi-ep \
--batch-sizes 1 8 -n 16
이 명령은 기본적으로 --pad-to-max를 적용합니다. 측정값은 벤치마크 결과에서 확인할 수 있습니다.
주요 옵션¶
| 옵션 | 기본값 | 설명 |
|---|---|---|
--pad-to-max |
비활성화(compare는 활성화) |
입력 길이를 max_len=512로 고정 |
--sweep-batch |
- | 배치 크기별 측정 |
--sweep-concurrency |
- | 동시성 수준별 측정 |
--concurrency |
1 | 동시 요청 상한 |
--request-rate |
inf |
초당 요청 수. inf이면 동시 요청 상한만 적용 |
--burstiness |
1.0 | 1.0은 푸아송 과정, inf는 고정 간격 |
--warmup |
3 | 측정에서 제외할 워밍업 요청 수 |
-n |
100 | 요청 수 |
--engine |
hf |
페이로드 형식: hf, vllm, triton |
충분한 워밍업 요청 사용
워커가 순차적으로 모델을 로드하는 동안 초기 요청은 대기할 수 있습니다. 워커 4개 구성에서 워밍업 요청을 3회만 실행하면 p99가 1,611 ms였지만, 20회로 늘리면 20.4 ms로 낮아졌습니다. 이 저장소의 측정에서는 워커 수의 약 5배를 워밍업 요청 수로 사용했습니다.
LMI는 첫 요청 시점에 모델을 로드하므로 더 많은 워밍업 요청이 필요할 수 있습니다.
부하 패턴¶
--request-rate와 --burstiness로 요청 도착 패턴을 설정합니다.
--request-rate inf(기본값): 동시 요청 상한만 적용하고 요청을 즉시 전송합니다. 최대 처리량 측정에 적합합니다.--request-rate 200 --burstiness 1.0: 푸아송 과정으로 요청을 전송합니다.--burstiness inf: 일정한 간격으로 요청을 전송합니다.
요청 간격은 Gamma(shape=burstiness, scale=1/(rate*burstiness)) 분포에서 추출합니다. burstiness=1이면 지수 분포를 따르며, 요청 도착은 푸아송 과정이 됩니다.