LLM 추론이 느린 이유는 연산이 부족해서가 아닙니다. GPU가 다음 가중치 로딩을 기다리는 동안 연산 유닛이 놀고 있습니다. Speculative Decoding은 그 유휴 시간을 채웁니다.
핵심 요약 → Speculative Decoding: 소형 Draft 모델이 토큰 K개 예측 → 대형 Target 모델이 한 번에 검증 → 출력 품질 변화 없음: 수락된 토큰은 Target 모델이 직접 생성한 것과 동일한 분포 → 속도 향상: 수락률(α) 0.6~0.8 구간에서 실제 2~3배 (EAGLE3 기준 최대 4.48배) → 2026년 최신: EAGLE3 = 표준, MTP (DeepSeek V4 네이티브), Medusa (단순 설정) → vLLM + EAGLE3: --speculative-model 파라미터 3줄로 활성화 → SGLang + EAGLE3: 자동 튜닝 지원, SpecV2(실험적) 오버랩 스케줄러 → gpt-oss-120B + EAGLE3: 코드 워크로드에서 비용 19.4% 절감 (Red Hat 실측) → 수락률 0.55 미만이면 효과 없거나 역효과 — 실제 트래픽 분포로 측정 필수
왜 LLM 추론이 느린가 — 근본 원인
현대 GPU는 LLM 추론 중 충분히 활용되지 않습니다. GPU 연산 유닛은 메모리에서 가중치가 로딩되기를 기다리고 있고, 산술 용량이 부족한 게 아닙니다. 로드라인 분석에서 LLM 추론은 산술 집약도가 바이트당 약 1 FLOP 근처에 집중되며 이는 메모리 바운드 영역 깊숙이 위치합니다.
# LLM 추론의 병목 구조
일반 추론 (Autoregressive Decoding):
토큰 1 생성 → 토큰 2 생성 → ... → 토큰 N 생성
각 스텝마다: 전체 모델 가중치 GPU 메모리에서 로드
→ 다음 토큰 계산
→ 이전 토큰 없이는 다음 계산 불가
→ 순차적, 직렬, 메모리 바운드
70B 모델로 500 토큰 생성 = 500번의 직렬 전체 모델 패스
GPU가 하는 일: 가중치 로딩 기다리기 → 계산 → 기다리기 → 계산...
병목: 메모리 대역폭 (compute 아님)
→ 연산 유닛의 유휴 시간이 핵심 낭비
1. 핵심 원리 — Draft-and-Verify
# Speculative Decoding 동작 원리
일반 추론:
Target(70B) → 토큰1
Target(70B) → 토큰2 ← 직렬, 느림
Target(70B) → 토큰3
Speculative Decoding:
Draft(7B) → 토큰1_예측, 토큰2_예측, 토큰3_예측, 토큰4_예측 (빠름)
Target(70B) → [토큰1_예측, 토큰2_예측, 토큰3_예측, 토큰4_예측] 한 번에 검증
→ 토큰1 수락 ✅, 토큰2 수락 ✅, 토큰3 거부 ❌
→ 토큰3부터 Target이 직접 생성
결과:
1번의 Draft 실행 + 1번의 Target 검증 = 토큰 2개 생성
vs 일반: 2번의 Target 실행 = 토큰 2개 생성
→ Target 패스 횟수가 줄어듦 = 빠름
핵심 보장:
수락된 토큰 = Target 모델이 직접 생성했을 때와 동일한 확률 분포
→ 출력 품질 변화 없음, 결정론적
2. 속도 향상 수학 — 수락률이 전부
# 예상 속도 향상 계산
def expected_speedup(
alpha: float, # 토큰별 수락률 (0~1)
gamma: int, # Draft 토큰 수 (K)
draft_cost: float = 0.1, # Draft 비용 (Target 대비 비율)
) -> float:
"""
이론적 최대 속도 향상 계산
(Leviathan et al. 2023 공식)
"""
# gamma개 토큰 중 평균 수락 수
# 기하분포: 첫 거부 전까지의 평균
avg_accepted = (1 - alpha ** (gamma + 1)) / (1 - alpha)
# 각 라운드 비용: Draft 실행 + Target 검증 1회
cost_per_round = draft_cost * gamma + 1.0 # Target 패스 = 1.0 기준
# 순수 Target 대비 속도 향상
speedup = avg_accepted / cost_per_round
return speedup
# 수락률별 시뮬레이션 (gamma=4, draft_cost=0.1)
scenarios = {
"불량 Draft (α=0.4)": expected_speedup(0.4, 4), # ~1.2x (marginal)
"보통 Draft (α=0.6)": expected_speedup(0.6, 4), # ~1.7x
"좋은 Draft (α=0.7)": expected_speedup(0.7, 4), # ~2.2x
"우수 Draft (α=0.8)": expected_speedup(0.8, 4), # ~2.8x
"EAGLE3 수준 (α=0.85)": expected_speedup(0.85, 5), # ~3.4x
}
for label, speedup in scenarios.items():
print(f"{label}: {speedup:.1f}x")
# 실제 측정값과 차이:
# 이론값 > 실제 (Draft 비용, 검증 오버헤드, 배치 효율 등)
# 실제는 이론의 60~80% 수준
# 핵심 인사이트:
# α = 0.55 이하 → 효과 없거나 역효과
# α = 0.6~0.8 → 실용적 범위 (2~3x 실제 측정)
# α > 0.8 → EAGLE3 파인튜닝 필요
3. 2026년 주요 Draft 방법 비교
# 2026년 Speculative Decoding 주요 방법
방법 특징 수락률 설정 난이도 VRAM 추가
─────────────────────────────────────────────────────────────────────────
EAGLE3 트리 기반 추론, 현재 표준 0.7~0.85 중간 소량
MTP 모델 내장 (DeepSeek·GLM) 0.8~0.9 없음 없음
Medusa 다수 Draft 헤드 병렬 0.6~0.75 낮음 소량
Vanilla 별도 소형 모델 0.5~0.65 높음 많음
EAGLE3 (2026년 표준):
- 타겟 모델 히든 스테이트 + 이전 토큰으로 Draft 생성
- 트리 구조로 여러 후보 동시 탐색
- 타겟 모델당 ~277MB Draft 헤드 (co-deploy 가능)
- SpecForge로 훈련: Qwen3-235B-A22B EAGLE3 훈련 9.9배 가속
- 주요 모델 공식 EAGLE3 헤드 공개:
Llama 3.1/3.3, Qwen3, DeepSeek V4, Gemma, Kimi K2.6
MTP (Multi-Token Prediction):
- DeepSeek V4, GLM-5.1에 내장
- 추가 Draft 모델 없이 모델 아키텍처 자체가 다음 N개 토큰 예측
- 설정 = 0줄 (모델이 지원하면 자동 활성화)
- vLLM: --speculative-model deepseek-ai/DeepSeek-V4-MTP
Medusa:
- 여러 Draft 헤드를 타겟 모델에 추가
- 설정 단순
- EAGLE3 대비 수락률 낮음
4. vLLM + EAGLE3 — 3줄로 활성화
# ── vLLM 서버에 EAGLE3 활성화 ──
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-70B-Instruct \
--speculative-model lmsys/llama-3.1-70b-eagle3 \ # EAGLE3 Draft 헤드
--num-speculative-tokens 5 \ # Draft 토큰 수 (K)
--tensor-parallel-size 4 \ # GPU 수
--max-model-len 8192
# ── 주요 파라미터 ──
# --num-speculative-tokens: K (Draft 제안 토큰 수)
# 권장: 4~8 (수락률에 따라 튜닝)
# 높이면: 수락률 높을 때 더 빠름
# 낮추면: 수락률 낮을 때 오버헤드 감소
# ── MTP 지원 모델 (Draft 모델 불필요) ──
python -m vllm.entrypoints.openai.api_server \
--model deepseek-ai/DeepSeek-V4 \
--speculative-model deepseek-ai/DeepSeek-V4-MTP \
--num-speculative-tokens 3
# ── Python API로 설정 ──
from vllm import LLM, SamplingParams
llm = LLM(
model="meta-llama/Llama-3.1-8B-Instruct",
speculative_config={
"model": "meta-llama/Llama-3.1-8b-eagle3",
"num_speculative_tokens": 5,
},
tensor_parallel_size=1,
)
sampling_params = SamplingParams(temperature=0.8, max_tokens=512)
outputs = llm.generate(["코드 작성해줘: 퀵소트 Python"], sampling_params)
# 수락률 확인 (디버깅용)
for output in outputs:
print(f"수락률: {output.metrics.spec_decode_acceptance_rate:.2%}")
5. SGLang + EAGLE3 — 자동 튜닝
# ── SGLang EAGLE3 자동 튜닝 (권장) ──
python -m sglang.launch_server \
--model-path meta-llama/Llama-3.1-8B-Instruct \
--speculative-algorithm EAGLE \
--speculative-draft-model-path lmsys/llama-3.1-8b-eagle3 \
# 아래 3개 파라미터 모두 생략 → 자동 튜닝
# --speculative-num-steps 4 \
# --speculative-eagle-topk 4 \
# --speculative-num-draft-tokens 64 \
--port 30000
# ── 수동 튜닝 파라미터 ──
python -m sglang.launch_server \
--model-path meta-llama/Llama-3.1-70B-Instruct \
--speculative-algorithm EAGLE \
--speculative-draft-model-path lmsys/llama-3.1-70b-eagle3 \
--speculative-num-steps 3 \ # EAGLE 트리 깊이
--speculative-eagle-topk 4 \ # 각 레벨 top-k 후보
--speculative-num-draft-tokens 64 \ # 총 Draft 토큰 예산
--tp 4 # Tensor Parallel
# SpecV2 실험적 기능 (오버랩 스케줄러, 더 높은 처리량)
SGLANG_ENABLE_SPEC_V2=True python -m sglang.launch_server \
--speculative-eagle-topk 1 \ # SpecV2는 topk=1 필요
# ...
# ── 벤치마크 도구로 최적 파라미터 탐색 ──
python -m sglang.bench_speculative \
--model meta-llama/Llama-3.1-8B-Instruct \
--draft-model lmsys/llama-3.1-8b-eagle3 \
--dataset mt_bench \
--search # 자동으로 최적 파라미터 탐색
6. 수락률 측정 + 튜닝
# ── vLLM Prometheus 메트릭으로 수락률 모니터링 ──
import requests
def get_spec_decode_metrics():
"""vLLM Prometheus 엔드포인트에서 수락률 조회"""
response = requests.get("http://localhost:8000/metrics")
metrics = {}
for line in response.text.split("\n"):
if "vllm:spec_decode_acceptance_rate" in line and not line.startswith("#"):
# 수락률: 전체 수락 토큰 / 전체 제안 토큰
value = float(line.split()[-1])
metrics["acceptance_rate"] = value
if "vllm:spec_decode_draft_acceptance_rate" in line and not line.startswith("#"):
metrics["draft_acceptance_rate"] = float(line.split()[-1])
return metrics
def evaluate_spec_decode_config():
"""
수락률 기반 설정 평가
"""
metrics = get_spec_decode_metrics()
alpha = metrics.get("acceptance_rate", 0)
if alpha < 0.55:
print(f"⚠️ 수락률 {alpha:.1%} — Speculative Decoding 비효율적")
print(" 권장: Draft 모델 교체 또는 비활성화")
return "disable"
elif alpha < 0.65:
print(f"🟡 수락률 {alpha:.1%} — 개선 필요")
print(" 권장: num_speculative_tokens 줄이기 (4→3)")
return "tune_down"
elif alpha < 0.80:
print(f"🟢 수락률 {alpha:.1%} — 정상 작동 중")
return "ok"
else:
print(f"🚀 수락률 {alpha:.1%} — 최적 상태")
print(" 권장: num_speculative_tokens 늘려보기 (5→6)")
return "tune_up"
7. EAGLE3 Draft 헤드 직접 훈련
# 공식 EAGLE3 헤드가 없는 모델에 직접 훈련
# (277MB 헤드, H100 1대에서 약 1.5시간)
# ── SpecForge 사용 (2026년 3월 공개, 9.9배 빠른 훈련) ──
pip install specforge
# 훈련 데이터 준비
python specforge/prepare_data.py \
--model meta-llama/Llama-3.1-8B-Instruct \
--dataset sharegpt \
--output data/eagle3_train
# EAGLE3 헤드 훈련
python specforge/train_eagle3.py \
--target-model meta-llama/Llama-3.1-8B-Instruct \
--train-data data/eagle3_train \
--output-dir ./my-eagle3-head \
--batch-size 32 \
--learning-rate 3e-4 \
--num-epochs 3 \
--num-gpus 1 # H100 1대로 약 1.5시간
# 사용 (vLLM)
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-8B-Instruct \
--speculative-model ./my-eagle3-head \
--num-speculative-tokens 5
8. 실전 성능 수치 — 실측 데이터
# 실제 측정 벤치마크 (2026년 공개 데이터)
환경: SGLang v0.5.6, GLM-4.7-Flash + EAGLE3, H100 80GB (1대)
수락률: 40%, 평균 2.4 토큰/검증 스텝
MT-Bench (154 프롬프트):
단일 요청(B=1): 1.30x 속도 향상
시스템 처리량: 1.70x 향상 (슬롯 회전 가속)
환경: vLLM, gpt-oss-120B (MoE) + EAGLE3, H100
워크로드: SWE-bench (코드 헤비)
동시 요청 200개: 일관된 처리량·레이턴시 향상 유지
비용 절감: 출력 토큰 1M당 19.4% 절감
환경: EAGLE3, Llama 3.1 70B, H100 4대 (TP=4)
일반 대화 (α≈0.72): 2.3~2.8x 속도 향상
코드 생성 (α≈0.80): 2.8~3.5x 속도 향상
창의적 글쓰기: 1.2~1.5x (낮은 수락률)
# 워크로드별 수락률 경향
코드 생성: 높음 (0.75~0.85) → Speculative Decoding 최적
구조화 출력: 높음 (0.70~0.80) → 적합
일반 대화: 중간 (0.60~0.72) → 적합
창의적 글쓰기: 낮음 (0.40~0.60) → 비효율 가능
9. 언제 적용하고 언제 피하나
# Speculative Decoding 적용 결정 트리
def should_apply_spec_decoding(workload: dict) -> tuple[bool, str]:
"""
워크로드 특성 기반 적용 여부 결정
"""
# ✅ 강력 추천
if workload.get("task") in ["code_generation", "structured_output", "sql"]:
return True, "코드·구조화 출력은 수락률 높음 (0.75+) — 2~3x 기대"
if workload.get("output_length", 0) > 200:
return True, "출력이 길수록 총 절감 효과 큼"
if workload.get("latency_sensitive"):
return True, "레이턴시 개선이 가장 직접적인 효과"
# ❌ 피하는 게 나음
if workload.get("task") in ["creative_writing", "poetry", "brainstorming"]:
return False, "창의적 태스크는 수락률 낮음 → 오버헤드가 이득 초과"
if workload.get("output_length", 0) < 50:
return False, "짧은 출력은 Draft 실행 오버헤드 대비 효과 작음"
if workload.get("temperature", 0) > 1.5:
return False, "고온도 샘플링은 수락률 급격히 낮춤"
if workload.get("concurrent_requests", 1) > 200:
# 고동시성에서는 처리량 향상이 레이턴시 향상보다 효과적
return True, "고동시성: 처리량 1.7x 향상 기대 (레이턴시는 더 작음)"
return True, "기본 권장 (실제 수락률 측정 후 확인)"
# ⚠️ P99 레이턴시 주의
# 수락 실패 시 Target 모델을 두 번 실행해야 함
# → P99 레이턴시 스파이크 발생 가능
# → P50은 개선돼도 P99가 악화되는 경우 있음
# → 반드시 P99도 모니터링
10. API 레벨 추론 (Claude·GPT·Gemini) — 내부 적용 여부
# 상용 API (Anthropic·OpenAI·Google)는 Speculative Decoding 적용 여부 미공개
# 단, 다음 효과는 확인됨:
# Anthropic: 출력 길이에 따른 레이턴시 변화 패턴이
# 순수 autoregressive 대비 비선형
# → 내부적으로 유사 최적화 적용 추정
# 개발자가 직접 제어 가능한 경우 = 자체 호스팅 모델
# (vLLM, SGLang, TensorRT-LLM, TGI)
# 로컬 모델에서 가장 효과적인 설정
RECOMMENDED_CONFIGS = {
"Llama-3.1-8B": "lmsys/llama-3.1-8b-eagle3",
"Llama-3.1-70B": "lmsys/llama-3.1-70b-eagle3",
"Qwen3-8B": "Qwen/Qwen3-8B-EAGLE3",
"Qwen3-32B": "Qwen/Qwen3-32B-EAGLE3",
"DeepSeek-V4": "MTP 내장 (별도 Draft 불필요)",
"GLM-5.1": "thoughtworks/GLM-4.7-Flash-Eagle3 (아키텍처 유사)",
}
결론
✅ Speculative Decoding이 확실히 효과적인 케이스
- 코드 생성, 구조화 출력, SQL → 수락률 0.75+ → 2~3배 속도 향상
- 자체 호스팅 모델 (vLLM·SGLang) — API는 제어 불가
- 출력이 긴 워크로드 → 총 절감 효과 큼
- 레이턴시가 UX에 직결되는 인터랙티브 앱
✅ 2026년 실전 권장 설정
- EAGLE3 + vLLM/SGLang → 대부분 케이스의 표준
- 자동 튜닝 먼저 (bench_speculative.py) → 파라미터 수동 조정
- 수락률 측정은 실제 프로덕션 트래픽 분포로 (벤치마크 트래픽 아님)
❌ 주의사항
- 수락률 0.55 미만 → 비활성화가 나음
- P99 레이턴시 모니터링 필수 (P50만 보면 스파이크 놓침)
- Draft 헤드는 Target 모델과 버전 핀 필수 → 모델 업데이트 시 Draft도 업데이트
- 창의적 글쓰기, 고온도 샘플링 → 효과 없거나 역효과
'LLM' 카테고리의 다른 글
| Kimi K2.6 API 실전 가이드 2편 — Thinking 모드, preserve_thinking, 함수 호출, 프리픽스 캐싱 완전정리 (0) | 2026.06.01 |
|---|---|
| Kimi K2.6 완전분석 1편 — 1조 파라미터 MoE 아키텍처, Agent Swarm 300개, 벤치마크 실체 (0) | 2026.06.01 |
| 중국 오픈소스 코딩 모델 17일 대공세 — GLM-5.1·MiniMax M2.7·Kimi K2.6·DeepSeek V4 완전 비교 (0) | 2026.05.28 |
| "트랜스포머의 저주를 깼다" — SubQ 1200만 토큰 LLM 완전 분석 (0) | 2026.05.27 |
| 지금 쓰는 모델이 6개월 후엔 레거시다 — H2 2026 모델 로드맵 완전 정리 (0) | 2026.05.26 |