Blog
llm-inferencequantizationkv-cacheoptimizationvllmai

LLM 추론 최적화 가이드 - 양자화, KV Cache, 추측적 디코딩

LLM 추론 최적화의 핵심 기법인 양자화(GPTQ, AWQ, GGUF), KV Cache 최적화, 추측적 디코딩, 배치 처리, 텐서 병렬, FlashAttention을 체계적으로 정리합니다.

Data Dynamics2026年4月16日12 min read
This post is not yet translated. The original Korean version is shown below.

LLM 추론 최적화는 제한된 GPU 자원에서 최대한의 처리량과 최소한의 지연시간을 달성하는 핵심 기술입니다. 이 글에서는 양자화, KV Cache, 추측적 디코딩 등 주요 최적화 기법을 체계적으로 다룹니다.


1. LLM 추론의 이해

추론 과정

LLM 추론은 **Prefill(입력 처리)**과 Decode(토큰 생성) 두 단계로 나뉩니다.

[LLM 추론 단계]

입력: "Spark 성능을 최적화하는 방법은?"
       ↓
[Prefill 단계] — 입력 토큰을 한 번에 병렬 처리
  - KV Cache 생성
  - 계산 집약적 (GPU 컴퓨트 바운드)
  - TTFT (Time to First Token) 결정
       ↓
[Decode 단계] — 토큰을 하나씩 순차 생성
  - KV Cache 읽기 + 업데이트
  - 메모리 집약적 (메모리 바운드)
  - TPS (Tokens Per Second) 결정
       ↓
출력: "Spark 성능을 최적화하려면 다음 방법을..."

핵심 성능 지표

지표설명영향 요소
TTFT첫 번째 토큰 생성 시간Prefill 속도, 모델 크기
TPS초당 생성 토큰 수Decode 속도, 메모리 대역폭
Throughput전체 처리량 (tok/s)배칭, GPU 활용률
Latency (P95)95번째 백분위 응답 시간큐잉, 스케줄링

GPU 메모리 구성

[7B 모델의 GPU 메모리 사용 (FP16)]

총 GPU 메모리: 24 GB (RTX 4090)

모델 가중치:     ██████████████  14 GB (58%)
KV Cache:       ████████         8 GB (33%)
활성화/임시:     ██               2 GB (9%)
                 ─────────────────────────
                 합계: 24 GB

→ KV Cache가 동시 요청 수를 결정하는 병목

2. 양자화 (Quantization)

양자화란

모델 가중치의 정밀도를 줄여 메모리 사용량과 연산량을 절감하는 기법입니다.

FP32 (32비트): 0.12345678901234567890  → 4바이트/파라미터
FP16 (16비트): 0.1235                  → 2바이트/파라미터 (2x 절감)
INT8 (8비트):  31                       → 1바이트/파라미터 (4x 절감)
INT4 (4비트):  7                        → 0.5바이트/파라미터 (8x 절감)

주요 양자화 방식 비교

방식비트품질 손실속도추론 환경대표 도구
FP16/BF1616없음기준GPU기본
GPTQ4매우 적음빠름GPU (CUDA)AutoGPTQ
AWQ4매우 적음매우 빠름GPU (CUDA)AutoAWQ
GGUF2~8방식에 따라보통CPU/GPUllama.cpp
BitsAndBytes4/8적음보통GPUHuggingFace
FP88거의 없음빠름H100+vLLM, TRT-LLM
AQLM2중간빠름GPU-

GGUF 양자화 (llama.cpp / Ollama)

# GGUF 양자화 수준별 비교 (LLaMA 3.1 8B)
# Q2_K:   2.7 GB  — 품질 저하 있음, 최소 메모리
# Q4_K_M: 4.1 GB  — 좋은 균형점 (가장 추천)
# Q5_K_M: 4.8 GB  — 우수한 품질
# Q6_K:   5.5 GB  — 높은 품질
# Q8_0:   7.2 GB  — 거의 원본 수준
# FP16:  14.0 GB  — 원본
 
# Ollama에서 양자화 모델 사용
ollama run llama3.1:8b-q4_K_M

AWQ 양자화 (GPU 서빙용)

# AWQ 양자화 모델을 vLLM으로 서빙
python -m vllm.entrypoints.openai.api_server \
    --model TheBloke/Llama-3.1-8B-Instruct-AWQ \
    --quantization awq \
    --max-model-len 4096

양자화 선택 가이드

[GPU 서빙인가?]
├─ Yes
│  ├─ H100/A100 → FP8 (최소 손실, 최고 속도)
│  ├─ A100/A10 → AWQ 4비트 (높은 품질, 빠른 속도)
│  └─ RTX 4090 → GPTQ 또는 AWQ 4비트
└─ No (CPU 또는 혼합)
   └─ GGUF Q4_K_M (Ollama/llama.cpp)

3. KV Cache 최적화

KV Cache란

Transformer의 Self-Attention 계산 시, 이전 토큰의 Key/Value를 캐싱하여 중복 계산을 방지합니다.

[KV Cache 없이]
토큰 1 생성: K,V 계산 (토큰 0)
토큰 2 생성: K,V 계산 (토큰 0, 1)        ← 토큰 0 재계산!
토큰 3 생성: K,V 계산 (토큰 0, 1, 2)     ← 토큰 0, 1 재계산!
→ O(n²) 연산

[KV Cache 사용]
토큰 1 생성: K,V 계산 (토큰 0) → 캐시 저장
토큰 2 생성: 캐시(토큰 0) + K,V 계산 (토큰 1) → 캐시 업데이트
토큰 3 생성: 캐시(토큰 0,1) + K,V 계산 (토큰 2) → 캐시 업데이트
→ O(n) 연산

KV Cache 메모리 계산

KV Cache 크기 = 2 × num_layers × num_heads × head_dim × seq_len × dtype_bytes

LLaMA 3.1 8B 예시:
= 2 × 32 × 32 × 128 × 4096 × 2(FP16)
= 2,147,483,648 bytes ≈ 2 GB (시퀀스 1개당)

→ 동시 10개 요청: ~20 GB의 KV Cache 필요!

PagedAttention (vLLM)

[기존: 연속 메모리 할당]
요청 1: [████████░░░░░░░░░░]  ← 최대 길이만큼 예약, 낭비 발생
요청 2: [██████░░░░░░░░░░░░]
요청 3: [메모리 부족]

[PagedAttention: 페이지 단위 할당]
요청 1: [█][█][█][█]          ← 필요한 만큼만 블록 할당
요청 2: [█][█][█]
요청 3: [█][█]                ← 남은 블록 활용!

→ 메모리 낭비 60~80% 감소
→ 동시 처리 가능 요청 수 2~4배 증가

MQA / GQA (Multi-Query / Grouped-Query Attention)

KV Cache 크기를 줄이는 아키텍처 수준의 최적화:

방식KV 헤드 수Cache 크기적용 모델
MHA (Multi-Head)Q=K=V 동일기준GPT-3
MQA (Multi-Query)K=V=11/32PaLM, Falcon
GQA (Grouped-Query)K=V 그룹1/4~1/8LLaMA 3, Gemma

4. 추측적 디코딩 (Speculative Decoding)

원리

작은 Draft 모델로 여러 토큰을 빠르게 생성하고, 큰 Target 모델로 한 번에 검증합니다.

[일반 디코딩]
Target(70B): 토큰 1 → 토큰 2 → 토큰 3 → 토큰 4 → 토큰 5
             (5 스텝, 각 스텝 느림)

[추측적 디코딩]
Draft(8B):   토큰 1,2,3,4,5 빠르게 생성 (1 스텝)
Target(70B): 5개 토큰을 한 번에 검증 → 4개 수락, 1개 재생성 (1 스텝)
             → 총 2 스텝으로 4개 토큰 생성 (2.5x 가속)

vLLM에서의 사용

# 추측적 디코딩 활성화
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-70B-Instruct \
    --speculative-model meta-llama/Llama-3.1-8B-Instruct \
    --num-speculative-tokens 5 \
    --speculative-draft-tensor-parallel-size 1

성능 효과

시나리오일반추측적 디코딩가속비
코드 생성 (반복 패턴 많음)30 tok/s75 tok/s2.5x
일반 대화30 tok/s55 tok/s1.8x
창작 글쓰기 (예측 어려움)30 tok/s40 tok/s1.3x

참고: 예측 가능성이 높은 태스크(코드, 형식화된 출력)에서 가속 효과가 큽니다.


5. 배치 처리와 스케줄링

Continuous Batching

[Static Batching]
배치 1: [요청A(100tok), 요청B(50tok), 요청C(200tok)]
→ 가장 긴 요청(C) 완료까지 전체 대기
→ A, B 완료 후에도 GPU 유휴

[Continuous Batching]
시점 1: [A, B, C] 동시 처리
시점 2: B 완료 → D 즉시 추가 [A, D, C]
시점 3: A 완료 → E 즉시 추가 [E, D, C]
→ GPU 유휴 시간 최소화

처리량 최적화 설정

# vLLM 최적화 설정
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-8B-Instruct \
    --max-num-seqs 256 \            # 최대 동시 시퀀스
    --max-num-batched-tokens 8192 \ # 배치당 최대 토큰
    --gpu-memory-utilization 0.9 \  # GPU 메모리 활용률
    --enable-chunked-prefill \      # 청크 프리필 활성화
    --max-model-len 4096

6. 추가 최적화 기법

FlashAttention

Attention 연산의 메모리 접근 패턴을 최적화하여 속도를 향상시킵니다.

버전속도 향상메모리 절감지원 GPU
FlashAttention-12~4xO(N) → O(√N)A100+
FlashAttention-25~9x (FP16)동일A100+
FlashAttention-31.5~2x (추가)FP8 지원H100

Prefix Caching

동일한 시스템 프롬프트를 공유하는 요청에서 프리픽스 KV Cache를 재사용합니다.

요청 1: [시스템 프롬프트 (공통)] + [사용자 질문 A]
요청 2: [시스템 프롬프트 (공통)] + [사용자 질문 B]
요청 3: [시스템 프롬프트 (공통)] + [사용자 질문 C]

→ 시스템 프롬프트의 KV Cache를 1번만 계산, 3번 재사용
→ TTFT 50~80% 감소 (시스템 프롬프트가 긴 경우)
# vLLM에서 Prefix Caching 활성화
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-8B-Instruct \
    --enable-prefix-caching

텐서 병렬 (Tensor Parallelism)

# 4개 GPU로 70B 모델 실행
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-70B-Instruct \
    --tensor-parallel-size 4
병렬 전략분할 대상적합 상황
Tensor Parallel레이어 내부 (가중치)단일 노드 멀티 GPU
Pipeline Parallel레이어 간 (깊이)멀티 노드
Data Parallel요청 (복제)동일 모델 N개 인스턴스

7. 최적화 전략 요약

시나리오별 최적화 가이드

목표핵심 기법기대 효과
모델 메모리 절감양자화 (AWQ/GGUF Q4)모델 크기 75% 감소
동시 처리량 증가PagedAttention + Continuous Batching처리량 2~4배
첫 토큰 속도 향상Prefix Caching + FlashAttentionTTFT 50~80% 감소
토큰 생성 속도 향상추측적 디코딩TPS 1.5~2.5배
대형 모델 실행텐서 병렬70B+ 모델 서빙 가능
비용 절감양자화 + 소형 모델GPU 비용 60~80% 절감

적용 우선순위 (권장)

1. 양자화 적용 (가장 쉽고 효과 큼)
   ↓
2. vLLM + Continuous Batching (서빙 엔진 전환)
   ↓
3. FlashAttention 활성화 (대부분 기본 적용)
   ↓
4. Prefix Caching (시스템 프롬프트 재사용)
   ↓
5. 추측적 디코딩 (대형 모델 가속)
   ↓
6. 텐서 병렬 (초대형 모델)

참고: 최적화 기법들은 대부분 조합하여 사용할 수 있습니다. 양자화 + PagedAttention + Continuous Batching + Prefix Caching을 함께 적용하면 최대 효과를 얻을 수 있습니다.


References

  • Kwon, W. et al. (2023). "Efficient Memory Management for Large Language Model Serving with PagedAttention." SOSP
  • Dao, T. (2024). "FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning." ICLR
  • Leviathan, Y. et al. (2023). "Fast Inference from Transformers via Speculative Decoding." ICML
  • Frantar, E. et al. (2023). "GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers." ICLR
  • Lin, J. et al. (2024). "AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration." MLSys
  • Ainslie, J. et al. (2023). "GQA: Training Generalized Multi-Query Transformer Models." EMNLP

— Data Dynamics 엔지니어링 팀