제5부 추론 최적화와 서빙
5.10 TensorRT-LLM IV — speculative decoding
5.10.1 이 장에서 배우는 것 / 선수 지식
5.7~5.9에서 KV 캐시·인플라이트 배칭·병렬·양자화로 LLM 추론을 최적화했다. 그래도 단일 요청·작은 배치의 decode는 메모리 바운드라(5.1.6) 토큰을 하나씩만 생성하고 GPU 연산 유닛은 유휴 상태다. speculative decoding은 바로 이 유휴 연산 자원을 역이용한다: 고비용 가중치 읽기 한 번(메모리 바운드 스텝)에 여러 후보 토큰을 한꺼번에 검증해 받아들인다. 잘 되면 출력 분포를 그대로 유지하면서 TPOT를 줄인다(무손실 가속).
이 장은 TRT-LLM 묶음(5.7~5.10)의 마지막이다. draft(초안 제안)·verify(검증) 구조, 왜 분포가 보존되는지(speculative sampling), 수용률(acceptance rate) 이 속도를 어떻게 정하는지, 초안을 만드는 방법들(별도 draft 모델·Medusa·EAGLE·lookahead), 그리고 언제 도움이 되고 언제 손해인지(배치 regime)를 판다.
배우는 것:
- 왜 통하나 — decode 메모리 바운드(연산 여유)를 이용해 한 번의 target forward로 여러 토큰을 검증하는 원리(루프라인, 1.10).
- draft → verify → accept 메커니즘과, 분포 보존(speculative/rejection sampling)이 왜 출력을 바꾸지 않는지.
- 수용률·기대 토큰 수·속도 모델 — 수계산으로 가속 상한을 추정.
- 초안 생성 방식 — 별도 draft 모델, self-speculative(Medusa·EAGLE), n-gram/lookahead의 차이.
- 배치 regime 상호작용 — 작은 배치(지연 바운드)엔 큰 이득, 큰 배치(이미 컴퓨트 바운드)엔 작거나 역효과.
- TRT-LLM에서 켜고 수용률·TPOT를 측정·튜닝하는 흐름(실습).
선수 지식: 5.1(prefill/decode·메모리 바운드·여유 연산 — 이 장의 전제), 5.7(KV 캐시 — draft·verify가 KV를 다룸), 5.8(배칭 상호작용), 1.10(루프라인), 5.9(draft 모델 양자화). 환경은 5.7.
정직: speculative decoding 알고리즘(draft 모델·Medusa·EAGLE·lookahead)의 지원·인터페이스·기본값은 TRT-LLM 버전마다 다르고, 이들은 외부 연구를 통합한 것이라 명칭·가용성이 변한다. 수용률·가속 배수는 모델 쌍·데이터·온도에 강하게 의존하므로 이 장의 수치는 구조를 보여주는 개략치 — 반드시 실측. 표준 speculative sampling은 출력 분포를 정확히 보존하지만(무손실), 구현·근사에 따라 다를 수 있으니 검증.
5.10.2 왜 통하나 — 메모리 바운드의 여유를 쓴다
5.1.6의 사실 두 개를 결합한다:
핵심 아이디어:
target 모델의 forward를 K개 후보 토큰에 대해 병렬로 한 번 실행한다. 이 forward는 가중치를 한 번만 읽지만(메모리 바운드라 1토큰일 때와 비슷한 비용) K개 위치를 동시에 검증한다. 검증을 통과한 토큰을 받아들이면 한 번의 고비용 읽기로 여러 토큰을 확정 → decode 스텝(=읽기) 횟수가 줄어 TPOT가 떨어진다.
이것이 "메모리 바운드의 유휴 연산 자원을 쓴다"는 말의 뜻이다. 컴퓨트 바운드라면(큰 배치) 여유가 없어 이득이 작다(5.10.6).
5.10.3 메커니즘 — draft → verify → accept
분포 보존(왜 무손실인가). 단순히 "draft가 맞으면 쓰고 틀리면 버린다"가 아니다. speculative sampling(rejection sampling 기반)은 수용/거부 확률을 수학적으로 조정해, 최종 출력 토큰열의 분포가 target 모델만으로 순차 실행한 것과 정확히 동일하도록 만든다.
따라서 (표준 알고리즘에서) speculative decoding은 품질을 바꾸지 않는다 — 양자화(5.4~5.5)처럼 정확도를 거래하는 것이 아니라, 같은 출력을 더 빨리 낸다. (Medusa 등 일부 변형은 근사·tree 검증을 쓰니 구현별 확인.)
5.10.4 워크스루 (1) — 수용률·속도 모델
speculative가 얼마나 빨라지는지는 수용률 α(제안된 draft 중 평균 수용 비율)가 정한다. 수계산.
- 라운드마다 $K$개 제안. 한 라운드에 확정되는 기대 토큰 수(개략 모델):
- 수용이 독립·확률 $\alpha$라면, 확정 토큰 기대값 $\approx (1 - \alpha^{K+1}) / (1 - \alpha)$
- ($=$ 수용된 draft 기대값 $\alpha(1-\alpha^K)/(1-\alpha)$ + target 정정 토큰 1개 — 이미 포함, 따로 안 더함)
- 예) $\alpha=0.7$, $K=4$:
- 기대 확정 $\approx (1 - 0.7^5)/(1 - 0.7) \approx (1 - 0.168)/0.3 \approx 2.77$ 토큰 / target forward
- → 순차 decode가 토큰당 forward 1번인데, speculative는 'forward 1번에 ~2.77토큰'
순 가속(net speedup)은 draft 비용도 빼야 한다:
- $\mathrm{speedup} \approx$ (기대 확정 토큰) $/ (1 + \mathrm{draft\_cost\_ratio} \times K)$
- 기대 확정 토큰: 위(수용률·$K$)
- draft 비용: draft가 target 대비 얼마나 저비용인가(별도 모델이면 그 forward들, Medusa면 거의 0)
- 요지:
- $\alpha$(수용률) 높을수록 ↑ (draft가 target과 잘 맞음)
- draft가 쌀수록 ↑ (Medusa/EAGLE는 target에 헤드만 추가 → draft 비용 거의 0)
- $K$를 키우면 기대 토큰↑이나 draft 비용·낭비도↑ → 최적 $K$ 존재
수치 규모(개략): 좋은 조건(α 높고 draft 쌈)에서 TPOT를 수배 줄일 수 있지만, draft가 비용이 크거나 수용률이 낮으면 이득이 사라지거나 역효과(draft·verify 오버헤드 > 절약). 그래서 draft 모델과 target의 "정렬(agreement)"이 전부다 — 작고 싸면서도 target과 잘 맞는 draft가 이상적.
5.10.5 초안(draft) 생성 방식
수용률↑·draft 비용↓를 어떻게 동시에? 몇 가지 접근.
| 방식 | draft 비용 | 수용률 | 추가 학습 | 비고 |
|---|---|---|---|---|
| 별도 draft 모델 | 중(작은 모델 forward) | 모델 쌍 의존 | 불필요(기존 작은 모델) | 가장 단순 |
| Medusa(헤드) | 거의 0 | 중~높 | 헤드 학습 | tree 검증 |
| EAGLE | 낮 | 높음 | 학습 | 특징 기반 |
| lookahead/n-gram | 0 | 도메인 의존 | 불필요 | 반복·코드에 강함 |
견해: 별도 draft 모델은 시작점으로 단순하지만(작은 동족 모델이 있으면), 메모리·draft 비용·정렬이 부담이다. Medusa·EAGLE는 draft 비용을 거의 없애 보통 더 큰 순 가속을 주나 헤드 학습이 필요하다. lookahead/n-gram은 학습·모델 없이 코드·반복 텍스트에서 잘 듣는다. 워크로드(도메인·반복성)·운영 제약(학습 가능?)으로 고르고, 수용률·TPOT를 실측해 결정.
5.10.6 배치 regime — 언제 도움, 언제 손해
speculative의 전제는 "decode가 메모리 바운드라 연산 여유가 있다"였다. 이 여유가 배치 크기에 따라 사라진다.
| regime | speculative |
|---|---|
| 작은 배치·저지연(대화형 단일 사용자) | 큰 이득 — 유휴 연산 자원을 TPOT 단축에 씀 |
| 중간 배치 | 이득 점감 |
| 큰 배치·처리량 모드 | 이득 작음·역효과 가능(컴퓨트 여유 없음) |
핵심: speculative는 "지연 최적화"이지 "처리량 최적화"가 아니다. 단일 사용자·저지연(코드 어시스턴트·대화)에선 TPOT를 크게 줄이지만, 처리량 극대(큰 배치)에선 인플라이트 배칭(5.8)이 이미 GPU를 채워 speculative가 줄 여유가 없다. 그래서 저지연 운영점에 켜고, 큰 배치엔 끄거나 신중히 — 또는 배치 크기에 따라 동적으로(구현 의존).
5.10.7 워크스루 (2) — 켜고 측정·튜닝
TRT-LLM에서 speculative를 켜는 흐름(인자·방식 버전 의존, 문서 확인):
# (A) 별도 draft 모델: target과 draft 둘 다 엔진 빌드, 런타임에 묶음
trtllm-build --checkpoint_dir ./target_ckpt --output_dir ./target_engine ...
trtllm-build --checkpoint_dir ./draft_ckpt --output_dir ./draft_engine ...
# 런타임에서 speculative(draft+target) 구성으로 실행, K(제안 길이) 지정
python run_speculative.py --target ./target_engine --draft ./draft_engine \
--num_draft_tokens 4 --input_text "..." # 인자명 버전 의존
# (B) Medusa/EAGLE: target에 헤드 포함해 빌드(별도 모델 없음)
# 사전 학습/제공된 Medusa 헤드 가중치를 합쳐 변환·빌드(절차 버전 의존)
trtllm-build --checkpoint_dir ./medusa_ckpt --output_dir ./engine \
--speculative_decoding_mode medusa ... # 모드·인자 버전 확인
측정·튜닝(가장 중요):
1) 수용률(acceptance rate) 측정 — speculative의 핵심 지표
라운드당 평균 수용 토큰 / K → α 추정. 낮으면 draft·target 정렬 문제.
2) TPOT·tokens/s 비교 — speculative on/off
작은 배치에서 TPOT가 줄어야 정상. 안 줄면 draft 비용·낮은 수용률 의심.
3) K(num_draft_tokens) 튜닝
K↑ → 기대 토큰↑이나 거부 시 낭비·draft 비용↑ → 수용률 곡선 보고 최적 K.
보통 α가 높으면 큰 K, 낮으면 작은 K가 유리.
4) 배치별 확인
작은 배치에서 켜고, 큰 배치에선 이득이 사라지는지 측정 → 운영점별 on/off.
5) 출력 동등성 확인(표준 알고리즘이면)
speculative on/off의 출력 분포가 같은지(무손실인지) 점검 — 다르면 구현·근사 확인.
함정 미리: 수용률이 낮으면 speculative가 오히려 느리다(draft·verify 오버헤드만 추가). draft 모델이 target과 도메인·분포가 안 맞으면 α가 낮다. draft를 target 출력에 맞춰(distillation 등) 정렬하거나 Medusa/EAGLE로 바꾸는 것이 해법.
5.10.8 중간 점검 (체크포인트)
- [ ] speculative가 decode 메모리 바운드의 여유 연산을 어떻게 쓰는지(한 번의 target forward로 K개 검증)를 루프라인으로 설명한다.
- [ ] draft→verify→accept 흐름과, speculative sampling이 출력 분포를 보존(무손실)하는 이유를 안다.
- [ ] 수용률 α가 기대 확정 토큰·순 가속을 어떻게 정하는지 수계산하고, draft 비용의 역할을 안다.
- [ ] 초안 방식(별도 모델·Medusa·EAGLE·lookahead)의 draft 비용·수용률·학습 필요를 비교한다.
- [ ] 배치 regime(작은 배치=이득, 큰 배치=점감/역효과)을 이유와 함께 설명한다.
- [ ] TRT-LLM에서 켜고 수용률·TPOT·K를 측정·튜닝하며, 출력 동등성을 확인한다.
증상→의심: speculative 켰는데 더 느림 → 수용률 낮음(draft·target 미정렬) 또는 draft 비용 과다 → 정렬·Medusa/EAGLE·K 조정. 작은 배치는 빨라지는데 큰 배치는 그대로/느림 → 큰 배치 컴퓨트 바운드(정상) → 큰 배치엔 off. 출력이 speculative on/off에서 다름 → 비표준/근사 구현 → 알고리즘·품질 검증. 수용률이 도메인마다 불규칙 → draft가 특정 분포에만 맞음 → 도메인 맞춤 draft. 메모리 부족 → 별도 draft 모델 적재 → 작은 draft·Medusa(헤드).
5.10.9 트레이드오프·대안
디코딩 가속 선택.
| 방법 | 누구에게 | 비고 |
|---|---|---|
| speculative(별도 draft) | 저지연·작은 배치·동족 작은 모델 보유 | 단순, 메모리·정렬 부담 |
| Medusa/EAGLE(self-spec) | draft 비용 0·높은 수용률 원함 | 헤드 학습 필요, 구현 복잡 |
| lookahead/n-gram | 학습·모델 없이·반복/코드 도메인 | 수용률 도메인 의존 |
| speculative 안 씀 + 큰 배치 | 처리량 우선 서비스 | 인플라이트 배칭이 이미 GPU 채움(5.8) |
| 양자화·병렬과 병행 | 모두 | speculative는 직교 — 함께 적용 가능 |
견해: 저지연이 핵심이면 speculative는 강력한 카드다(무손실로 TPOT 단축). 동족 작은 모델이 있으면 별도 draft로 빠르게 실험하고, 이득이 확인되면 Medusa/EAGLE로 draft 비용을 없애 더 키운다. 처리량 모드(큰 배치)에선 인플라이트 배칭이 답이고 speculative는 부차적. speculative는 양자화·병렬(5.9)과 직교하므로 함께 쓸 수 있다 — 단 복잡도·튜닝 비용을 감안.
비엔비디아 정직: speculative decoding·Medusa·EAGLE·lookahead는 모두 공개 연구에서 나왔고 vLLM·SGLang 등도 지원한다. TRT-LLM의 강점은 엔비디아 커널·tree attention·FP8과의 통합·Triton 서빙이다. 수용률·가속은 모델 쌍·도메인에 크게 의존하니 당신 워크로드로 실측하고 다른 런타임과 비교(5.15).
5.10.10 흔한 함정
- speculative를 처리량 최적화로 오해. 큰 배치는 이미 컴퓨트 바운드라 여유가 없어 이득이 작거나 역효과. 저지연·작은 배치 운영점에 켠다.
- draft·target 미정렬. draft가 target과 도메인·분포가 안 맞으면 수용률↓ → 오버헤드만 추가. 정렬(distillation)·Medusa/EAGLE.
- K를 맹목적으로 키움. K↑가 항상 빠른 것이 아니다 — 거부 시 낭비·draft 비용↑. 수용률 곡선으로 최적 K.
- 수용률을 안 본다. speculative의 핵심 지표는 수용률 — 안 재면 왜 느린지 모른다. 라운드당 수용 토큰을 모니터.
- 무손실을 가정하고 검증 생략. 표준 알고리즘은 분포 보존이지만 변형·근사·tree 검증은 다를 수 있다 — on/off 출력 동등성을 확인.
- 별도 draft 모델 메모리 간과. draft도 HBM·KV를 쓴다 → 동시성에 영향. 작은 draft·Medusa(헤드)로 절감.
- 양자화 draft의 정렬 변화. draft를 양자화하면 분포가 변해 수용률이 떨어질 수 있다 — 검증.
- 모든 워크로드에 일괄 적용. 도메인·배치·SLA마다 이득이 다르다. 운영점별로 측정해 on/off.
5.10.11 연습문제
연습 1 (왜 통하나). speculative decoding이 "무비용 이득(free lunch)"처럼 보이는데, 정확히 무엇을 이용하며 왜 큰 배치에서는 그 이득이 사라지는지 루프라인 언어로 설명하라.
정답
이용하는 것: 작은 배치 decode의 메모리 바운드성 — 가중치(+KV)를 HBM에서 읽는 것이 병목이고 GPU 연산 유닛은 유휴 상태다(산술 강도 낮음, 1.10). speculative는 그 유휴 연산 자원으로 K개 후보를 한 번의 target forward(가중치 1회 읽기)로 병렬 검증해, 한 번의 고비용 읽기로 여러 토큰을 확정 → 읽기 횟수↓ → TPOT↓. 큰 배치에서 사라지는 이유: 배치가 커지면 산술 강도가 올라 이미 컴퓨트 바운드에 근접(5.1.4) → 연산 여유가 없다 → speculative의 verify(K배 연산)가 추가 부담이 되어 이득이 줄거나 역효과. 즉 "여유 연산을 쓰는" 최적화라 여유가 없으면 못 쓴다.
연습 2 (분포 보존). speculative decoding이 출력 품질을 바꾸지 않는다(무손실)는 주장의 근거를, "draft 맞으면 쓰고 틀리면 버림"과 어떻게 다른지와 함께 설명하라.
정답
단순 "맞으면 쓰기"는 draft 분포 q로 편향되어 target 분포 p와 달라질 수 있다(품질 변화). speculative sampling은 수용/거부 확률을 수학적으로 조정한다: target 확률 p(t)≥q(t)면 무조건 수용, p(t)<q(t)면 p(t)/q(t) 확률로 수용하고 거부 시 보정 분포 (p−q)+ 에서 재샘플. 이 규칙은 최종 토큰 분포가 target p와 정확히 동일함이 증명된다(rejection sampling). 따라서 출력은 target을 순차로 실행한 것과 분포적으로 같다 — speculative는 같은 출력을 더 빨리 낸다(양자화처럼 정확도를 거래하지 않음). 단 Medusa 등 tree·근사 변형은 구현별로 확인.
연습 3 (속도 모델). draft가 거의 무비용(Medusa)이고 수용률 α=0.8, K=4라 하자. (a) target forward당 기대 확정 토큰 수(개략)? (b) 이것이 순 가속에 어떻게 연결되나? (c) α가 0.4로 떨어지면 어떤 일이 생기고 대응은?
정답
(a) 기대 확정 ≈ (1−α^(K+1))/(1−α) = (1−0.8^5)/(1−0.8) = (1−0.328)/0.2 ≈ 3.36 토큰/forward(+정정). (b) draft가 무비용(Medusa는 헤드만)라 순 가속 ≈ 기대 확정 토큰 ≈ ~3배 TPOT 단축(오버헤드 무시 개략). draft 비용이 클수록 이 배수가 감소함. (c) α=0.4면 기대 확정 ≈ (1−0.4^5)/0.6 ≈ 1.65 — 이득이 크게 줄고, draft 비용이 있으면 역효과일 수도. 대응: draft·target 정렬 개선(distillation·도메인 맞춤), K를 줄여 낭비 감소, EAGLE류로 수용률↑, 또는 그 워크로드엔 speculative off. 핵심은 수용률이 속도를 지배한다는 것.
연습 4 (draft 선택). 다음에 별도 draft 모델 / Medusa·EAGLE / lookahead 중 무엇을 권할지와 이유: (a) 코드 자동완성(반복·정형 텍스트 많음, 추가 학습 어려움), (b) 범용 대화 어시스턴트(저지연, 헤드 학습 가능), (c) 이미 작은 동족 모델을 보유하고 빠른 실험을 원함.
정답
(a) lookahead/n-gram — 코드·반복 텍스트는 n-gram·Jacobi로도 수용률이 높고, 추가 학습·모델 없이 적용 가능(제약 충족). (b) Medusa 또는 EAGLE — 저지연 목표 + 헤드 학습 가능 → draft 비용 0·높은 수용률로 가장 큰 순 가속. EAGLE이 수용률 더 높은 경향(구현 의존). (c) 별도 draft 모델 — 이미 작은 동족 모델이 있어 학습 없이 즉시 실험 가능, 단순. 이득 확인되면 Medusa/EAGLE로 draft 비용 제거 검토. 모두 수용률·TPOT 실측으로 확정.
연습 5 (운영 설계). 한 LLM 서비스가 낮에는 단일 사용자 대화(저지연), 밤에는 대량 배치 생성(처리량)을 한다. speculative를 어떻게 운영할지, 다른 최적화(인플라이트 배칭·양자화)와의 관계와 함께 설계하라.
정답
낮(저지연·작은 배치): speculative on — decode 메모리 바운드의 여유로 TPOT 크게 단축, 무손실. draft는 Medusa/EAGLE(비용 0) 권장, 수용률·TPOT 모니터. 밤(처리량·큰 배치): speculative off(또는 최소) — 큰 배치는 이미 컴퓨트 바운드라 이득 작거나 역효과, 대신 인플라이트 배칭(5.8) 으로 GPU를 채워 처리량 극대. 관계: speculative는 양자화·병렬(5.9)과 직교라 낮 운영점에 함께 적용 가능(weight-only INT4로 decode 더 빠르게 + speculative). 핵심: 배치 regime에 따라 on/off, 처리량은 배칭이·지연은 speculative가 주력. 운영점별로 수용률·p99·tokens/s를 측정해 확정.
5.10.12 요약 · 다음 장
- speculative decoding은 작은 배치 decode의 메모리 바운드(여유 연산) 를 이용해, 저비용 draft가 K개 후보를 제안하고 target이 한 번의 forward로 병렬 검증해 여러 토큰을 확정 → TPOT 단축.
- speculative sampling은 수용/거부를 수학적으로 조정해 출력 분포를 정확히 보존한다(표준 알고리즘은 무손실). 양자화와 달리 정확도를 거래하지 않는다.
- 속도는 수용률 α(draft·target 정렬)와 draft 비용이 정한다. Medusa·EAGLE는 draft 비용을 거의 없애 순 가속을 키운다. 최적 K가 존재.
- 배치 regime: 작은 배치·저지연엔 큰 이득, 큰 배치·처리량 모드엔 점감·역효과(컴퓨트 여유 소진). speculative는 지연 최적화, 처리량은 인플라이트 배칭(5.8)이 주력. 둘·양자화·병렬과 직교.
- 실습: 켜고 수용률·TPOT·K를 측정·튜닝, on/off 출력 동등성 확인. 정직: 알고리즘·인자 버전 의존, 수용률·가속은 모델·도메인 의존 → 실측.
다음 장: 5.11 Triton I — 모델 리포지토리·백엔드. TRT-LLM 묶음(5.7~5.10)을 마치고, 이제 서빙 계층으로 올라간다. 최적화된 엔진(TensorRT·TRT-LLM·PyTorch·ONNX 등)을 하나의 서버로 운영하는 Triton Inference Server — 모델 리포지토리 구조, 다중 백엔드, 요청 처리·스트리밍을 실습으로 본다.