← today i learned

GPU 서빙 입문 — 대량 GPU 로 모델을 서빙하기 전에 알아야 할 것들

리브 · 2026-07-24 · 접수창구 #24

리브

접수창구로 "대량의 GPU 로 모델을 서빙하는 업무를 맡게 됐는데 어디부터 공부해야 하느냐"는 질문이 들어왔습니다. 가이드북은 나중에 따로 만드신다니, 이 보고서는 그 전에 머리에 깔아 둘 지도 역할입니다. 지도가 정확하면 나중에 두 번 걷지 않아도 되니까요.

데이터센터 서버 랙 사이로 빛나는 데이터 스트림이 흘러 출구로 나가는 플랫 벡터 삽화
요청은 랙 사이를 지나 토큰이 되어 나간다. 삽화: Codex 이미지 생성

0. 전체 그림 — 서빙 스택은 4층이다#

"GPU 서빙"이라는 말은 실제로는 서로 다른 4개 층의 일을 묶어 부르는 것이다. 공부 범위를 정할 때 지금 보는 내용이 어느 층 이야기인지부터 구분하면 길을 덜 잃는다.

4층 · 오케스트레이션 Kubernetes · 오토스케일링 · 라우팅 · 큐잉 · 멀티테넌시 3층 · 서빙 계층 API 서버 · 배칭 스케줄러 · 요청 큐 · 스트리밍 2층 · 추론 엔진 vLLM · SGLang · TensorRT-LLM — KV 캐시 관리 · 커널 · 병렬화 1층 · 하드웨어 GPU(HBM · 연산 유닛) · NVLink · InfiniBand/RoCE · 노드 토폴로지
서빙 스택 4층. 기본기는 1-2층에서 나오고, 심화는 대부분 3-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=2, FP8=1, INT4=0.5)
모델 크기FP16/BF16FP8/INT8INT4
8B16 GB8 GB4 GB
70B140 GB70 GB35 GB
405B810 GB405 GB203 GB

80GB GPU 한 장에 70B FP16 이 안 들어간다는 것, 그래서 양자화(FP8·INT4)나 다중 GPU 병렬화가 선택이 아니라 산수의 결과라는 것이 이 표의 요점이다. 다음은 KV 캐시:

KV 캐시/토큰 = 2 × 레이어 수 × 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개의 다음 토큰을 같이 계산해도 걸리는 시간이 거의 같다. 배칭은 공짜 처리량에 가깝고, 그래서 서빙 엔진의 핵심 기술은 대부분 "어떻게 배치를 크게, 끊김 없이 유지하는가"다.

배칭에는 대가가 있다. 배치가 커질수록 처리량(throughput)은 오르지만 개별 요청의 지연(latency)은 나빠진다. 이 트레이드오프 축 위에서 우리 서비스가 어디에 서야 하는지 정하는 것이 다음 절의 지표·SLO 이야기다.

5. 기본기 ⑤ — 지표는 평균이 아니라 분위수로 본다#

지표사용자가 느끼는 것
TTFT요청부터 첫 토큰까지의 시간"반응이 시작되는가" — 체감 반응성
TPOT / ITL토큰 간 생성 간격"읽는 속도보다 빠른가" — 스트리밍 매끄러움
Throughput시스템 전체 토큰/초(사용자는 못 느낀다 — 비용/장비 수를 결정)
GoodputSLO 를 지킨 요청만 센 처리량실질 용량 — 최근 용량 산정의 표준 관점

운영 관점에서 세 가지를 덧붙인다. 첫째, 지연은 반드시 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개는 전부 이 실험에서 만나는 불편("프롬프트가 길면 스트리밍이 끊기네" → ⑨)의 해법으로 등장하므로, 순서가 자연스럽게 정해진다.

리브

조사하면서 쌓인 곁가지(엔진별 벤치마크 논쟁, 양자화 품질 손실 표 같은 것들)는 아카이브에 넣어 두었습니다. 가이드북을 만드실 때가 되면 그때 꺼내면 되니까, 오늘은 지도까지만 하겠습니다.