추측 디코딩 (Speculative Decoding)

추측 디코딩 (Speculative Decoding)

추측 디코딩은 주 모델보다 앞서 여러 토큰을 예측해 토큰 생성 속도를 크게 높이는 기법이에요. n개 토큰을 배치로 한 번에 계산하는 것(프롬프트 처리)이 n번 순차적으로 계산하는 것(응답 생성)보다 효율적이라는 점을 이용해요. 드래프트 토큰을 빠르게 만들고, 타깃 모델이 한 배치에서 검증하는 방식이라 드래프트 예측이 자주 맞을수록 큰 속도 향상을 얻어요.

출처: llama.cpp speculative 문서

구현 방식들

llama-server는 여러 추측 디코딩 구현을 지원하고, 드래프트 모델이 있는 방식과 없는 방식을 섞어 쓸 수도 있어요.

드래프트 모델 (draft)

훨씬 작은 드래프트 모델이 드래프트를 생성하는 방식이에요. 추측 디코딩에서 가장 많이 쓰는 접근이에요.

EAGLE-3 (draft-eagle3)

EAGLE-3는 타깃 모델의 히든 스테이트를 읽어 다음 토큰을 예측하는 작은 드래프트 모델을 써요. 같은 크기의 독립 드래프트 모델보다 수용률이 높아요. 드래프트는 특정 타깃 모델을 위해 학습된 단일 레이어 트랜스포머예요. 체크포인트를 --target-model-dir로 변환하면 타깃의 토크나이저와 읽을 레이어 인덱스를 상속받아요.

python convert_hf_to_gguf.py AngelSlim/Qwen3-4B_eagle3 \
  --target-model-dir Qwen/Qwen3-4B --outtype bf16 --outfile Qwen3-4B-eagle3.gguf

llama-server -m Qwen3-4B.gguf -md Qwen3-4B-eagle3.gguf --spec-type draft-eagle3

DFlash (draft-dflash)

DFlash는 한 번의 forward pass로 드래프트 토큰 블록 전체를 만들고(블록 디퓨전), 타깃 모델의 히든 스테이트를 드래프트 모델의 어텐션에 주입해요. 드래프트를 하나씩 생성하는 대신 블록 단위로 뽑아 GPU 친화적으로 만든 방식이에요.

python convert_hf_to_gguf.py z-lab/Qwen3-4B-DFlash \
  --target-model-dir Qwen/Qwen3-4B --outtype bf16 --outfile Qwen3-4B-DFlash.gguf

llama-server -m Qwen3-4B.gguf -md Qwen3-4B-DFlash.gguf \
  --spec-type draft-dflash --spec-draft-n-max 15 -fa on --jinja

--spec-draft-n-max은 드래프트 모델이 학습한 블록 크기로 제한돼요.

n-gram 계열 (모델 불필요)

모델 없이 과거 텍스트의 패턴을 재사용하는 방식들이에요.

  • ngram-cache: 짧은 n-gram 시퀀스의 통계를 유지해 확률로 드래프트를 만듦
  • ngram-simple: 현재 n-gram과 일치하는 최근 이력을 찾아 그 뒤의 m개 토큰으로 드래프트 생성
  • ngram-map-k: n-gram 키가 이력에서 반복해서 등장한 뒤 같은 m-gram이 따라올 때 드래프트로 사용
  • ngram-map-k4v (실험): 키마다 최대 4개 값(m-gram)을 추적, 내부 통계로 유독 빈번한 m-gram을 드래프트로 사용
  • ngram-mod: LCG 해시로 n-gram 해시를 계산해 다음 토큰을 저장하는 가벼운(~16MB) 방식. 모든 서버 슬롯이 해시 풀을 공유
# 코드 재작성 같은 패턴 반복 작업에
llama-server [...] --spec-type ngram-simple

# ngram-mod 예시 (MoE는 긴 드래프트 필요)
llama-server ... --spec-type ngram-mod --spec-ngram-mod-n-match 24 \
  --spec-ngram-mod-n-min 48 --spec-ngram-mod-n-max 64

주요 CLI 옵션

--spec-type [none|draft-simple|draft-eagle3|draft-dflash|draft-mtp|ngram-cache|ngram-simple|ngram-map-k|ngram-map-k4v|ngram-mod]
   쓸 추측 디코딩 타입 목록 (기본: none)
--spec-draft-model, -md, --model-draft FNAME   드래프트 모델 경로
--spec-draft-hf, -hfd, -hfrd, --hf-repo-draft <user>/<model>[:quant]
   HuggingFace 드래프트 모델 저장소
--spec-draft-n-max N   드래프트할 토큰 수 (기본: 3)
--spec-draft-n-min N   드래프트에 쓸 최소 토큰 수 (기본: 0)

드래프트 모델 방식과 드래프트 없는 방식(draftless)을 함께 쓰면 draftless가 우선순위가 높아요.

통계 확인

각 구현은 실행 후 드래프트 수용률 같은 통계를 출력해요.

draft acceptance rate = 0.57576 ( 171 accepted / 297 generated)
statistics draft: #calls = 10, #gen drafts = 10, #acc drafts = 10, #gen tokens = 110, #acc tokens = 98

#acc tokens(메인 모델이 수용한 토큰)가 높을수록 속도 향상이 커요.

더 알아보기