Skip to main content

계산할 줄 아는 사람이 GPU를 덜 낭비한다

LLM을 로컬에서 돌리려는 사람에게 가장 위험한 문장은 "이 정도면 되겠지"다. 24GB 그래픽카드를 샀는데 70B 모델이 느리게나마 돌아갈 줄 알았고, 48GB 카드라면 45GB 모델 파일이 넉넉히 들어갈 줄 알았고, 128K 컨텍스트를 지원하는 모델이라면 내 컴퓨터에서도 긴 PDF를 통째로 넣을 수 있을 줄 알았다. 하지만 GPU는 기대가 아니라 숫자로 움직인다.

VRAM 계산은 어렵지 않다. 다만 한 가지 습관이 필요하다. 모델 가중치만 보지 말고, 실행 중 생기는 모든 메모리 사용자를 한 줄씩 더해야 한다. LLM 추론에서 GPU 메모리는 보통 모델 가중치, KV 캐시, 활성값과 임시 버퍼, 프레임워크와 CUDA 오버헤드로 나뉜다. 여러 LLM 메모리 가이드도 실제 추론 메모리를 이 구성 요소들의 합으로 봐야 한다고 설명한다1.

이 장의 목표는 단순하다. 사용자가 보유한 GPU와 목표 모델을 놓고 "실행 가능", "간신히 가능", "멀티 GPU 필요", "이 모델은 포기해야 함"을 스스로 판정할 수 있게 만드는 것이다. 계산을 한 번 해보면 GPU 선택이 훨씬 차분해진다. 광고 문구보다 무서운 것은 산수다.

VRAM 요구량을 직접 계산하는 법

첫 번째 덩어리: 모델 가중치 계산

모델 가중치는 LLM의 본체다. 7B, 13B, 70B 같은 숫자는 파라미터 수를 뜻한다. 70B 모델은 대략 700억 개의 숫자를 갖고 있다. 이 숫자 하나를 몇 비트로 저장하느냐에 따라 필요한 VRAM이 달라진다.

가중치 메모리의 기본 공식은 다음과 같다.

가중치 메모리 = 파라미터 수 × 파라미터당 비트 수 ÷ 8

70B 모델을 FP16으로 올리면 파라미터 하나가 16비트, 즉 2바이트이므로 다음과 같이 계산한다.

70,000,000,000 × 16 ÷ 8 = 140,000,000,000 bytes

대략 140GB다. 이것만으로도 소비자용 24GB GPU 한 장은 애초에 후보가 아니다. 그래서 우리는 양자화를 사용한다. 양자화는 모델의 숫자를 더 낮은 정밀도로 저장해 메모리를 줄이는 방법이다. 다만 모든 4비트 형식이 정확히 4.00비트만 쓰는 것은 아니다. GGUF의 K-quant 계열처럼 블록 단위 스케일 정보와 메타데이터가 붙어 실제 bits per weight, 즉 bpw가 이름보다 커지는 형식도 있다2.

형식대략적인 파라미터당 메모리70B 가중치 예산특징
FP3232비트, 4바이트약 280GB추론에서는 거의 쓰지 않는 고정밀 형식
FP16 / BF1616비트, 2바이트약 140GB품질 기준선에 가까운 일반 추론 형식
FP88비트, 1바이트약 70GBHopper·Blackwell 계열에서 중요해진 저정밀 부동소수점
INT88비트, 1바이트약 70GB품질 손실이 작고 메모리는 FP16의 절반
INT44비트, 0.5바이트약 35GB가장 직관적인 4비트 계산값
AWQ / GPTQ 4-bit보통 4비트 안팎약 35GB 이상GPU 추론에 많이 쓰이는 4비트 양자화 형식
GGUF Q8_0약 8.5bpw약 74GBllama.cpp 계열에서 많이 쓰는 고품질 양자화
GGUF Q6_K약 6.57bpw약 57GB품질을 꽤 보존하면서 FP16보다 크게 절감
GGUF Q5_K_M약 5.67bpw약 50GB품질과 용량의 중간 지점
GGUF Q4_K_M약 4.83bpw약 42GB로컬 추론에서 자주 쓰는 균형점
EXL2사용자가 bpw 선택4.0bpw면 약 35GBNVIDIA GPU에서 빠르지만 모델이 VRAM에 완전히 들어가는 구성이 중요

여기서 첫 번째 함정이 나온다. "Q4니까 70B는 35GB겠네"라고 계산했는데, 실제로 받은 GGUF Q4_K_M 파일은 40GB를 넘을 수 있다. Q4_K_M은 품질을 위해 단순한 4.00bpw보다 조금 더 많은 정보를 저장한다. 반대로 GPTQ나 AWQ 4비트 모델은 더 4비트 계산에 가깝지만, 그룹 스케일이나 커널 처리 방식에 따른 오버헤드가 붙을 수 있다.

EXL2는 조금 다른 성격이다. EXL2는 특정 bpw를 목표로 만든 양자화 형식이며, NVIDIA GPU에서 빠른 추론을 목표로 많이 쓰인다. 다만 GGUF처럼 CPU와 GPU 사이에 유연하게 나눠 올리는 사용성보다는, 모델이 GPU VRAM 안에 제대로 들어갔을 때 강점을 보이는 쪽에 가깝다. 로컬 LLM 계산기들도 GGUF는 유연하고, EXL2는 빠르지만 VRAM에 맞지 않으면 실패하기 쉽다는 식으로 구분한다3.

가중치 계산을 손에 익히기

정밀도 표를 외울 필요는 없다. 다음 세 줄만 기억해도 1차 판단은 가능하다.

FP16/BF16 가중치 ≈ 모델 크기(B) × 2GB
INT8 가중치      ≈ 모델 크기(B) × 1GB
INT4 가중치      ≈ 모델 크기(B) × 0.5GB

이 계산법으로 보면 8B 모델은 FP16에서 약 16GB, INT4에서 약 4GB다. 32B 모델은 FP16에서 약 64GB, INT4에서 약 16GB다. 70B 모델은 FP16에서 약 140GB, INT4에서 약 35GB다. 이것은 "가중치만"의 값이다.

실전에서는 여기에 형식별 bpw를 반영한다. 예를 들어 70B 모델을 GGUF Q4_K_M으로 실행한다면 단순 INT4인 35GB가 아니라 42GB 안팎으로 잡는 편이 더 현실적이다. 32B 모델을 GGUF Q4_K_M으로 잡으면 다음처럼 계산한다.

32B × 4.83 ÷ 8 = 약 19.3GB

이 숫자만 보면 RTX 4090 24GB에 들어갈 것처럼 보인다. 하지만 24GB 중 19.3GB를 가중치가 차지하면 남는 공간은 4.7GB뿐이다. 여기서 KV 캐시, CUDA 오버헤드, 활성값, 프레임워크 버퍼가 들어와야 한다. 짧은 채팅은 가능할 수 있지만, 32K 컨텍스트나 여러 요청을 기대하기는 어렵다.

두 번째 덩어리: KV 캐시 계산

모델 가중치는 고정 비용이다. 한 번 모델을 올리면 프롬프트가 짧든 길든 가중치 크기는 크게 변하지 않는다. 반면 KV 캐시는 사용자가 넣는 문맥과 생성되는 답변에 따라 계속 커지는 동적 비용이다.

KV 캐시는 attention 연산에서 이전 토큰의 Key와 Value를 저장한 것이다. 새 토큰을 생성할 때 이전 모든 토큰을 처음부터 다시 계산하지 않기 위해 저장해둔다. 속도는 빨라지지만, 컨텍스트가 길수록 메모리는 늘어난다.

공식은 다음과 같다.

KV 캐시 메모리 = 2 × 레이어 수 × KV 헤드 수 × 헤드 차원
              × 시퀀스 길이 × 배치 크기 × 원소당 바이트 수

조금 더 짧게 쓰면 다음과 같다.

M_kv = 2 × L × H_kv × D_head × S × B × bytes

각 항목의 의미는 이렇다.

기호의미예시
2Key와 Value 두 종류를 저장고정값
Ltransformer 레이어 수Llama 70B는 80
H_kvKV 헤드 수Llama 70B는 8
D_head헤드 하나의 차원보통 128
S시퀀스 길이, 즉 총 토큰 수8K, 32K, 128K
B배치 크기 또는 동시 요청 수개인 사용은 1, 서버는 4·8·16 이상
bytesKV 캐시 원소당 바이트FP16/BF16은 2, FP8은 1

중요한 점은 모든 항목이 곱셈으로 연결되어 있다는 것이다. 컨텍스트 길이를 2배로 늘리면 KV 캐시도 2배다. 동시 요청 수를 8배로 늘리면 KV 캐시도 8배다. KV 캐시 공식과 이 선형 증가 특성은 여러 KV 캐시 메모리 분석에서 공통적으로 설명된다4.

Llama 70B로 직접 계산해보기

이제 실제로 계산해보자. Llama 3.1/3.3 계열 70B 모델은 대략 다음과 같은 attention 구조를 갖는 것으로 계산할 수 있다.

항목값
레이어 수 L80
KV 헤드 수 H_kv8
헤드 차원 D_head128
KV 캐시 dtypeBF16 또는 FP16
원소당 바이트2

먼저 토큰 하나가 KV 캐시에서 차지하는 메모리를 구한다.

토큰당 KV 캐시 = 2 × 80 × 8 × 128 × 2 bytes
              = 327,680 bytes

327,680바이트는 약 320KB다. 토큰 하나만 보면 작다. 하지만 LLM은 토큰을 수천, 수만, 수십만 개씩 다룬다.

4,096토큰이라면 다음과 같다.

327,680 × 4,096 = 1,342,177,280 bytes

즉 약 1.25GiB, 십진 표기로는 약 1.34GB다. 32K 컨텍스트라면 4K의 8배이므로 약 10GiB다. 128K 컨텍스트라면 약 40GiB, 십진 표기로는 약 43GB다. Spheron의 KV 캐시 예시에서도 Llama 3.1 70B가 128K 컨텍스트에서 단일 요청만으로 약 42.9GB의 KV 캐시를 요구한다고 계산한다5.

Llama 70B, BF16/FP16 KV 캐시배치 1배치 4배치 8
4K 컨텍스트약 1.3GB약 5.4GB약 10.7GB
8K 컨텍스트약 2.7GB약 10.7GB약 21.5GB
32K 컨텍스트약 10.7GB약 42.9GB약 85.9GB
128K 컨텍스트약 42.9GB약 171.8GB약 343.6GB

이 표를 보면 왜 70B 모델이 무서운지 감이 온다. 70B를 4비트로 양자화해 가중치를 35~42GB 수준으로 줄였다고 해도, 128K 컨텍스트 단일 요청의 KV 캐시가 그만큼 또는 그 이상을 먹는다. 배치 8이라면 KV 캐시만 300GB를 넘는다. 모델이 커서만 문제가 아니라, 문맥과 동시성이 함께 커지기 때문이다.

GQA 때문에 계산이 달라진다

KV 캐시 계산에서 가장 자주 틀리는 부분은 헤드 수다. 많은 사람이 attention head 수를 그대로 KV 헤드 수에 넣는다. 하지만 최신 LLM은 Grouped Query Attention, 줄여서 GQA를 많이 쓴다. GQA에서는 여러 Query 헤드가 더 적은 수의 Key/Value 헤드를 공유한다.

예를 들어 Llama 70B는 Query 헤드가 64개인 구조로 알려져 있지만, KV 헤드는 8개로 계산한다. 만약 실수로 64를 넣으면 KV 캐시가 8배로 부풀려진다.

잘못된 계산: H_kv = 64
올바른 계산: H_kv = 8
차이: 64 ÷ 8 = 8배

반대로 오래된 MHA, 즉 Multi-Head Attention 모델은 Query 헤드 수와 KV 헤드 수가 같을 수 있다. 이 경우 같은 파라미터 규모라도 KV 캐시가 훨씬 커진다. 모델 카드를 볼 때 num_key_value_heads, n_kv_heads, num_kv_heads 같은 항목을 반드시 확인해야 한다. 없다면 Hugging Face의 config.json을 열어보는 것이 가장 빠르다.

KV 캐시 dtype도 따로 봐야 한다

또 하나의 함정이 있다. 모델 가중치를 INT4로 양자화했다고 해서 KV 캐시도 자동으로 INT4가 되는 것은 아니다. 많은 추론 환경에서 모델 가중치는 4비트지만 KV 캐시는 FP16 또는 BF16으로 유지된다. 그러면 긴 컨텍스트에서는 양자화로 줄인 가중치보다 KV 캐시가 더 커질 수 있다.

KV 캐시 dtype을 FP8로 낮추면 FP16/BF16 대비 KV 캐시 메모리를 절반으로 줄일 수 있다. 더 낮은 정밀도의 KV 캐시도 연구되고 있고, 일부 하드웨어와 프레임워크에서는 FP8 또는 FP4 계열 KV 캐시를 지원한다. 다만 이것은 "항상 켜도 되는 무료 옵션"이 아니다. 하드웨어 세대, 추론 엔진, 커널 지원, 모델 품질 검증을 함께 봐야 한다. 특히 긴 추론이나 복잡한 reasoning 작업에서는 품질 저하가 없는지 반드시 테스트해야 한다.

예를 들어 Llama 70B, 32K 컨텍스트, 배치 8의 KV 캐시가 BF16에서 약 85.9GB라면 FP8 KV 캐시는 대략 절반인 약 42.9GB가 된다. 이 차이는 GPU 한두 장의 차이를 만들 수 있다. 하지만 FP8 KV 캐시를 쓸 수 있는지, 그리고 성능 이득이 있는지는 A100, H100, Blackwell 계열처럼 하드웨어마다 다르게 봐야 한다.

세 번째 덩어리: 활성값, 임시 버퍼, 런타임 오버헤드

가중치와 KV 캐시를 계산했다면 이제 남은 것은 실행 비용이다. 추론 중에는 각 레이어를 통과하며 중간 계산 결과가 생긴다. 이를 활성값이라고 부른다. 학습에서는 활성값을 역전파를 위해 오래 붙잡아야 하므로 매우 커지지만, 추론에서는 상대적으로 작다. 그래도 0은 아니다.

추론 엔진도 자기 몫을 가져간다. CUDA 컨텍스트, 메모리 allocator, attention 커널 workspace, 그래프 캡처, NCCL 통신 버퍼, 샘플링용 logits, 메모리 단편화가 모두 VRAM을 사용한다. 단일 GPU 로컬 추론에서는 대략 1~3GB 정도를 최소 여유로 보는 경우가 많고, 프로덕션 서빙이나 멀티 GPU에서는 더 넉넉하게 잡아야 한다.

실무에서는 다음처럼 계산하는 것이 안전하다.

총 VRAM ≈ 모델 가중치 + KV 캐시 + 활성값/임시 버퍼 + 런타임 오버헤드 + 안전 여유

간단히 시작하고 싶다면 다음처럼 잡을 수 있다.

총 VRAM ≈ 모델 가중치 + KV 캐시 + 2~6GB + 안전 여유

하지만 이 공식은 단일 사용자나 작은 배치에서만 편하다. API 서버처럼 요청이 계속 들어오고, continuous batching을 사용하고, 긴 프롬프트가 섞이는 환경에서는 오버헤드를 고정 2GB로 보면 안 된다. 실제 운영에서는 메모리 단편화와 피크 요청까지 고려해 훨씬 보수적으로 잡아야 한다.

40~50% 여유 규칙

초보자가 가장 자주 하는 실수는 GPU VRAM의 80~90%를 모델 가중치로 채우는 것이다. 이 구성은 "로드 성공"에는 가까울 수 있지만 "안정적인 추론"과는 멀다. 사용자가 긴 프롬프트를 넣는 순간 KV 캐시가 자라며 바로 한계에 닿는다.

로컬 실험이 아니라 실제로 편하게 쓰고 싶다면, 전체 VRAM의 40~50%를 KV 캐시와 런타임 여유분으로 남기는 기준을 권한다. 다시 말해 모델 가중치는 전체 VRAM의 50~60% 안에 들어오는 편이 좋다.

예를 들어 24GB GPU라면 가중치를 20GB까지 채우는 모델은 매우 빡빡하다. 짧은 컨텍스트에서는 실행될 수 있지만, 16K나 32K 컨텍스트를 쓰면 금방 불안정해진다. 반면 가중치가 10~14GB 수준이면 KV 캐시와 오버헤드에 10GB 안팎을 남길 수 있어 훨씬 편하다.

48GB 멀티 GPU 구성도 마찬가지다. 70B GGUF Q4_K_M 가중치가 약 42GB라면 총 VRAM 48GB에서 남는 공간은 6GB뿐이다. 여기에 CUDA, 프레임워크, 통신 버퍼, KV 캐시가 들어와야 한다. 아주 짧은 컨텍스트에서는 로드될 수 있지만, Llama 70B의 32K KV 캐시만 약 10GB이므로 32K 문맥은 이미 어렵다. "2×24GB면 70B Q4가 된다"는 말은 조건을 생략한 표현이다. 정확히는 "짧은 컨텍스트와 낮은 동시성에서는 가능할 수 있다"에 가깝다.

직접 계산하는 5단계 절차

이제 실제로 어떤 모델이 내 GPU에서 가능한지 판단하는 절차를 정리해보자.

1단계: 목표 모델의 파라미터 수를 확인한다

모델 이름의 7B, 14B, 32B, 70B를 확인한다. MoE 모델이라면 전체 파라미터와 활성 파라미터를 구분해야 한다. 가중치 메모리는 대체로 전체 파라미터를 기준으로 잡는다. "A3B"처럼 활성 파라미터가 작아도 전체 전문가 가중치를 올려야 하는 경우가 많다.

2단계: 가중치 정밀도 또는 양자화 형식을 고른다

FP16인지, INT8인지, AWQ/GPTQ 4비트인지, GGUF Q4_K_M인지, EXL2 몇 bpw인지 정한다. 그리고 다음 공식을 적용한다.

가중치 GB ≈ 모델 크기(B) × bpw ÷ 8

8B FP16이면 8 × 16 ÷ 8 = 16GB다. 70B Q4_K_M이면 70 × 4.83 ÷ 8 = 약 42GB다.

3단계: 목표 컨텍스트와 동시 요청 수를 정한다

컨텍스트는 입력 프롬프트만이 아니다. 시스템 프롬프트, 이전 대화, RAG로 붙인 문서, 사용자의 질문, 모델이 생성할 답변까지 포함된다. 개인 로컬 추론이면 배치 크기 B는 보통 1이다. API 서버라면 동시에 처리할 요청 수나 continuous batching으로 묶일 시퀀스 수를 B로 잡는다.

4단계: KV 캐시를 계산한다

모델의 레이어 수, KV 헤드 수, 헤드 차원을 확인한다. Hugging Face 모델 폴더의 config.json에서 찾을 수 있다. num_hidden_layers, num_key_value_heads, head_dim 또는 hidden_size ÷ num_attention_heads를 보면 된다.

KV 캐시 = 2 × L × H_kv × D_head × S × B × bytes

FP16/BF16 KV 캐시는 bytes에 2를 넣는다. FP8 KV 캐시를 확실히 사용한다면 1을 넣는다.

5단계: 오버헤드와 안전 여유를 더한다

마지막으로 활성값, CUDA, 프레임워크, 메모리 단편화, 통신 버퍼를 더한다. 로컬 단일 GPU는 최소 2~4GB, 프로덕션 서버나 멀티 GPU는 그 이상을 잡는 편이 좋다. 그리고 최종값이 GPU VRAM의 90%에 붙어 있으면 "가능"이 아니라 "위험"으로 분류한다.

예제 1: RTX 4090 24GB에서 32B Q4 모델

가정해보자. 사용자는 RTX 4090 24GB 한 장을 갖고 있고, 32B 모델을 GGUF Q4_K_M으로 실행하고 싶다. 컨텍스트는 8K, 단일 사용자다.

먼저 가중치다.

32 × 4.83 ÷ 8 = 약 19.3GB

이미 24GB 중 19.3GB를 썼다. 남은 공간은 약 4.7GB다. 여기에 KV 캐시가 들어간다. 모델마다 구조가 다르지만 32B급 모델에서 8K 컨텍스트는 대략 1~2GB 이상의 KV 캐시를 잡아먹을 수 있다. CUDA와 프레임워크 오버헤드를 2GB만 잡아도 거의 한계다.

이 구성의 판정은 "짧은 컨텍스트에서는 가능할 수 있지만 여유가 작다"다. 4K 컨텍스트로 줄이면 안정성이 올라간다. 16K나 32K를 원하면 더 낮은 양자화, KV 캐시 양자화, CPU 오프로딩, 또는 48GB급 GPU가 필요해진다.

예제 2: 2×RTX 3090 48GB에서 70B 4비트 모델

이번에는 24GB GPU 두 장, 총 48GB 구성이다. 목표는 Llama 70B 4비트다. 많은 사용자가 이 구성을 70B 입문점으로 생각한다.

AWQ나 GPTQ 4비트로 가중치를 약 35GB로 잡으면 남는 총량은 13GB다. GGUF Q4_K_M처럼 42GB 안팎이면 남는 총량은 6GB다. 단순히 총 VRAM만 보면 AWQ/GPTQ 쪽이 더 가능성이 높다.

Llama 70B의 KV 캐시는 앞에서 계산했다. 8K 컨텍스트 단일 요청은 약 2.7GB, 32K 컨텍스트 단일 요청은 약 10.7GB다. 여기에 런타임 오버헤드와 멀티 GPU 통신 버퍼가 붙는다.

따라서 2×24GB에서 70B 4비트는 다음처럼 판단하는 것이 현실적이다.

조건판정
4K~8K, 단일 사용자, 가벼운 런타임가능성이 있음
32K, 단일 사용자매우 빡빡하거나 실패 가능
32K, 여러 동시 요청사실상 부족
128K 컨텍스트총 48GB로는 KV 캐시 때문에 불가능에 가까움

이 예제의 교훈은 선명하다. 멀티 GPU의 총 VRAM이 모델 가중치보다 크다고 해서 끝이 아니다. KV 캐시와 오버헤드까지 올려야 한다.

예제 3: 70B FP16 서버를 계획한다면

이제 프로덕션에 가까운 계산을 해보자. 70B 모델을 FP16/BF16으로 서빙하고 싶다. 가중치만 약 140GB다. 컨텍스트는 32K, 동시에 4개 요청을 처리한다고 하자.

KV 캐시는 다음과 같다.

Llama 70B, 32K, batch 4 ≈ 42.9GB

이제 합친다.

가중치 140GB + KV 캐시 42.9GB = 182.9GB

여기에 활성값, 프레임워크, CUDA, 통신 버퍼, 안전 여유를 넣으면 200GB 이상을 보는 것이 자연스럽다. H100 80GB 두 장, 총 160GB로는 가중치와 일부 KV 캐시조차 빠듯하다. 4장 구성이나 H200 같은 더 큰 메모리 GPU, 또는 FP8/INT8/INT4 가중치와 KV 캐시 최적화를 고려해야 한다.

이 계산을 하고 나면 왜 프로덕션 70B 서빙에서 96~160GB 이상, 긴 컨텍스트나 높은 동시성에서는 그보다 훨씬 큰 VRAM 예산이 언급되는지 이해할 수 있다. "70B는 140GB"가 아니라 "70B FP16에 내가 원하는 컨텍스트와 동시성을 더하면 얼마인가"가 진짜 질문이다.

사용 시나리오별 VRAM 예산은 다르다

같은 모델이라도 어떻게 쓰느냐에 따라 필요한 VRAM이 완전히 달라진다. 8B 모델 하나를 두고도 개인 채팅, 긴 문서 RAG, 멀티턴 챗봇, API 서버는 서로 다른 시스템이다.

시나리오보통의 컨텍스트배치/동시성VRAM 압박의 주범예산 전략
단일 사용자 로컬 추론4K~8K1모델 가중치Q4/Q5 모델과 적당한 여유 확보
긴 컨텍스트 RAG16K~128K1~4KV 캐시와 prefill컨텍스트 제한, 검색 문서 압축, KV 캐시 dtype 검토
멀티턴 챗봇8K~32K 이상사용자 수만큼 증가누적 대화 기록히스토리 요약, 오래된 메시지 제거, 세션별 한도 설정
고동시성 API 서버4K~32K8~수십 이상KV 캐시 × 동시 요청PagedAttention, continuous batching, max_model_len 제한, 충분한 GPU 수

단일 사용자 로컬 추론은 비교적 단순하다. 배치가 1이고, 컨텍스트도 짧다면 가중치가 가장 큰 비중을 차지한다. 이때는 "내 GPU에 어떤 양자화 모델이 들어가는가"가 핵심이다.

긴 컨텍스트 RAG는 다르다. 검색된 문서 여러 개를 프롬프트에 붙이고, 시스템 프롬프트와 질문까지 더하면 16K, 32K, 64K가 쉽게 된다. 여기서는 작은 모델도 KV 캐시가 빠르게 커진다. RAG에서 가장 싼 최적화는 무조건 더 큰 GPU가 아니라, 필요 없는 문서를 덜 넣고, 문서를 요약하고, 검색 결과를 더 정확히 고르는 것이다.

멀티턴 챗봇은 시간이 지날수록 문제가 생긴다. 첫 질문과 답변은 짧지만, 대화가 20턴, 50턴 쌓이면 이전 메시지가 모두 컨텍스트에 포함된다. 사용자는 "방금 전 대화를 기억해줘"라고 기대하지만, GPU 입장에서는 그 기억이 모두 KV 캐시 비용이다. 오래된 대화는 요약하거나 잘라내는 정책이 필요하다.

고동시성 API 서버는 가장 가혹하다. 요청 하나의 KV 캐시가 2GB라도 동시 요청 16개면 32GB다. 평균 요청은 짧아도, 긴 요청 몇 개가 섞이면 피크 메모리가 치솟는다. 이때는 vLLM의 PagedAttention처럼 KV 캐시를 블록 단위로 효율적으로 관리하는 추론 엔진이 중요해진다. PagedAttention은 요청마다 최대 컨텍스트를 통째로 예약하는 낭비를 줄이고, 필요한 블록을 동적으로 할당해 더 많은 요청을 같은 GPU에서 처리하도록 돕는다5. 다만 이것도 KV 캐시 자체의 물리적 크기를 없애는 마법은 아니다.

VRAM 부족을 해결하는 순서

계산 결과가 GPU VRAM을 넘었다고 해서 바로 새 GPU를 사야 하는 것은 아니다. 먼저 줄일 수 있는 것부터 줄여야 한다.

가장 먼저 컨텍스트 길이를 줄인다. 32K를 8K로 낮추면 KV 캐시가 4분의 1이 된다. 모델을 바꾸지 않고도 효과가 크다. 다음으로 양자화 수준을 조정한다. FP16에서 INT8로, INT8에서 Q4로 내려가면 가중치 메모리가 크게 줄어든다. 그다음 KV 캐시 dtype을 검토한다. 프레임워크와 하드웨어가 지원한다면 FP8 KV 캐시로 긴 컨텍스트 비용을 줄일 수 있다.

그래도 부족하면 모델 규모를 낮추거나, 더 작은 active parameter를 가진 MoE 모델을 검토하거나, 멀티 GPU로 넘어간다. CPU 오프로딩은 마지막 선택지에 가깝다. 실행 자체는 가능하게 만들지만, VRAM 대신 시스템 RAM과 PCIe를 쓰기 때문에 속도가 크게 떨어질 수 있다. 특히 대화형 사용에서는 토큰 생성 속도가 답답해진다.

내 GPU로 가능한지 빠르게 판정하는 법

계산을 매번 길게 하기 번거롭다면 다음 판정 기준을 써도 좋다.

먼저 가중치가 전체 VRAM의 60%를 넘는지 본다. 넘는다면 긴 컨텍스트는 어렵다고 가정한다. 다음으로 목표 컨텍스트의 KV 캐시를 계산한다. 가중치와 KV 캐시를 더했을 때 전체 VRAM의 80%를 넘으면 실전에서는 위험하다. 마지막으로 런타임 여유를 최소 10~20%, 가능하면 40~50%까지 확보할 수 있는지 본다.

예를 들어 24GB GPU에서 가중치가 14GB인 모델은 출발점이 좋다. KV 캐시와 오버헤드에 10GB가 남는다. 반면 가중치가 21GB인 모델은 시작부터 위험하다. 3GB 안에 KV 캐시와 런타임을 모두 넣어야 하기 때문이다.

48GB 총 VRAM에서 가중치가 35GB인 모델은 짧은 컨텍스트에서는 가능성이 있다. 하지만 32K 이상의 긴 문맥을 요구하면 KV 캐시가 10GB 이상 붙을 수 있으므로 곧 한계에 닿는다. 80GB GPU에서 가중치가 42GB인 모델은 훨씬 편하다. 같은 모델이라도 남는 38GB가 컨텍스트와 동시성을 살린다.

스프레드시트로 만들면 GPU 구매가 쉬워진다

진지하게 GPU를 구매하거나 서버를 설계한다면 간단한 스프레드시트를 만드는 것이 좋다. 열은 다음 정도면 충분하다.

항목입력값 예시
모델 파라미터 B70
가중치 bpw4.83
가중치 GBB × bpw ÷ 8
레이어 수80
KV 헤드 수8
헤드 차원128
컨텍스트 길이32768
동시 요청 수1, 4, 8
KV dtype bytes2 또는 1
KV 캐시 GB공식으로 계산
오버헤드 GB3~10
총 필요 VRAM가중치 + KV + 오버헤드
보유 GPU 총 VRAM24, 48, 80, 160
판정가능 / 위험 / 불가

이 표를 만들어두면 모델이 바뀌어도 겁나지 않는다. Llama 70B든 Qwen 32B든 Mistral 24B든, 결국 숫자를 바꿔 넣으면 된다. GPU 구매도 감이 아니라 시뮬레이션이 된다.

계산은 포기의 기술이기도 하다

VRAM 계산을 하면 기분이 좋아지기만 하지는 않는다. 오히려 어떤 모델은 포기해야 한다는 사실을 일찍 알려준다. 24GB GPU 한 장으로 70B Q4를 32K 컨텍스트에서 쾌적하게 쓰고 싶다는 목표는 숫자상 맞지 않는다. 48GB 총 VRAM으로 70B를 로드할 수는 있어도, 긴 컨텍스트와 동시 사용자를 기대하면 금방 막힌다. 128K RAG 서버를 운영하려면 모델 가중치보다 KV 캐시 예산이 더 중요한 순간도 온다.

하지만 이것은 나쁜 소식이 아니다. 계산을 모르면 GPU를 사고 나서 실패한다. 계산을 알면 사기 전에 방향을 바꿀 수 있다. 모델을 70B에서 32B로 낮출 수도 있고, Q4_K_M 대신 더 낮은 bpw를 선택할 수도 있고, 컨텍스트를 32K에서 8K로 제한할 수도 있고, 처음부터 2장 또는 4장 GPU 구성을 설계할 수도 있다.

멀티 GPU는 이 계산에서 출발한다. 한 장에 안 들어가니까 여러 장을 쓴다. 하지만 여러 장을 쓰더라도 총 VRAM이 가중치만 겨우 담는 수준이면 문제는 반복된다. 어떤 병렬화 전략을 쓰든, 모델 가중치와 KV 캐시와 런타임 여유가 모두 들어갈 자리를 마련해야 한다.

다음 장부터는 멀티 GPU를 쓰기 전에 반드시 확인해야 할 하드웨어와 소프트웨어 조건을 살펴볼 것이다. 그 전에 기억해야 할 문장은 하나다. "VRAM 요구량은 모델 크기가 아니라, 모델 크기와 컨텍스트와 동시성과 정밀도의 곱으로 결정된다." 이 문장을 이해하면 GPU 선택은 훨씬 덜 막연해진다.

참고

1GPU Memory Requirements for LLMs: VRAM Calculator

2LLM VRAM Calculator - Advanced GPU Memory Calculator for Large Language Models

3LLM VRAM Calculator: Can My GPU Run DeepSeek & Llama?

4KV Cache Memory: Calculating GPU Requirements for LLM Inference

5KV Cache Optimization: Serve 10x More Users on the Same GPU (2026)

책 목록

VRAM의 벽을 넘는 멀티 GPU LLM 운영 가이드

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기