GPU 서빙 입문 — 대량 GPU 로 모델을 서빙하기 전에 알아야 할 것들
접수창구로 "대량의 GPU 로 모델을 서빙하는 업무를 맡게 됐는데 어디부터 공부해야 하느냐"는 질문이 들어왔습니다. 가이드북은 나중에 따로 만드신다니, 이 보고서는 그 전에 머리에 깔아 둘 지도 역할입니다. 지도가 정확하면 나중에 두 번 걷지 않아도 되니까요.
0. 전체 그림 — 서빙 스택은 4층이다#
"GPU 서빙"이라는 말은 실제로는 서로 다른 4개 층의 일을 묶어 부르는 것이다. 공부 범위를 정할 때 지금 보는 내용이 어느 층 이야기인지부터 구분하면 길을 덜 잃는다.
아래 기본기 6개는 1-2층을, 심화 로드맵은 2-4층을 다룬다. 순서에는 이유가 있다. 위층의 모든 설계 결정(배칭·스케줄링·오토스케일링)은 결국 아래층의 물리적 제약(메모리 용량·대역폭)에서 도출되기 때문에, 아래에서 위로 올라가는 것이 두 번 공부하지 않는 동선이다.
1. 기본기 ① — GPU 는 연산기가 아니라 메모리 장치로 이해한다#
추론 서빙에서 GPU 의 병목은 대부분 연산(FLOPS)이 아니라 메모리 대역폭이다. 예를 들어 H100 은 FP16 기준 약 1,000 TFLOPS 급 연산 성능을 갖지만, HBM3 메모리 대역폭은 약 3.35 TB/s 다. LLM 이 토큰 하나를 생성할 때마다 모델 가중치 전체를 HBM 에서 연산 유닛으로 읽어 와야 하는데, 이 "읽기" 속도가 생성 속도의 상한을 정한다. 70B 모델을 FP16 으로 올리면 가중치가 140GB 이므로, 대역폭을 다 쓴다고 가정해도 단일 배치의 토큰 생성 속도 상한이 계산으로 나온다.
그래서 처음 외워야 할 스펙은 클럭이나 코어 수가 아니라 세 가지다: HBM 용량(모델과 KV 캐시가 들어가는가), 메모리 대역폭(토큰 생성이 얼마나 빠른가), GPU 간 인터커넥트(NVLink·InfiniBand — 모델을 쪼갤 때 통신이 병목이 되는가). 연산이 남고 메모리가 모자라는 이 불균형이 뒤에 나오는 배칭·양자화·병렬화 전부의 존재 이유다. 이 관점을 정식화한 것이 roofline 모델과 arithmetic intensity(연산 강도) 개념인데, 용어만 알아 두어도 엔진 튜닝 문서를 읽을 때 막히지 않는다.
2. 기본기 ② — 추론에는 성격이 다른 두 국면이 있다#
LLM 추론 요청 하나는 두 국면을 거친다.
| 국면 | 하는 일 | 병목 | 직결되는 지표 |
|---|---|---|---|
| Prefill | 입력 프롬프트 전체를 한 번에 처리해 KV 캐시를 만든다 | 연산(compute-bound) | TTFT (첫 토큰까지 시간) |
| Decode | 토큰을 한 개씩 자기회귀로 생성한다 | 메모리 대역폭(memory-bound) | TPOT (토큰 간 간격) |
같은 GPU 에서 두 국면의 병목이 다르다는 것이 서빙 문제의 뿌리다. 긴 프롬프트의 prefill 이 GPU 를 점유하면 다른 요청들의 decode 가 밀려 토큰 스트림이 뚝뚝 끊긴다. 최근 서빙 아키텍처의 큰 흐름 하나가 이 두 국면을 아예 다른 GPU 풀로 분리하는 것(심화 ⑨의 P/D disaggregation)인데, 기본기 단계에서는 "요청 하나에 성격이 다른 두 작업이 섞여 있다"는 사실만 정확히 잡아 두면 된다.
이 국면 구분에서 KV 캐시라는 개념이 나온다. decode 때마다 이전 토큰 전부를 다시 계산하지 않으려고 attention 의 key/value 를 저장해 두는 것인데, 이것이 GPU 메모리의 두 번째 대형 소비자이며 다음 절의 계산 대상이다.
3. 기본기 ③ — 메모리 계산은 암산이 되어야 한다#
용량 산정(capacity planning)의 절반은 두 개의 곱셈이다. 먼저 가중치:
| 모델 크기 | FP16/BF16 | FP8/INT8 | INT4 |
|---|---|---|---|
| 8B | 16 GB | 8 GB | 4 GB |
| 70B | 140 GB | 70 GB | 35 GB |
| 405B | 810 GB | 405 GB | 203 GB |
80GB GPU 한 장에 70B FP16 이 안 들어간다는 것, 그래서 양자화(FP8·INT4)나 다중 GPU 병렬화가 선택이 아니라 산수의 결과라는 것이 이 표의 요점이다. 다음은 KV 캐시:
Llama 3 70B(레이어 80, KV 헤드 8, 헤드 차원 128, FP16)면 토큰당 약 320KB. 동시 사용자 100명이 평균 4K 토큰 컨텍스트를 유지하면 KV 캐시만 약 128GB 다. 가중치가 아니라 KV 캐시가 동시접속 수를 결정하는 경우가 많다는 것, 그리고 GQA(grouped-query attention) 같은 모델 구조 선택이 곧 서빙 비용 문제라는 것을 이 공식에서 읽을 수 있다. 실무에서는 여기에 activation 과 프레임워크 오버헤드로 여유분을 얹어 잡는다.
4. 기본기 ④ — 배칭이 처리량의 대부분을 결정한다#
decode 가 memory-bound 라는 사실의 뒤집힌 면: 가중치를 한 번 읽어 올 때 요청 1개 대신 32개의 다음 토큰을 같이 계산해도 걸리는 시간이 거의 같다. 배칭은 공짜 처리량에 가깝고, 그래서 서빙 엔진의 핵심 기술은 대부분 "어떻게 배치를 크게, 끊김 없이 유지하는가"다.
- Continuous batching — 배치 전체가 끝나기를 기다리지 않고, 요청이 끝난 자리에 대기 중인 요청을 토큰 단위로 끼워 넣는다. 정적 배칭 대비 처리량이 수 배 뛰며, 현대 서빙 엔진의 표준이다.
- PagedAttention — KV 캐시를 OS 의 가상 메모리처럼 페이지 단위로 관리해 단편화를 없앤다. vLLM 을 유명하게 만든 기법이고, 배치를 크게 유지하려면 메모리 낭비가 없어야 하기 때문에 배칭과 한 몸이다.
배칭에는 대가가 있다. 배치가 커질수록 처리량(throughput)은 오르지만 개별 요청의 지연(latency)은 나빠진다. 이 트레이드오프 축 위에서 우리 서비스가 어디에 서야 하는지 정하는 것이 다음 절의 지표·SLO 이야기다.
5. 기본기 ⑤ — 지표는 평균이 아니라 분위수로 본다#
| 지표 | 뜻 | 사용자가 느끼는 것 |
|---|---|---|
| TTFT | 요청부터 첫 토큰까지의 시간 | "반응이 시작되는가" — 체감 반응성 |
| TPOT / ITL | 토큰 간 생성 간격 | "읽는 속도보다 빠른가" — 스트리밍 매끄러움 |
| Throughput | 시스템 전체 토큰/초 | (사용자는 못 느낀다 — 비용/장비 수를 결정) |
| Goodput | SLO 를 지킨 요청만 센 처리량 | 실질 용량 — 최근 용량 산정의 표준 관점 |
운영 관점에서 세 가지를 덧붙인다. 첫째, 지연은 반드시 P95·P99 분위수로 본다. 평균 TTFT 가 좋아도 P99 가 무너져 있으면 사용자 100명 중 1명은 매번 최악을 경험한다. 둘째, throughput 과 latency 는 서로를 깎는 관계이므로 "SLO(예: P99 TTFT < 1초, TPOT < 50ms)를 먼저 정하고, 그 제약 아래에서 goodput 을 최대화한다"가 올바른 문제 설정이다. 셋째, 부하 테스트 없이 스펙시트로 용량을 정하지 않는다. 같은 모델·같은 GPU 라도 입력/출력 길이 분포에 따라 결과가 크게 달라지므로, 실제 트래픽 분포를 흉내 낸 벤치마크(vLLM 의 bench 도구, genai-perf 등)가 산정의 근거가 된다.
6. 기본기 ⑥ — 프레임워크 지형은 넓게 알고 하나를 깊게 판다#
| 이름 | 층 | 한 줄 요약 |
|---|---|---|
| vLLM | 추론 엔진 | 사실상의 오픈소스 표준. PagedAttention 원조, 생태계·문서 최다. 처음 깊게 팔 하나로 무난 |
| SGLang | 추론 엔진 | RadixAttention 기반 prefix 캐시 공유가 강점. 대화·에이전트처럼 프롬프트가 겹치는 워크로드에 유리 |
| TensorRT-LLM | 추론 엔진 | NVIDIA 컴파일 기반. 최고 성능을 짜낼 수 있으나 빌드·운영 복잡도가 높다 |
| Triton Inference Server | 서빙 계층 | 멀티 프레임워크·멀티 모델 서버. LLM 외 모델(비전·임베딩·랭커)까지 한 서버로 묶을 때 |
| KServe / Ray Serve | 오케스트레이션 | Kubernetes 위 모델 배포·스케일링 추상화. 엔진을 감싸는 바깥 껍데기 |
주의할 점 하나. "모델 서빙"이 LLM 서빙만을 뜻하지는 않는다. 임베딩·리랭커·비전 모델처럼 요청-응답이 한 번에 끝나는 모델은 KV 캐시도 decode 국면도 없어서 문제가 훨씬 단순하다(동적 배칭 + 복제 수 조절이 거의 전부). 맡은 업무에 이런 모델이 섞여 있다면 그쪽은 Triton 계열 지식으로 커버되고, 이 보고서의 어려운 부분은 대부분 LLM 쪽 이야기다.
7. 심화 로드맵 — 기본기 위에 쌓는 7개 주제#
여기서부터는 "당장 전부"가 아니라 필요가 생길 때 꺼내 쓰는 목록이다. 각 주제에 검색 키워드를 붙여 두었다.
⑦ 모델 병렬화 — 모델이 GPU 한 장을 넘을 때
Tensor Parallelism(TP)은 레이어 안을 쪼개 노드 내 NVLink 로 묶고, Pipeline Parallelism(PP)은 레이어를 구간으로 잘라 노드 사이에 걸친다. MoE 모델이면 Expert Parallelism(EP)이 추가된다. 핵심 감각은 "병렬화는 공짜가 아니라 통신 비용과의 거래"라는 것. TP 는 매 레이어 all-reduce 통신이 필요해서 인터커넥트가 느리면 오히려 손해다. 키워드: tensor parallelism, NCCL, all-reduce, NVLink topology.
⑧ Prefix 캐싱 — 같은 프롬프트를 두 번 계산하지 않기
시스템 프롬프트·문서·대화 이력처럼 요청 간에 겹치는 접두사의 KV 캐시를 재사용한다. 에이전트·RAG 워크로드에서는 적중률에 따라 prefill 비용이 몇 분의 일로 줄어서, 캐시 적중률을 높이는 라우팅(같은 세션을 같은 GPU 로)이 곧 성능 튜닝이 된다. 키워드: prefix caching, RadixAttention, cache-aware routing.
⑨ P/D 분리(disaggregation) — 두 국면을 다른 GPU 풀로
기본기 ②의 논리적 귀결. prefill 전용 풀과 decode 전용 풀을 나누고 KV 캐시를 넘겨주면, 긴 프롬프트가 스트리밍을 끊는 간섭이 사라지고 풀별로 최적 하드웨어·병렬화를 따로 고를 수 있다. NVIDIA Dynamo, llm-d, Mooncake 같은 최신 분산 서빙 스택의 중심 아이디어다. 키워드: prefill decode disaggregation, KV cache transfer.
⑩ Speculative decoding — 대역폭 병목을 우회하는 트릭
작은 draft 모델이 토큰 여러 개를 추측하고 큰 모델이 한 번의 forward 로 검증한다. 출력 분포는 그대로 유지하면서 decode 를 2-3배 가속할 수 있다. 배치가 이미 큰 고부하 상황에서는 이득이 줄어드는 등 적용 조건이 까다로워서, 도입 전 벤치마크가 필수인 대표적 기법이다. 키워드: speculative decoding, draft model, EAGLE, Medusa.
⑪ 오케스트레이션 — GPU 를 "무리"로 다루기
Kubernetes 위에서 GPU 스케줄링(device plugin·GPU Operator), 작은 모델 여럿의 GPU 공유(MIG·MPS·time-slicing), LLM 특화 오토스케일링을 다룬다. LLM 은 모델 로딩에 수 분이 걸려 콜드스타트가 무겁고, GPU 사용률은 스케일 신호로 부적합해서 큐 깊이·KV 캐시 사용률 같은 신호를 쓴다. 전통 웹서버 스케일링 직감이 그대로 통하지 않는 지점이다. 키워드: GPU Operator, MIG, llm-d, KEDA, inference gateway.
⑫ 관측성 — GPU 사용률이라는 함정
nvidia-smi 의 GPU utilization 100% 는 "커널이 돌고 있는 시간의 비율"일 뿐, 연산 유닛이 실제로 일하는 비율이 아니다. memory-bound 인 decode 는 연산 유닛이 대부분 놀면서도 사용률 100% 로 찍힌다. 이 숫자로 용량을 판단하면 크게 틀린다. DCGM 으로 SM activity·메모리 대역폭 사용률·전력을 따로 보고, 엔진이 내보내는 지표(배치 크기, 큐 대기, KV 캐시 점유율)와 함께 대시보드를 짠다. 키워드: DCGM exporter, SM efficiency, MFU.
⑬ 장애와 신뢰성 — GPU 는 생각보다 자주 죽는다
수백 장 규모가 되면 ECC 에러, HBM 불량, NVLink 플랩, 열 스로틀링이 일상 이벤트가 된다. 헬스체크와 자동 격리(cordon)·재스케줄링, 드라이버·CUDA·펌웨어 버전 매트릭스 관리, 그리고 "재시작에 수 분 걸리는 무거운 프로세스"를 전제로 한 배포 전략(드레이닝, 롤링의 여유 용량)이 운영 업무의 실체다. 키워드: Xid errors, DCGM health check, node problem detector.
8. 학습 순서 제안#
| 단계 | 할 일 | 목표 |
|---|---|---|
| 1단계 | 기본기 ①-⑤를 문서로 학습 | 용어가 아니라 "왜"를 설명할 수 있는 상태. 메모리 암산이 되는 상태 |
| 2단계 | GPU 1장에 vLLM 으로 8B 급 모델을 직접 서빙 | 배치 크기·컨텍스트 길이를 바꿔 가며 TTFT/TPOT/throughput 이 움직이는 것을 눈으로 확인 |
| 3단계 | 부하 테스트 도구로 자기 워크로드 벤치마크 | SLO 를 정하고 goodput 기준 장비 수를 산정해 본다 |
| 4단계 | 다중 GPU(TP)와 Kubernetes 배포로 확장 | 심화 ⑦·⑪ 진입. 이때부터 심화 주제를 필요 순서대로 |
순서의 요점은 2단계다. 문서만으로는 배칭과 지표의 트레이드오프가 몸에 붙지 않는데, GPU 1장 실험이면 기본기 다섯 개가 전부 눈앞에서 재현된다. 심화 7개는 전부 이 실험에서 만나는 불편("프롬프트가 길면 스트리밍이 끊기네" → ⑨)의 해법으로 등장하므로, 순서가 자연스럽게 정해진다.
조사하면서 쌓인 곁가지(엔진별 벤치마크 논쟁, 양자화 품질 손실 표 같은 것들)는 아카이브에 넣어 두었습니다. 가이드북을 만드실 때가 되면 그때 꺼내면 되니까, 오늘은 지도까지만 하겠습니다.