스터디 · 2026-10-12 · 기초
LLM 인프라 기초: GPU 메모리·서빙·비용 한 번에 보기
LLM을 돌리는 비용은 대부분 GPU 메모리를 어떻게 쓰느냐에서 갈린다. 이 글은 가중치·KV 캐시·정밀도에서 시작해 추론 엔진, 연속 배칭, 모델 병렬화, 배포 방식 고르기와 토큰 비용 계산까지 실무 순서대로 정리한다.
목차
- 학습은 가중치 외에 기울기·옵티마이저 상태까지 메모리에 올려야 하고, 추론은 요청이 들어올 때마다 계속 드는 운영비다.
- GPU 메모리는 가중치, KV 캐시, 활성값에 쓰인다. 가중치는 'BF16 기준 파라미터 수(십억 개) × 2GB'로 어림하고, 동시에 처리할 수 있는 요청 수는 KV 캐시를 어떻게 관리하느냐에 달려 있다.
- vLLM 같은 추론 엔진은 페이지드 어텐션과 연속 배칭으로 메모리 낭비를 줄여 처리량을 높인다. 다만 지연(TTFT)과 처리량은 서로 줄다리기 관계다.
- 모델이 GPU 한 장에 들어가지 않으면 먼저 양자화를 검토하고, 그래도 안 되면 텐서 병렬(층 안을 나눔)이나 파이프라인 병렬(층 순서로 나눔)을 쓴다.
- 비용은 API라면 '요청 수 × 입력·출력 토큰 × 단가'로, 직접 운영한다면 'GPU 시간당 비용 ÷ 처리 토큰 수'로 어림한다.
무엇이고 왜 필요한가: 학습과 추론은 다른 일이다
LLM을 '돌린다'는 말에는 두 가지 일이 섞여 있다. 학습은 많은 데이터를 보면서 파라미터(모델이 배운 숫자)를 고치는 일이고, 추론은 다 만든 모델로 답을 만들어 내는 일이다. 학습할 때는 앞으로 계산한 뒤 오차를 거꾸로 보내 값을 고치는 과정(역전파)까지 거친다. 그래서 가중치 말고도 기울기, 옵티마이저 상태, 중간 계산값을 함께 메모리에 올려 둬야 하고, 같은 모델이라도 추론보다 훨씬 많은 GPU가 든다. Megatron-LM논문도 거대 트랜스포머는 메모리 제약 때문에 학습하기 어렵다고 짚었고, 83억 개 파라미터 모델을 GPU 512장으로 학습했다.
추론은 한 번으로 끝나지 않는다. 사용자 요청이 올 때마다 계속 드는 운영비다. vLLM 논문논문은 LLM 요청 하나를 처리하는 비용이 전통적인 키워드 검색보다 10배 비쌀 수 있다는 추정을 인용하면서, 처리량을 높여 요청당 비용을 낮추는 일이 중요해졌다고 말한다. 대부분의 회사는 모델을 직접 학습하지 않고 이미 있는 모델을 서빙(사용자에게 응답을 내주는 운영)한다. 그래서 이 글도 추론을 중심으로 다룬다.
LLM 추론에는 특징이 하나 있다. 앞서 나온 토큰을 보고 다음 토큰을 하나씩 만들어 낸다는 점이다(자기회귀 모델). vLLM 논문은 이렇게 순서대로 생성하기 때문에 작업 속도가 메모리에 묶이고, GPU의 계산 능력을 다 쓰지 못한다고 설명한다. FlashAttention논문도 최신 GPU는 계산 속도가 메모리 속도를 앞질러서, 트랜스포머 연산 대부분이 메모리 접근에서 막힌다고 지적한다. LLM 인프라 이야기의 상당 부분이 '메모리를 어떻게 아껴 쓰나'인 이유가 여기에 있다.
구성 요소: GPU 메모리는 어디에 쓰이나
GPU 메모리(VRAM)에는 크게 세 가지가 올라간다. 첫째는 가중치다. 모델 자체이고, 서빙하는 동안 내내 고정돼 있다. 둘째는 KV 캐시다. 앞서 처리한 토큰들의 어텐션 키·값을 저장해 두는 메모로, 다음 토큰을 만들 때 같은 계산을 다시 하지 않게 해 준다. 요청마다 따로 생기고 글이 길어질수록 커졌다가 요청이 끝나면 사라진다. 셋째는 활성값이다. 계산 도중에 잠깐 생기는 중간값이다.
vLLM 논문논문은 실제 비율 예를 보여 준다. 40GB A100 GPU에서 13B(130억 파라미터) 모델을 서빙하면 메모리의 약 65%를 가중치가, 30% 가까이를 KV 캐시가 차지하고, 나머지 약 5%를 활성값 등이 쓴다. 가중치는 변하지 않고 활성값은 작다. 그러니 KV 캐시를 어떻게 관리하느냐가 한 번에 묶어 처리할 수 있는 요청 수(배치 크기)를 정한다. vLLM 블로그글에 따르면 LLaMA-13B에서는 시퀀스 하나의 KV 캐시만 최대 1.7GB에 이른다.
가중치 크기는 간단히 어림할 수 있다. Hugging Face 가이드글의 경험칙은 다음과 같다. 파라미터가 X billion(십억 개 단위)이면 FP32에서는 약 4X GB, BF16·FP16에서는 약 2X GB가 든다. 예를 들어 Llama-2-70b는 140GB, Falcon-40b는 80GB다. 가이드는 1,024 토큰 미만의 짧은 입력에서는 필요한 메모리가 거의 가중치로 정해진다고 설명한다. 실제로 BF16 기준 31GB로 예상한 bigcode/octocoder를 올려 보니 약 29GB가 측정됐다. 입력이 길거나 동시 요청이 많으면 그만큼 KV 캐시 몫이 커진다는 점도 기억해야 한다.
GPU 메모리를 나눠 쓰는 모습
GPU 메모리 40GB (A100, 13B 모델)
가중치 약 65%KV 캐시 약 30%활성값 등 약 5%
정밀도와 양자화: 숫자를 얼마나 촘촘히 적을까
파라미터는 소수이고, 소수 하나를 몇 바이트로 적느냐가 정밀도다. FP32는 4바이트, FP16과 BF16은 2바이트, FP8은 1바이트를 쓴다. BF16은 FP16과 크기는 같지만 표현할 수 있는 수의 범위가 넓어서 학습할 때 값이 덜 불안정하다. Hugging Face 가이드글는 요즘 거의 모든 모델이 BF16으로 학습된다고 설명한다. 앞의 octocoder를 FP32로 돌렸다면 64GB가 필요했을 것이라고도 밝혔다.
양자화는 가중치를 8비트나 4비트처럼 더 적은 비트로 줄여 저장하는 방법이다. Hugging Face 가이드글는 8비트·4비트로 정밀도를 낮춰도 성능이 크게 떨어지지 않으면서 계산상 이점을 얻을 수 있다는 연구를 소개한다. 바이트 수로 셈해 보면, 가중치는 8비트에서 파라미터 X billion당 약 X GB, 4비트에서 약 X/2 GB다. 70B 모델이라면 4비트에서 가중치만 약 35GB라는 어림이 나온다. vLLM 문서글에 따르면 이 엔진은 FP8, INT8, INT4, GPTQ·AWQ, GGUF 같은 양자화 형식을 지원한다. GPTQ·AWQ는 가중치 양자화 방식이고, GGUF는 로컬 실행에서 흔히 쓰는 파일 형식이다.
주의할 점이 두 가지 있다. 첫째, 양자화가 품질에 미치는 영향은 모델과 작업마다 다르다. 그러니 꼭 내 업무의 평가 세트로 확인해야 한다. 둘째, 가중치를 줄여도 KV 캐시는 따로 남는다. 긴 문서를 다루거나 동시 요청이 많은 서비스라면 가중치를 줄인 뒤에도 메모리가 모자랄 수 있다.
추론 엔진과 연속 배칭: 지연과 처리량의 균형
추론 엔진은 모델을 메모리에 올려 두고 여러 사용자의 요청을 받아 효율적으로 처리하는 서버 소프트웨어다. 요청 하나는 두 단계를 거친다. 먼저 프리필 단계에서 프롬프트 전체를 한 번에 처리하고, 이때 첫 토큰이 나온다. 여기까지 걸린 시간이 TTFT(첫 토큰까지 걸리는 시간)다. 이어지는 디코드 단계에서는 토큰을 하나씩 만들어 낸다. 사용자는 TTFT와 그 뒤 글자가 나오는 속도를 체감한다. 운영자는 GPU가 1초에 내놓는 토큰 수, 곧 처리량(토큰/초)을 본다. 처리량은 비용과 바로 이어진다.
지연과 처리량은 줄다리기 관계다. 여러 요청을 한꺼번에 묶으면 메모리에서 가중치를 한 번 읽어 여러 요청을 처리할 수 있으니 처리량이 오른다. 하지만 묶음이 커지면 각 요청이 기다리거나 한 단계가 느려져 지연이 늘 수 있다. 예전 방식에서는 묶음 전체가 끝나야 새 요청이 들어올 수 있었다. 연속 배칭은 디코드 단계마다 끝난 요청을 내보내고 기다리던 요청을 바로 끼워 넣어 GPU가 쉬는 틈을 줄인다. vLLM 문서글는 연속 배칭과 함께 chunked prefill(긴 프롬프트의 프리필을 잘라서 처리), prefix caching(같은 앞부분 재사용), 프리필·디코드 분리 실행을 지원 기능으로 소개한다.
vLLM의 핵심 기술은 페이지드 어텐션이다. vLLM 논문논문에 따르면 기존 시스템은 요청마다 최대 길이(예: 2,048 토큰)만큼 연속된 메모리를 미리 잡아 두었다. 그 결과 KV 캐시 메모리 가운데 실제 토큰 정보가 담긴 부분은 20.4~38.2%뿐이었다. 페이지드 어텐션은 운영체제의 가상 메모리처럼 KV 캐시를 고정 크기 블록으로 나누고, 필요할 때마다 블록을 할당한다. vLLM 블로그글는 이렇게 하면 낭비가 4% 미만으로 줄고, 한 프롬프트에서 답을 여러 개 뽑는 경우 메모리를 최대 55%까지 아낀다고 밝혔다. 논문은 같은 수준의 지연에서 FasterTransformer·Orca보다 처리량이 2~4배 높다고 보고했고, 블로그는 HF Transformers보다 최대 24배, TGI보다 최대 3.5배 높다고 밝혔다. 다만 이 배수들은 특정 모델·GPU·데이터로 낸 실험 결과다.
어텐션 계산 자체를 빠르게 하는 기술도 있다. FlashAttention논문은 어텐션을 작은 타일로 나눠 GPU 칩 안의 빠른 SRAM에서 계산한다. 그래서 상대적으로 느린 HBM(GPU의 고대역폭 메모리)에 읽고 쓰는 횟수가 줄어든다. 근사가 아니라 정확한 어텐션을 계산하면서도 GPT-2에서 어텐션 계산이 최대 7.6배 빨라졌고, 메모리 사용량은 시퀀스 길이에 비례하는 수준으로 줄었다. vLLM 문서글는 FlashAttention을 비롯한 최적화 어텐션 커널을 쓴다고 밝힌다.
GPU 한 장에 안 들어갈 때: 텐서 병렬과 파이프라인 병렬
Hugging Face 가이드글는 글을 쓸 당시 가장 큰 GPU였던 A100·H100의 메모리가 80GB라고 적었다. 그리고 가이드가 예로 든 모델 대부분은 올리는 것만으로도 80GB를 넘기 때문에 텐서 병렬이나 파이프라인 병렬이 필요하다고 설명한다. 실무에서는 GPU를 늘리기 전에 양자화로 한 장에 넣을 수 있는지부터 따져 보는 편이 단순하다.
텐서 병렬은 각 층 안의 큰 행렬을 여러 GPU가 쪼개 나눠 계산한 뒤 결과를 합치는 방식이다. Megatron-LM논문은 이런 층 내부 모델 병렬을 PyTorch에 통신 연산 몇 개만 넣어 구현했다. 이 방식은 파이프라인 병렬과 함께 쓸 수 있다. 이 연구는 GPU 512장에서 15.1 PetaFLOPs를 유지했고, GPU 한 장일 때와 비교해 76%의 확장 효율을 냈다. 텐서 병렬은 층마다 GPU끼리 결과를 주고받아야 하므로 GPU 사이 연결(인터커넥트)이 빨라야 한다. 그래서 보통 같은 서버 안의 GPU끼리 묶는다.
파이프라인 병렬은 층을 순서대로 잘라 앞쪽 층은 GPU A에, 뒤쪽 층은 GPU B에 올리는 방식이다. 주고받는 통신은 적다. 하지만 Hugging Face 가이드글는 단순한 파이프라인 병렬로는 앞 GPU가 일하는 동안 뒤 GPU가 노는 문제를 해결하지 못해 더 발전된 방식이 필요하다고 지적한다. vLLM 문서글에 따르면 이 엔진은 분산 추론을 위해 텐서·파이프라인·데이터·전문가·컨텍스트 병렬을 지원한다. 이 가운데 데이터 병렬은 모델 복제본을 여러 개 띄우는 방식으로, 한 장에 들어가는 모델의 처리량을 늘릴 때 쓴다.
단계별 적용: 배포 방식 고르기와 비용 어림
처음 시작한다면 다음 순서를 권한다. 첫째, 요구사항을 적는다. 하루 요청 수, 요청당 평균 입력·출력 토큰, 허용할 수 있는 TTFT, 데이터를 외부로 보내도 되는지를 정한다. 둘째, 메모리를 어림한다. '파라미터 × 바이트'로 가중치를 셈하고 KV 캐시 몫을 여유로 남긴다. 셋째, 배포 방식을 고른다. 넷째, 비용을 계산한다. 다섯째, 부하 테스트로 TTFT와 처리량을 실제로 재고 배치 크기와 GPU 수를 조정한다.
배포 방식은 크게 네 가지다. 클라우드 API는 모델 회사의 API를 쓴 토큰만큼 돈을 내고 쓰는 방식이다. 운영 부담이 가장 적지만 데이터가 외부로 나간다. GPU 클라우드는 GPU를 시간 단위로 빌려 추론 엔진을 직접 띄우는 방식이다. 오픈웨이트 모델을 자유롭게 고를 수 있지만 운영은 직접 해야 한다. 자체 서버는 장비 구입, 전력, 운영 인력이 필요하다. 대신 데이터가 내부에 머물고, 사용량이 꾸준히 많을 때 유리하다. 로컬 실행(로컬 LLM)은 PC나 노트북에서 작은 모델이나 양자화된 모델을 돌리는 방식으로, 개인 시험용에 맞는다. vLLM은 OpenAI API와 호환되는 서버를 띄울 수 있다글글. 그래서 API를 쓰다가 직접 운영으로 옮길 때 앱 코드를 덜 고쳐도 된다.
비용 어림은 다음과 같이 한다. API라면 '월 비용 ≈ 월 요청 수 × (평균 입력 토큰 × 입력 단가 + 평균 출력 토큰 × 출력 단가)'다. 입력과 출력의 단가가 따로 매겨지는 경우가 많으므로 나눠서 셈한다. 예시로 하루 1,000건, 건당 입력 2,000 토큰·출력 500 토큰이라면 하루 입력 200만 토큰, 출력 50만 토큰이다. 30일이면 입력 6,000만 토큰, 출력 1,500만 토큰이 되고, 여기에 각 단가를 곱한다.
직접 운영한다면 '토큰당 비용 ≈ GPU 시간당 비용 ÷ 시간당 처리 토큰 수'로 본다. 처리량이 두 배가 되면 토큰당 비용은 절반이 된다. vLLM 블로그글에 따르면 LMSYS는 vLLM을 도입해 같은 트래픽을 처리하는 데 드는 GPU 수를 50% 줄였다. 반대로 요청이 적어 GPU가 놀아도 시간당 비용은 그대로 나간다. 그래서 사용량이 적거나 들쭉날쭉하면 API가, 꾸준히 많으면 직접 운영이 유리해지기 쉽다.
배포 방식 네 가지 비교
| 초기 비용 낮음 | 데이터 내부 보관 | 운영 부담 적음 | 모델 선택 자유 | |
|---|---|---|---|---|
| 클라우드 API | ✓ | ✕ | ✓ | △ |
| GPU 클라우드 | ✓ | △ | △ | ✓ |
| 자체 서버 | ✕ | ✓ | ✕ | ✓ |
| 로컬 실행 | ✓ | ✓ | △ | △ |
점검 목록과 흔한 실수
배포 전에는 세 묶음을 확인한다. 메모리 쪽에서는 가중치를 정밀도에 맞는 바이트 수로 셈했는지, KV 캐시를 위한 여유를 남겼는지, 양자화한 뒤 품질을 평가했는지 본다. 성능 쪽에서는 TTFT 목표를 정했는지, 처리량(토큰/초)을 실제 부하로 쟀는지, 연속 배칭을 지원하는 추론 엔진을 쓰는지 본다. 비용·운영 쪽에서는 입력·출력 토큰을 나눠 셈했는지, GPU 사용률을 지켜보는지, 데이터를 외부로 보낼 때의 사내 규칙을 확인했는지 본다.
흔한 실수는 다음과 같다. 가중치만 셈하고 KV 캐시를 잊어 긴 요청에서 메모리가 모자란다. '최대 24배' 같은 벤치마크 배수를 내 환경에서도 그대로 기대한다. 처리량만 올리다가 TTFT가 늘어 사용자 체감이 나빠진다. 단순한 파이프라인 병렬로 GPU를 여러 장 쓰면서 대부분의 시간을 놀린다. 요청이 적은데 자체 서버를 들여 GPU 사용률이 낮게 머문다.
한계도 알아 둬야 한다. 이 글의 수치는 특정 시점의 자료에서 왔다. 예를 들어 '가장 큰 GPU가 80GB'라는 말은 Hugging Face 가이드글가 쓰일 당시 기준이다. 하드웨어와 엔진은 빠르게 바뀌므로, 실제로 결정할 때는 최신 문서와 직접 잰 값으로 다시 확인해야 한다.
배포 전 점검 목록
메모리
- 가중치를 정밀도별 바이트로 셈했나
- KV 캐시 여유를 남겼나
- 양자화 후 품질을 평가했나
성능
- TTFT 목표를 정했나
- 처리량을 실제 부하로 쟀나
- 연속 배칭 엔진을 쓰나
비용·운영
- 입력·출력 토큰을 나눠 셈했나
- GPU 사용률을 지켜보나
- 데이터 반출 규칙을 확인했나
더 공부하려면
처음에는 Hugging Face 가이드글를 읽기를 권한다. 가중치 메모리 셈법, 정밀도, FlashAttention, MQA·GQA 같은 구조 개선을 코드 예제와 함께 차례로 보여 준다. 다음으로 vLLM 블로그글에서 페이지드 어텐션이 KV 캐시를 블록으로 관리하는 방식을 그림으로 익히면 좋다.
원리를 더 깊이 보려면 vLLM 논문논문을 읽는다. 메모리 낭비가 어디서 생기는지와 스케줄링 설계가 자세히 나온다. FlashAttention논문은 GPU 안의 HBM과 SRAM이라는 메모리 계층을 이해하는 데 좋다. 모델 병렬화의 출발점을 알고 싶다면 Megatron-LM논문이 텐서 병렬을 어떻게 구현했는지 살펴본다.
직접 해 보려면 vLLM 문서글의 기능 목록에서 연속 배칭, 양자화, 병렬화 옵션을 확인하고 Quickstart 가이드로 작은 모델부터 띄워 본다. 띄운 뒤에는 TTFT와 처리량을 직접 재 보는 것이 가장 좋은 공부다.
관련 용어
참고 문헌
참고 자료(공식 문서·엔지니어링 글)
- Optimizing LLMs for Speed and Memory · Hugging Face (huggingface.co)
- vLLM: Easy, Fast, and Cheap LLM Serving with PagedAttention | vLLM Blog (blog.vllm.ai)
- vLLM (docs.vllm.ai)
핵심 논문
AI가 참고 문헌을 바탕으로 작성하고 검수를 거친 해설입니다. 정확한 내용은 원문을 확인해 주세요.