빠른지보다 먼저, 무엇이 느린지 물어야 한다
멀티 GPU LLM 시스템을 처음 구축하면 누구나 가장 먼저 tokens/sec를 봅니다. 숫자가 높으면 기분이 좋고, 낮으면 GPU를 더 사고 싶어집니다. 하지만 이 숫자 하나만 보고 판단하면 꽤 자주 잘못된 결론에 도착합니다. 사용자는 첫 글자가 늦게 뜨는 것을 불편해할 수도 있고, 운영자는 동시 접속자가 늘어날 때만 시스템이 무너지는 것을 걱정할 수도 있습니다. 연구자는 긴 프롬프트에서만 느려지는 현상을 보고 싶고, 서비스 운영자는 p95 지연 시간이 SLA를 넘는 순간을 찾아야 합니다.
LLM 추론은 일반 웹 서버처럼 "요청 하나를 처리하고 끝"나는 작업이 아닙니다. 먼저 입력 프롬프트 전체를 읽고, 그다음 한 토큰씩 답을 생성합니다. 이 두 단계의 성격이 완전히 다릅니다. 그래서 벤치마킹은 단순 속도 측정이 아니라, 시스템의 어느 부분이 막히는지 추적하는 작업입니다.
이 장의 핵심 질문은 하나입니다. 지금 필요한 것은 GPU 추가인가, 옵션 조정인가, 모델 축소인가? 이 질문에 답하려면 먼저 지표를 제대로 나누어 봐야 합니다.

LLM 성능 지표를 분해해서 보기
LLM 벤치마킹에서 자주 쓰는 지표는 서로 비슷해 보이지만, 실제로는 다른 병목을 가리킵니다. NVIDIA의 LLM 벤치마킹 문서도 TTFT, end-to-end latency, ITL, TPS 같은 지표를 구분해서 설명합니다. 특히 TTFT는 큐 대기, prefill, 네트워크 지연을 함께 포함할 수 있고, ITL은 첫 토큰 이후의 decode 성능을 보는 데 적합합니다.1
| 지표 | 뜻 | 주로 봐야 하는 상황 |
|---|---|---|
| TTFT | 요청 후 첫 토큰이 나오기까지 걸린 시간 | 채팅, 에이전트, IDE 자동완성처럼 "반응성"이 중요한 서비스 |
| TPOT / ITL | 첫 토큰 이후 토큰 하나를 생성하는 데 걸리는 평균 시간 | 긴 답변, 코드 생성, 추론형 모델의 체감 속도 |
| End-to-end latency | 요청부터 최종 답변 완료까지의 전체 시간 | 비스트리밍 API, 배치 작업, 업무 자동화 |
| Throughput | 시스템 전체가 초당 처리하는 토큰 수 | 다중 사용자 서빙, 비용 효율, GPU 사용률 최적화 |
| Maximum concurrency | SLA를 유지하며 동시에 처리 가능한 요청 수 | 운영 용량 산정, 오토스케일링 기준 설정 |
| GPU memory utilization | VRAM 중 모델 가중치와 KV 캐시가 차지하는 비율 | OOM, 긴 컨텍스트, 동시 요청 수 제한 분석 |
TTFT는 사용자가 "응답이 시작됐다"고 느끼는 시점입니다. 스트리밍 채팅에서는 전체 답변이 20초 걸리더라도 첫 토큰이 0.5초 안에 나오면 꽤 빠르게 느껴집니다. 반대로 첫 토큰이 8초 뒤에 나오면, 이후 초당 100토큰으로 생성되더라도 사용자는 이미 답답함을 느낍니다.
TPOT 또는 ITL은 토큰과 토큰 사이의 간격입니다. 예를 들어 ITL이 20ms라면 대략 초당 50토큰입니다. 긴 코드 생성이나 보고서 작성처럼 출력이 긴 작업에서는 TTFT보다 ITL이 중요합니다. 특히 reasoning 모델처럼 내부적으로 긴 답을 생성하는 모델은 ITL이 조금만 나빠져도 전체 시간이 크게 늘어납니다.
End-to-end latency는 전체 요청 완료 시간입니다. 스트리밍 UI에서는 TTFT와 ITL을 따로 보는 편이 더 유용하지만, "요약 결과를 받아 다음 파이프라인에 넘기는" 백엔드 작업에서는 전체 완료 시간이 더 중요합니다.
Throughput은 운영자의 숫자입니다. 시스템이 초당 몇 토큰을 처리하는지, 같은 GPU 비용으로 얼마나 많은 요청을 감당할 수 있는지 보여줍니다. 그러나 throughput만 높이고 싶어 배치를 크게 키우면 개별 사용자의 latency가 나빠질 수 있습니다. 이 균형을 찾는 것이 서빙 튜닝의 핵심입니다.
Maximum concurrency는 "몇 명까지 동시에 받아도 되는가"를 묻는 지표입니다. 여기서 중요한 것은 단순히 에러 없이 받는 수가 아니라, p95 TTFT나 p95 latency 같은 기준을 넘지 않는 동시성입니다. 동시성 200에서 throughput이 최고라고 해도 p95 TTFT가 30초라면 채팅 서비스에는 쓸 수 없습니다.
마지막으로 GPU memory utilization은 멀티 GPU LLM에서 가장 자주 놓치는 지표입니다. GPU 사용률이 40%인데도 느린 경우가 있고, GPU 코어는 놀고 있는데 VRAM의 KV 캐시가 꽉 차서 새 요청이 대기하는 경우도 있습니다. vLLM이나 NIM 같은 서버의 로그에서 GPU KV cache usage, waiting requests, prefix cache hit rate를 함께 봐야 하는 이유가 여기에 있습니다.
prefill은 계산, decode는 메모리 싸움이다
LLM 추론은 크게 두 단계로 나뉩니다. 첫 번째는 prefill입니다. 입력 프롬프트 전체를 한 번에 읽고, 각 토큰에 대한 KV 캐시를 만드는 단계입니다. 두 번째는 decode입니다. 이미 만들어진 KV 캐시를 참고하면서 한 토큰씩 다음 토큰을 생성하는 단계입니다.
prefill은 대체로 compute-bound입니다. 여기서 compute-bound란 GPU의 연산 능력, 특히 행렬 곱셈 처리 능력이 병목이 된다는 뜻입니다. 긴 프롬프트를 넣으면 모델은 많은 입력 토큰을 한꺼번에 처리해야 하므로 GPU의 텐서 코어가 바빠집니다. RAG에서 문서 20쪽을 붙여 넣거나, 긴 대화 기록을 매번 보내는 경우 TTFT가 늘어나는 이유가 바로 이 prefill 비용 때문입니다.
decode는 대체로 memory-bound입니다. memory-bound란 계산 장치보다 메모리에서 데이터를 읽고 쓰는 속도가 병목이 된다는 뜻입니다. decode에서는 토큰을 하나 만들 때마다 모델 가중치와 KV 캐시를 계속 읽습니다. 한 번에 생성하는 토큰 수는 작기 때문에 거대한 행렬 연산을 시원하게 몰아서 하기 어렵고, 대신 VRAM 대역폭과 캐시 접근 효율이 중요해집니다. NVIDIA 문서도 출력 시퀀스가 길어질수록 KV 캐시가 커지고, 토큰 간 지연이 메모리 관리와 메모리 대역폭의 영향을 크게 받는다고 설명합니다.2
이 차이를 알면 긴 프롬프트와 긴 출력의 병목이 다르게 보입니다. 입력 20,000토큰에 출력 200토큰인 요약 서비스는 TTFT가 크게 튑니다. 처음에 프롬프트를 읽는 시간이 길기 때문입니다. 반대로 입력 200토큰에 출력 4,000토큰인 코드 생성 서비스는 첫 토큰은 빨리 나오지만, 뒤로 갈수록 decode 시간이 전체 비용을 지배합니다.
따라서 벤치마크는 최소한 네 가지 모양으로 나누어야 합니다.
| 워크로드 | 예시 | 주 병목 |
|---|---|---|
| 짧은 입력·짧은 출력 | 챗봇 짧은 질답 | 큐잉, 스케줄링, 네트워크 |
| 긴 입력·짧은 출력 | RAG, 문서 요약 | prefill, TTFT, KV 캐시 초기 할당 |
| 짧은 입력·긴 출력 | 코드 생성, 글쓰기 | decode, ITL, 메모리 대역폭 |
| 긴 입력·긴 출력 | 장문 분석, reasoning | prefill과 decode 모두, KV 캐시 용량 |
Koyeb의 GPU LLM 벤치마크도 512×512, 1024×1024, 4096×1024처럼 입력과 출력 길이를 통제한 token shape로 측정합니다. 이런 방식은 모델과 GPU를 공정하게 비교하고, 입력 길이와 출력 길이에 따라 병목이 어떻게 바뀌는지 보기 좋습니다.3
실험은 한 번에 하나씩 바꾼다
성능 튜닝에서 가장 흔한 실패는 옵션을 한꺼번에 바꾸는 것입니다. --max-num-seqs도 바꾸고, --max-num-batched-tokens도 바꾸고, prefix caching도 켜고, 모델 양자화도 바꾸면 결과가 좋아져도 무엇 때문인지 알 수 없습니다. 벤치마킹은 실험입니다. 실험은 통제되어야 합니다.
먼저 기준선을 잡습니다. 모델, 양자화 포맷, 컨텍스트 길이, GPU 수, 병렬화 방식, 서버 버전, 드라이버 버전, CUDA 버전, 입력 길이, 출력 길이, 동시성, 샘플링 옵션을 모두 기록합니다. temperature가 달라져 출력 길이가 달라지면 결과가 흔들리므로, 가능하면 합성 데이터나 고정된 데이터셋을 사용합니다. TensorRT-LLM의 벤치마크 절차도 입력 길이와 출력 길이를 지정해 합성 데이터셋을 만들고, 같은 조건에서 throughput을 측정하는 방식을 사용합니다.4
실험 순서는 다음처럼 잡는 것이 좋습니다.
단일 요청 latency 기준선 측정
concurrency 1에서 TTFT, ITL, end-to-end latency를 측정합니다. 이 값은 "이 시스템이 가장 한가할 때 낼 수 있는 최소 지연"입니다. 여기서 이미 느리다면 배치 튜닝보다 모델 포맷, 병렬화 방식, GPU 세대, 커널 최적화를 먼저 봐야 합니다.동시성 증가 곡선 측정
concurrency를 1, 2, 4, 8, 16, 32, 64처럼 올립니다. 각 구간에서 throughput, p50/p95 TTFT, p50/p95 ITL, 에러율, waiting request 수를 기록합니다. 어느 순간 throughput 증가가 둔해지고 latency가 급증하는 지점이 시스템의 포화점입니다.batch 관련 옵션 조정
vLLM에서는max-num-seqs가 동시에 처리할 수 있는 sequence 수에 영향을 주고,max-num-batched-tokens는 한 번의 배치에 담을 수 있는 토큰 수를 제한합니다. 짧은 요청이 많은 서비스는max-num-seqs가 중요하고, 긴 프롬프트가 많은 서비스는max-num-batched-tokens가 중요해집니다. 값을 올리면 throughput은 좋아질 수 있지만, VRAM 사용량과 TTFT가 함께 늘 수 있습니다.chunked prefill 실험
긴 프롬프트가 들어올 때 prefill이 GPU를 오래 붙잡으면 다른 사용자의 decode가 밀립니다. chunked prefill은 긴 prefill을 작은 덩어리로 나누어 decode와 섞어 처리하는 방식입니다. 긴 입력이 많은 RAG 서비스에서는 TTFT가 약간 바뀌더라도 전체 p95 latency가 좋아질 수 있습니다.prefix caching 실험
시스템 프롬프트, 공통 문서, few-shot 예제가 반복된다면 prefix caching을 켜고 TTFT 변화를 봅니다. 같은 prefix를 다시 계산하지 않고 이미 만들어 둔 KV 캐시를 재사용하면 긴 컨텍스트 서비스에서 첫 토큰 시간이 크게 줄어들 수 있습니다. KV 캐시 재사용과 오프로딩은 긴 문맥, 다중 사용자, 반복 prefix가 있는 환경에서 특히 효과적입니다.5VRAM 한계 실험
gpu-memory-utilization,max-model-len,kv-cache-dtype를 조정합니다. GPU 메모리 사용률을 높이면 더 많은 KV 캐시를 담을 수 있지만, 너무 공격적으로 잡으면 OOM이 납니다. FP8 KV cache는 KV 캐시 메모리를 줄여 더 많은 동시 요청을 수용하는 데 도움이 되지만, 반드시 실제 업무 데이터로 품질을 확인해야 합니다.
이 과정을 거치면 "GPU가 부족하다"는 막연한 감각이 더 구체적인 문장으로 바뀝니다. 예를 들어 "동시성 64 이후 p95 TTFT가 급등하며 GPU KV cache usage가 90%를 넘는다"는 결론이라면 GPU 코어가 아니라 KV 캐시 용량이 문제일 가능성이 큽니다. 반대로 "concurrency 1에서도 ITL이 높고 GPU 메모리 대역폭이 꽉 찬다"면 decode 단계의 메모리 병목을 의심해야 합니다.
tokens/sec 그래프는 포화점까지 봐야 한다
멀티 사용자 서빙에서 throughput은 보통 처음에는 동시성과 함께 증가합니다. 사용자가 1명일 때는 GPU가 놀고, 10명일 때는 배치가 잘 만들어져 GPU가 바빠집니다. 그러다 어느 순간부터 throughput 증가가 둔해지고, latency만 나빠집니다. 이 지점이 포화점입니다.
NVIDIA NIM의 Llama 3.3 70B 결과를 보면 이런 패턴이 잘 드러납니다. 예를 들어 2×H100 FP8 TP2 구성에서 500 입력·2000 출력 워크로드는 동시성이 증가할수록 throughput이 크게 올라가지만, 더 높은 동시성에서는 TTFT와 ITL도 함께 증가합니다. 20,000 입력·2,000 출력처럼 긴 입력 워크로드에서는 concurrency가 커질 때 TTFT가 매우 크게 증가해, throughput만으로는 사용자 경험을 설명할 수 없습니다.6
운영 기준은 보통 "최대 throughput 지점"이 아니라 "허용 가능한 latency 안에서 가장 높은 throughput 지점"입니다. 채팅 서비스라면 p95 TTFT 1초 이하, p95 ITL 50ms 이하처럼 기준을 잡을 수 있습니다. 내부 배치 요약 시스템이라면 p95 end-to-end latency 2분 이하와 같은 기준이 더 현실적입니다.
그래프는 최소한 세 개를 같이 그려야 합니다. 첫째, concurrency 대비 throughput. 둘째, concurrency 대비 p50/p95 TTFT. 셋째, concurrency 대비 p50/p95 ITL입니다. 여기에 GPU memory utilization과 KV cache usage를 겹쳐 보면 병목이 훨씬 선명해집니다.
PCIe에서는 TP보다 PP가 나을 때가 많다
멀티 GPU에서 병렬화 방식은 성능 그래프의 모양을 바꿉니다. Tensor Parallelism, 즉 TP는 한 레이어 내부의 행렬을 여러 GPU로 쪼갭니다. GPU들이 매 토큰, 매 레이어마다 서로 결과를 주고받아야 하므로 인터커넥트가 중요합니다. NVLink나 NVSwitch처럼 GPU 간 대역폭이 높을수록 유리합니다.
Pipeline Parallelism, 즉 PP는 레이어 묶음을 GPU별로 나눕니다. GPU 0이 앞쪽 레이어를 계산하고, GPU 1이 뒤쪽 레이어를 계산하는 식입니다. 통신은 레이어 경계에서 일어나므로 TP보다 덜 촘촘합니다. 대신 파이프라인 버블이 생기고, 단일 요청 latency가 늘 수 있습니다.
소비자용 멀티 GPU 워크스테이션은 대부분 PCIe 기반입니다. PCIe 4.0 x16의 이론 대역폭은 NVLink에 비해 훨씬 낮고, 메인보드 구성에 따라 x8로 내려가는 경우도 많습니다. 이런 환경에서 TP를 크게 잡으면 계산보다 GPU 간 통신이 발목을 잡을 수 있습니다. 실제로 RTX 4090, 5090, RTX PRO 6000을 비교한 벤치마크에서는 vLLM 멀티 GPU 구성에 pipeline parallelism을 사용했고, tensor parallelism은 더 많은 VRAM과 통신 오버헤드 때문에 일부 모델에서 불리할 수 있다고 설명합니다.7
따라서 PCIe 환경에서는 다음 순서로 실험하는 편이 안전합니다. 먼저 모델이 GPU 한 장에 들어가면 복제본을 여러 개 띄워 로드밸런싱합니다. 이것이 가장 단순하고 빠릅니다. 모델이 한 장에 안 들어가면 PP를 먼저 시도합니다. 그다음 NVLink가 있거나 H100/A100 SXM 같은 고대역폭 환경에서 TP를 비교합니다.
NVLink 환경에서도 TP 크기를 늘린다고 성능이 선형으로 늘지는 않습니다. TP=2에서는 비교적 효율이 좋을 수 있지만, TP=4, TP=8로 갈수록 통신 횟수와 동기화 비용이 증가합니다. 특히 decode 단계는 토큰 하나씩 진행되므로 작은 작업을 자주 동기화해야 합니다. GPU가 8장이라고 해서 한 요청의 tokens/sec가 8배가 되는 것은 아닙니다. 대신 더 큰 모델을 올리거나, 더 많은 동시 요청을 처리하거나, latency를 낮추는 방향으로 이득을 봅니다.
llama.cpp 기반의 공개 벤치마크에서도 70B Q4 모델은 2×RTX 4090이 약 19 tok/s, 4×RTX 4090이 약 18~19 tok/s 수준으로 나타나, GPU 수 증가가 단일 스트림 생성 속도를 선형으로 높이지 않는다는 점을 보여줍니다. 반면 prompt processing 속도는 구성과 입력 길이에 따라 다른 양상을 보입니다.8
결론은 단순합니다. TP는 빠른 GPU 간 연결이 있을 때 빛나고, PP는 PCIe 환경에서 모델을 나눠 올리는 현실적인 선택지입니다. 그리고 모델이 한 GPU에 들어간다면, 멀티 GPU 분할보다 복제본 확장이 더 나은 경우가 많습니다.
포맷이 바뀌면 같은 모델도 다른 모델처럼 움직인다
"Llama 70B를 돌린다"는 말은 성능 측면에서 충분한 설명이 아닙니다. 같은 모델이라도 어떤 포맷과 양자화를 쓰느냐에 따라 속도, 품질, VRAM 사용량이 크게 달라집니다.
GGUF는 llama.cpp 생태계에서 널리 쓰입니다. CPU와 GPU를 함께 쓰거나, 소비자용 GPU 여러 장에 레이어를 나눠 올리기 좋습니다. Q4_K_M, Q5_K_M, Q6_K 같은 선택지가 다양하고, VRAM이 부족한 로컬 환경에서 강합니다. 공개된 Llama 3 70B GGUF 양자화 표를 보면 Q4_K_M은 약 39.6GiB, Q5_K_M은 약 46.5GiB, Q6_K는 약 53.9GiB로 커지며 perplexity는 점점 FP16에 가까워집니다.9 즉 VRAM을 더 쓰면 품질 손실은 줄지만, 더 많은 GPU나 더 작은 컨텍스트가 필요합니다.
AWQ와 GPTQ는 주로 Hugging Face와 vLLM 계열에서 많이 사용됩니다. 둘 다 4비트 가중치 양자화에 자주 쓰이지만, 커널 지원과 모델별 최적화 상태에 따라 속도 차이가 납니다. AWQ는 vLLM에서 실전 서빙용으로 자주 선택되고, GPTQ는 모델 배포량이 많지만 특정 GPU나 커널에서는 기대만큼 빠르지 않을 수 있습니다. 중요한 것은 "4비트니까 무조건 빠르다"가 아니라, 해당 엔진이 그 포맷을 얼마나 잘 가속하느냐입니다.
EXL2는 ExLlama 계열에서 강점을 보이는 포맷입니다. 단일 사용자 또는 소수 사용자 로컬 추론에서 매우 빠른 경우가 많고, 비트율을 세밀하게 조정할 수 있습니다. 다만 대규모 프로덕션 서빙, OpenAI 호환 API, 동적 배치, Kubernetes 운영까지 고려하면 vLLM이나 TensorRT-LLM 생태계가 더 편할 수 있습니다.
FP8은 H100, H200, B200 같은 데이터센터 GPU에서 특히 중요합니다. FP16/BF16보다 메모리를 덜 쓰고, 하드웨어가 FP8 연산을 잘 지원하면 throughput이 크게 좋아집니다. NVIDIA NIM과 TensorRT-LLM 벤치마크에서도 FP8 모델과 FP4 모델을 별도로 제시하며, GPU 세대와 정밀도에 따라 throughput이 크게 달라짐을 보여줍니다.10
TensorRT engine은 특정 모델, 특정 GPU, 특정 입력 범위에 맞춰 최적화한 실행 엔진이라고 이해하면 됩니다. 빌드 과정이 번거롭고 유연성은 떨어질 수 있지만, 잘 맞는 환경에서는 latency와 throughput이 매우 좋습니다. NIM도 TensorRT-LLM 기반 최적화 프로파일을 사용하며, latency 프로파일과 throughput 프로파일을 구분합니다. latency 프로파일은 더 많은 GPU를 써서 요청 지연을 낮추고, throughput 프로파일은 모델을 올릴 수 있는 최소 GPU 수를 활용해 GPU당 처리량을 높이는 식입니다.11
정리하면 포맷 선택은 다음 기준으로 하면 됩니다.
| 포맷 | 강점 | 주의할 점 |
|---|---|---|
| GGUF | 로컬 추론, llama.cpp, CPU+GPU 혼합, 소비자 GPU 친화적 | 고동시성 프로덕션 서빙 기능은 제한적일 수 있음 |
| AWQ | vLLM 서빙에서 실용적, 4비트 VRAM 절감 | 모델별 커널 지원과 품질 확인 필요 |
| GPTQ | 배포 모델이 많고 선택지가 넓음 | 엔진에 따라 AWQ보다 느릴 수 있음 |
| EXL2 | 로컬 단일 사용자 속도와 세밀한 비트율 조정 | 대규모 운영 생태계는 상대적으로 좁음 |
| FP8 | H100/H200/B200 등에서 throughput과 VRAM 효율 우수 | 구형 GPU에서는 이점이 제한적 |
| TensorRT engine | 최적화된 latency와 throughput | 빌드 비용, 모델 변경 시 재최적화 부담 |
중요한 점은 품질도 함께 측정해야 한다는 것입니다. 벤치마크에서 Q4가 빠르고 VRAM을 적게 쓴다고 해서 업무에 충분한 답을 낸다는 보장은 없습니다. 특히 코딩, 수학, 긴 문서 검색, 법률·의료처럼 작은 오류가 큰 문제가 되는 작업은 포맷별 정답률, 회귀 테스트, 장문 검색 테스트를 함께 돌려야 합니다.
병목을 찾는 관찰 도구
좋은 벤치마크는 클라이언트 지표와 서버 지표를 함께 봅니다. 클라이언트는 사용자가 체감하는 TTFT, ITL, latency를 알려줍니다. 서버는 왜 그런 일이 생겼는지 알려줍니다.
클라이언트 측에서는 GenAI-Perf, vllm bench serve, Locust, k6 등을 사용할 수 있습니다. GenAI-Perf는 OpenAI 호환 API나 Triton 같은 백엔드에 대해 LLM 특화 지표를 측정할 수 있어, 단순 HTTP 부하 테스트보다 토큰 단위 분석에 적합합니다. 서버 측에서는 vLLM 로그, Prometheus, Grafana, DCGM exporter, nvidia-smi dmon, Nsight Systems 등을 봅니다.
관찰할 값은 GPU utilization만이 아닙니다. 오히려 GPU utilization이 높지 않은데도 느릴 때가 더 골치 아픕니다. 이때는 CPU 토크나이징 병목, 네트워크 지연, Python 스케줄링 오버헤드, 디스크에서 모델을 읽는 시간, 컨테이너 CPU 제한, NUMA 배치 문제를 봐야 합니다.
멀티 GPU에서는 GPU별 메모리 사용량도 중요합니다. 한 GPU만 VRAM이 꽉 차고 다른 GPU는 여유가 있다면 레이어 분할이나 tensor split 비율이 잘못되었을 수 있습니다. TP 환경에서 특정 GPU의 통신 시간이 길다면 PCIe 토폴로지나 NCCL 설정을 확인해야 합니다. nvidia-smi topo -m으로 GPU 간 연결 구조를 확인하고, 가능하면 같은 PCIe 스위치나 같은 NUMA 노드에 묶인 GPU를 함께 사용해야 합니다.
튜닝 결정을 내리는 법
마지막에는 숫자를 결정으로 바꿔야 합니다. 측정 결과가 다음과 같다면 선택지도 비교적 명확합니다.
TTFT만 높고 ITL은 괜찮다면 긴 prefill이 문제일 가능성이 큽니다. 이때는 입력을 줄이고, chunked prefill을 켜고, prefix caching을 활용하고, RAG 문서 수를 줄이거나 재랭킹을 강화합니다. 공통 prefix가 많다면 LMCache나 KV cache offloading도 검토합니다.
ITL이 높고 출력이 길수록 체감이 나쁘다면 decode 병목입니다. 이때는 더 빠른 메모리 대역폭의 GPU, 더 나은 양자화 커널, FP8/FP4 지원, TensorRT-LLM, speculative decoding을 검토합니다. 단순히 컨텍스트를 줄여도 decode 중 KV 캐시 접근량이 줄어 도움이 될 수 있습니다.
동시성을 올릴 때 TTFT가 급등하고 waiting request가 생긴다면 KV 캐시 용량이나 스케줄러 한계입니다. 이때는 max-model-len을 현실적으로 낮추고, max-num-seqs와 max-num-batched-tokens를 조정하고, FP8 KV cache나 CPU swap, prefix caching을 실험합니다. 그래도 부족하면 GPU 추가가 맞습니다.
GPU 메모리는 남는데 throughput이 오르지 않는다면 CPU, 네트워크, 토크나이저, 로드밸런서, API 서버가 병목일 수 있습니다. 이 경우 GPU를 더 사도 효과가 작습니다. 벤치마크 클라이언트를 다른 노드에 두고, 요청 생성 자체가 병목이 아닌지 확인해야 합니다.
품질은 충분하지만 VRAM이 부족하다면 양자화 포맷을 바꿉니다. Q6에서 Q5, Q5에서 Q4로 낮추거나, BF16에서 FP8로 바꿉니다. 반대로 품질 문제가 보이면 더 높은 비트율이나 더 큰 모델을 고려합니다.
벤치마크 체크리스트
실전에서는 다음 표를 복사해 실험 노트로 쓰면 좋습니다.
| 항목 | 기록할 내용 |
|---|---|
| 하드웨어 | GPU 모델, GPU 수, VRAM, PCIe/NVLink, CPU, RAM |
| 소프트웨어 | 드라이버, CUDA, inference engine, 컨테이너 태그 |
| 모델 | 모델명, 파라미터 수, 컨텍스트 길이, 양자화 포맷 |
| 병렬화 | TP, PP, replica 수, tensor split 비율 |
| 워크로드 | 입력 토큰, 출력 토큰, 요청 수, concurrency |
| 지표 | TTFT, ITL/TPOT, e2e latency, throughput, RPS |
| 분포 | 평균뿐 아니라 p50, p90, p95, p99 |
| 메모리 | GPU memory utilization, KV cache usage, OOM 여부 |
| 품질 | 정답률, 회귀 테스트, 장문 검색 성공률 |
| 비용 | 시간당 비용, 100만 토큰당 비용, 전력 사용량 |
이 체크리스트의 목적은 완벽한 논문식 벤치마크를 만드는 것이 아닙니다. 목적은 판단을 돕는 것입니다. GPU를 한 장 더 사야 하는지, PP를 TP로 바꿔야 하는지, Q4 대신 Q5를 써야 하는지, 컨텍스트를 32K에서 8K로 줄여도 되는지 결정하기 위한 지도입니다.
멀티 GPU LLM 시스템은 감으로 튜닝하기에는 너무 복잡합니다. 토큰은 빠르게 나오는데 첫 토큰이 느릴 수 있고, GPU는 놀고 있는데 KV 캐시가 꽉 찰 수 있으며, GPU를 늘렸는데 통신 때문에 더 느려질 수도 있습니다. 그러나 지표를 나누고, 워크로드를 나누고, 옵션을 하나씩 바꿔 측정하면 문제는 의외로 정직하게 모습을 드러냅니다.
좋은 벤치마크는 결국 돈을 아껴 줍니다. 필요 없는 GPU 구매를 막아 주고, 잘못된 모델 선택을 고쳐 주며, 사용자가 실제로 느끼는 속도를 개선합니다. 멀티 GPU의 세계에서 가장 강력한 튜닝 도구는 새 그래픽카드가 아니라, 잘 설계된 측정표입니다.
참고
1NVIDIA NIM LLMs Benchmarking Metrics
2LLM Inference Benchmarking: Fundamental Concepts
3Koyeb GPU LLM Performance Benchmarks
4TensorRT-LLM Performance Overview
5How to Reduce KV Cache Bottlenecks with NVIDIA Dynamo
6NVIDIA NIM LLMs Benchmarking Performance
7RTX 4090 vs RTX 5090 vs RTX PRO 6000 LLM Inference Benchmark
8GPU Benchmarks on LLM Inference
9GPU Benchmarks on LLM Inference — Quantization and Perplexity Table
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.