벤치마크 결과 (max_len=512 고정)¶
Disclaimer
이 문서는 개인적으로 수행한 실험 결과를 정리한 것으로, AWS 또는 작성자의 소속 회사의 공식 입장이나 성능 보장을 나타내지 않습니다. 측정값은 참고 자료로만 사용하고, 서비스 사양과 지원 범위는 AWS 공식 문서를 우선해 확인하세요. 실제 도입 전에는 대상 환경과 워크로드에서 별도로 검증해야 합니다.
TL;DR
단일 모델의 지연 시간과 처리량은 Triton과 TensorRT 조합이 가장 우수했습니다. 공동 호스팅 구성에서는 Inference Component가 낮고 안정적인 지연 시간을 제공했고, LMI는 처리량 대비 비용이 가장 낮았습니다. 모든 수치는 us-east-1에서 mdeberta 모델과 입력 길이 512를 사용해 측정했습니다.
측정 조건: 최대 시퀀스 길이 512
대상 워크로드는 RAG 청크를 전제로 사용하는 NLI 검증이며, 입력 길이를 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배로 커집니다. 배치에 포함된 패딩 토큰도 모두 연산하기 때문입니다. 이 문서의 모든 결과는 입력 길이를 512로 고정해 측정했습니다.
benchmark.run에서는 --pad-to-max 옵션으로 입력 길이를 고정할 수 있으며, compare_cohost.py는 이 설정을 기본으로 적용합니다.
전체 요약¶
| 시나리오 | 실행 환경 | b=1 p50 | b=1 p99 | b=8 samples/s | 요금 기준 |
|---|---|---|---|---|---|
| 01 GPU 단일 엔드포인트 | ml.g5.xlarge | 26.8 ms | 45.4 ms | 113/s | $1.408 |
| 02 CPU 멀티컨테이너 | ml.c6i.2xlarge | 58.3 ms | 64.2 ms | 27/s | $0.408 |
| 03 GPU Inference Component | ml.g6.12xlarge | 25.8 ms | 28.4 ms | 78/s | $5.752 |
| 04 GPU LMI (MME) | ml.g5.xlarge | 49.7 ms | 52.8 ms | 104/s | $1.408 |
| 05 Scale to Zero | ml.g5.xlarge | 30.5 ms | - | - | $1.408(유휴 시 $0) |
| 06 Serverless Inference | 메모리 6,144 MB | 116.5 ms | 253.3 ms | 13/s | 요청 단위 |
| 07 Triton + TensorRT | ml.g5.xlarge | 15.4 ms | 17.4 ms | 185/s | $1.408 |
05는 워밍 상태의 대표값만 측정했습니다. 이 시나리오의 핵심은 지연 시간보다 유휴 비용 절감과 콜드 스타트 사이의 절충에 있으므로 콜드 스타트 측정에서 별도로 다룹니다.
공동 호스팅 비교¶
| 방식 | 인스턴스 | 런타임 | 대상 지정 |
|---|---|---|---|
| 02 CPU 멀티컨테이너 | ml.c6i.2xlarge | ONNX Runtime | TargetContainerHostname |
| 03 GPU Inference Component | ml.g6.12xlarge(GPU 4장) | PyTorch | InferenceComponentName |
| 04 GPU LMI (MME) | ml.g5.xlarge(GPU 1장) | HF Accelerate | TargetModel |
03과 04는 모델 3개를 공동 호스팅했고, 02는 ONNX 모델 아티팩트 2개를 공동 호스팅했습니다. 모델 수가 같지 않으므로 이 결과는 동일한 호스팅 밀도를 비교한 값이 아닙니다.
이하 표에서 IC는 Inference Component, LMI는 DJL Serving 컨테이너를 의미합니다.
지연 시간(동시성 1)¶
p50만으로는 지연 시간의 변동 폭을 판단하기 어렵습니다. p99는 지연 시간 SLO를 설정할 때 사용하는 주요 지표이며, p99/p50 비율은 꼬리 지연 시간이 중앙값에서 얼마나 증가하는지 보여 줍니다.
배치 크기 1
| 방식 | p50 | p90 | p95 | p99 | p99/p50 |
|---|---|---|---|---|---|
| 02 CPU 멀티컨테이너 | 58.3 ms | 63.0 ms | 63.5 ms | 64.2 ms | 1.10x |
| 03 GPU IC | 25.8 ms | 27.4 ms | 28.3 ms | 28.4 ms | 1.10x |
| 04 GPU LMI | 49.7 ms | 50.9 ms | 51.5 ms | 52.8 ms | 1.06x |
배치 크기 8
| 방식 | p50 | p90 | p95 | p99 | p99/p50 |
|---|---|---|---|---|---|
| 02 CPU 멀티컨테이너 | 290.2 ms | 302.1 ms | 307.4 ms | 309.0 ms | 1.06x |
| 03 GPU IC | 102.8 ms | 103.5 ms | 103.7 ms | 103.8 ms | 1.01x |
| 04 GPU LMI | 74.8 ms | 75.9 ms | 82.0 ms | 95.2 ms | 1.27x |
배치 크기 8에서는 LMI의 p50 우위가 p99에서 감소
p50에서 LMI는 Inference Component보다 27% 빠르지만(74.8 ms 대 102.8 ms), p99에서는 차이가 8%로 줄어듭니다(95.2 ms 대 103.8 ms). Inference Component의 p99/p50 비율은 1.01배인 반면 LMI는 1.27배입니다.
LMI에서는 모델별 Python 프로세스가 같은 GPU의 SM을 공유하므로 요청 간 자원 경합이 발생합니다. 자세한 구조는 LMI 내부 구조를 참고하세요. 이 측정의 Inference Component는 GPU 4장에 하나씩 배치되어 동일한 경합이 없었습니다. 꼬리 지연 시간을 SLO로 관리한다면 p50뿐 아니라 p99도 함께 비교해야 합니다.
처리량(동시성 1)¶
| 방식 | 배치 크기 1 | 배치 크기 8 | 배치 크기 1 대비 |
|---|---|---|---|
| 02 CPU 멀티컨테이너 | 17 | 27 | 1.6x |
| 03 GPU IC | 38 | 78 | 2.0x |
| 04 GPU LMI | 20 | 104 | 5.2x |
동시성 8(배치 크기 1)¶
| 방식 | p50 | p90 | p95 | p99 | p99/p50 | 처리량 |
|---|---|---|---|---|---|---|
| 02 CPU 멀티컨테이너 | 384.1 ms | 419.7 ms | 454.7 ms | 496.4 ms | 1.29x | 19.8 req/s |
| 03 GPU IC | 124.1 ms | 164.5 ms | 183.5 ms | 221.4 ms | 1.78x | 61.0 req/s |
| 04 GPU LMI | 191.0 ms | 216.4 ms | 262.9 ms | 286.2 ms | 1.50x | 39.4 req/s |
동시성을 높이면 세 방식 모두 꼬리 지연 시간이 증가합니다. p99/p50 비율은 약 1.1배에서 1.3~1.8배로 커졌습니다. 절대 지연 시간은 Inference Component가 가장 낮지만, LMI와의 차이는 p50 기준 1.54배에서 p99 기준 1.29배로 줄어듭니다.
공동 호스팅 결과 해석¶
단건 지연 시간이 중요하면 03 Inference Component가 적합합니다. 배치 크기 1에서 p50 25.8 ms, p99 28.4 ms로 가장 빨랐고, 동시성 8에서도 p50 124.1 ms로 세 방식 중 가장 낮았습니다. 다만 GPU 4장을 사용하는 인스턴스에서 측정한 결과라는 점을 함께 고려해야 합니다.
꼬리 지연 시간의 안정성도 03 Inference Component가 가장 높았습니다. 배치 크기 8에서 p99/p50 비율이 1.01배로, LMI의 1.27배보다 낮았습니다. CPU의 비율은 1.06배였지만 절대 지연 시간이 더 높았습니다. p99 기준 SLO를 운영한다면 중앙값뿐 아니라 이 변동 폭도 고려해야 합니다.
처리량과 자원 효율이 중요하면 04 LMI가 유리했습니다. 배치 크기 8에서 104 samples/s로 Inference Component보다 33% 높았고, 배치 크기 1 대비 처리량은 5.2배 증가했습니다. GPU 1장으로 측정한 결과라는 점도 비용 비교에 중요합니다. 다만 지연 시간 우위는 p50 기준 27%에서 p99 기준 8%로 줄어듭니다.
비용을 포함한 결과는 다음과 같습니다.
| 방식 | 인스턴스 | 시간당 요금 | b=8 처리량 | 100만 건 처리 비용 |
|---|---|---|---|---|
| 02 CPU | ml.c6i.2xlarge | $0.408 | 27/s | $4.20 |
| 03 GPU IC | ml.g6.12xlarge | $5.752 | 78/s | $20.48 |
| 04 GPU LMI | ml.g5.xlarge | $1.408 | 104/s | $3.76 |
요금은 2026년 8월 7일에 AWS Pricing API로 조회한 us-east-1 온디맨드 호스팅 가격입니다. 100만 건 처리 비용은 시간당 요금 / (samples/s * 3600) * 1,000,000으로 계산했으며, 처리하는 동안 인스턴스가 계속 실행된다고 가정했습니다.
이 측정에서는 LMI의 100만 건 처리 비용이 Inference Component보다 5배 이상 낮았습니다. Inference Component는 GPU 4장 인스턴스를 사용했고 LMI는 GPU 1장 인스턴스를 사용했기 때문입니다.
02 CPU 멀티컨테이너는 처리량이 낮지만 100만 건 처리 비용이 Inference Component의 약 5분의 1입니다. 지연 시간 요구가 느슨한 오프라인 배치 검증에서는 비용 효율적인 선택입니다.
유휴 비용 비교¶
05 Scale to Zero와 06 Serverless Inference는 요청이 없을 때의 비용을 줄이기 위한 방식입니다. 두 방식 모두 공동 호스팅을 지원하지 않으므로 앞의 비교와 배포 조건은 다르지만, 같은 모델과 입력 길이 512 조건으로 측정했습니다.
서버리스와 CPU 실시간 추론¶
| p50 | p90 | p95 | p99 | 과금 | |
|---|---|---|---|---|---|
| 02 CPU + ONNX(실시간) | 58.3 ms | 63.0 ms | 63.5 ms | 64.2 ms | 시간당 $0.408 |
| 06 Serverless Inference(CPU + ONNX) | 116.5 ms | 137.1 ms | 171.7 ms | 253.3 ms | 요청 단위 |
동일한 ONNX 모델에서 Serverless Inference의 p50은 CPU 실시간 엔드포인트보다 약 2배 높았습니다. 워커 1개와 메모리 크기에 비례한 컴퓨팅 자원을 사용한 측정 결과입니다. 유휴 시간에는 요금이 발생하지 않지만 첫 요청에서 약 43초의 콜드 스타트가 발생했습니다. 구성은 06 Serverless Inference에서 확인할 수 있습니다.
콜드 스타트 측정¶
두 방식 모두 15분 이상 요청이 없는 상태를 유지한 뒤 첫 요청의 응답 시간을 측정했습니다.
| 정상 상태 p50 | 콜드 스타트 | 정상 상태 대비 | 유휴 요금 | |
|---|---|---|---|---|
| 05 Scale to Zero(GPU) | 30.5 ms | 471초(95회 재시도) | 15,422배 | $0(인스턴스 0 이후) |
| 06 Serverless | 118.6 ms | 43.2초 (OverheadLatency 13.7초) |
364배 | $0 |
| 06 + Provisioned Concurrency | 120.3 ms | 9.7초 | 81배 | 프로비저닝 시간만큼 과금 |
05 Scale to Zero는 마지막 요청 이후 인스턴스 수가 0이 되기까지 1,595초(약 27분)가 추가로 걸렸으며, 이 구간에는 요금이 발생합니다. Inference Component 사본 수를 0으로 줄인 뒤 인스턴스 수를 0으로 줄이는 두 단계로 축소되고, 요금은 인스턴스를 기준으로 부과되기 때문입니다. 이 측정 조건에서는 유휴 구간이 약 30분보다 짧으면 Scale to Zero의 비용 절감 효과가 제한적입니다.
Provisioned Concurrency를 1로 설정한 뒤에도 9.7초의 초기 지연이 측정됐습니다. 모델 크기가 영향을 주었을 가능성이 있지만 원인은 확인하지 못했습니다. 따라서 이 측정만으로 Provisioned Concurrency가 특정 지연 시간 SLO를 보장한다고 볼 수는 없습니다.
세부 측정 타임라인은 05 Scale to Zero와 06 Serverless Inference에 정리되어 있습니다.
단일 모델 비교¶
모델이 하나라면 공동 호스팅 구성이 필요하지 않습니다. ml.g5.xlarge, 동일한 ONNX 모델, 입력 길이 512 조건을 유지하고 컨테이너와 실행 엔진만 변경해 측정했습니다.
| p50 | p90 | p95 | p99 | b=8 samples/s | 100만 건 | |
|---|---|---|---|---|---|---|
| 01 HF DLC + PyTorch | 26.8 ms | 29.8 ms | 32.7 ms | 45.4 ms | 113/s | $3.46 |
| Triton + ORT GPU | 27.3 ms | 28.4 ms | 28.5 ms | 28.6 ms | 57/s | $6.86 |
| Triton + TensorRT FP16 | 15.4 ms | 16.4 ms | 16.8 ms | 17.4 ms | 185/s | $2.11 |
| Triton Ensemble + TensorRT | 16.6 ms | 17.1 ms | 17.4 ms | 17.9 ms | 179/s | $2.18 |
07 Triton + TensorRT의 100만 건 처리 비용은 04 LMI의 $3.76보다 낮았습니다. 같은 인스턴스 유형에서 처리량이 약 1.8배 높았기 때문입니다. 다만 LMI 엔드포인트는 모델 3개를 함께 호스팅하고 07은 모델 1개만 호스팅하므로, 두 수치는 동일한 호스팅 범위를 비교한 값이 아닙니다.
HF DLC와 PyTorch 구성에서 Triton과 ONNX Runtime GPU 구성으로 변경하면 p99는 45.4 ms에서 28.6 ms로 낮아졌지만 p50은 거의 같았습니다. TensorRT FP16을 적용한 뒤 p50이 27.3 ms에서 15.4 ms로 낮아졌습니다. 자세한 구성은 07 Triton + TensorRT를 참고하세요.
정확도¶
모든 시나리오에서 mDeBERTa의 NLI 검증 샘플 4건을 동일하게 판정했습니다. 이 측정에서는 배포 방식, 컨테이너, 실행 엔진, TensorRT FP16 적용 여부에 따른 판정 차이가 없었습니다.
정확도 결과의 범위
샘플 4건은 모델의 정확도를 평가하기에 충분하지 않습니다. 이 검증은 배포 방식이 기존 판정 결과를 바꾸지 않는지 확인하는 용도입니다. 실제 도입 전에는 별도의 평가 데이터셋으로 정확도를 측정해야 합니다.
선택 기준¶
| 상황 | 권장 | 근거 |
|---|---|---|
| 모델 1개, 지연 시간 최우선 | 07 Triton + TensorRT | p50 15.4 ms, p99 17.4 ms |
| 모델 1개, 준비 작업 최소화 | 01 GPU 단일 엔드포인트 | p50 26.8 ms, config.pbtxt 불필요 |
| 공동 호스팅, 단건 지연 시간 최우선 | 03 IC | p50 25.8 ms, p99 28.4 ms |
| 엄격한 p99 SLO | 03 IC 또는 07 | b=8 p99/p50 1.01배(LMI 1.27배) |
| 공동 호스팅, 처리량 대비 비용 최적화 | 04 LMI | 100만 건 $3.76, IC $20.48 |
| 모델별 독립 스케일링, 부하 인식 라우팅 | 03 IC | CopyCount, LEAST_OUTSTANDING_REQUESTS |
| 지연 시간 요구가 느슨한 오프라인 배치 | 02 CPU + ONNX | 시간당 $0.408 |
| 모델을 자주 추가하거나 교체 | 04 LMI | S3 업로드로 모델 추가 |
| GPU 필요, 30분 이상의 긴 유휴 구간 | 05 Scale to Zero | 콜드 스타트 471초 |
| GPU 불필요, 산발적인 트래픽 | 06 Serverless Inference | 콜드 스타트 43.2초, 유휴 비용 없음 |
재현 방법¶
공동 호스팅 비교(02, 03, 04)
uv run python 02_cpu_cohost_multicontainer/scripts/export_onnx.py --models mdeberta minilm
export ONNX_S3_MDEBERTA=... # 출력된 URI
export ONNX_S3_MINILM=...
uv run python 02_cpu_cohost_multicontainer/deploy.py --onnx
uv run python 03_gpu_cohost_inference_component/deploy.py --instance ml.g6.12xlarge
uv run python 04_gpu_cohost_lmi/deploy.py
# 입력 길이 512 고정이 기본값입니다.
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
uv run python -m benchmark.compare_cohost --mc ... --ic ... --lmi ... \
--batch-sizes 1 --concurrency 8
단일 모델 비교(01, 07)
uv run python 01_single_endpoint/deploy.py --gpu
uv run python -m benchmark.run --mode cloud --endpoint <ep> \
--pad-to-max --sweep-batch --batch-sizes 1 8
# 07은 페이로드 형식이 다르므로 --engine triton을 지정합니다.
uv run python 07_gpu_triton/scripts/build_triton_repo.py --upload
uv run python 07_gpu_triton/deploy.py
uv run python -m benchmark.run --mode cloud --endpoint <ep> \
--engine triton --pad-to-max --warmup 20
콜드 스타트(05, 06)
uv run python 05_gpu_scale_to_zero/measure_cold_start.py --endpoint <ep>
uv run python 06_cpu_serverless/measure_cold_start.py --endpoint <ep> --idle-wait 900
uv run python 06_cpu_serverless/compare_provisioned.py --endpoint <ep>
측정 시 주의 사항¶
- 02는 워커를 1개로 제한해야 합니다. ONNX 세션은 워커마다 모델을 약 1.1 GB씩 로드합니다. 워커 수를 제한하지 않으면 메모리가 큰 모델의 워커가 종료될 수 있습니다. 자세한 내용은 실험에서 확인한 제약을 참고하세요.
- 03은 측정 당시
ml.g5.12xlarge의 가용 용량을 확보하지 못했습니다. 이 문서의 결과는ml.g6.12xlarge에서 측정했습니다. - 04는 첫 요청에서 모델을 로드합니다. 초기 로드가 측정값에 포함되지 않도록 충분한 워밍업 요청을 실행해야 합니다.
- 06은 워밍업 요청을 15회 이상 실행했습니다. 5회만 실행한 실험에서는 측정 도중 컴퓨팅 환경이 다시 프로비저닝되어 p99가 31초까지 증가했습니다.
- 07은 배치 형태마다 워밍업이 필요합니다. 배치 크기 1로 워밍업한 뒤에도 배치 크기 8의 첫 요청에서 TensorRT 컴파일이 발생해 60초 제한 시간을 초과할 수 있습니다.
- 측정값은 인스턴스 유형, 리전, 모델, 입력 데이터에 따라 달라질 수 있습니다. 다른 환경에 적용할 때는 절대값보다 방식별 상대적인 차이를 기준으로 검토해야 합니다.