AI Engineering/이론

특명: 추론 속도를 올리기 위한 온몸 비틀기 (Speculative Decoding)

마늘냄새폴폴 2026. 1. 19. 21:26

이번 포스팅은 AI 엔지니어링에서 추론 속도를 끌어올리기 위한 서커스 기술인 추측 디코딩, Speculative Decoding에 대해서 정리해보는 시간을 가져보겠습니다. 

 

AI 엔지니어링을 하다보면 자연스럽게 빠져드는 TPS를 높이기위한 여러가지 노력들에서 단연 빠지지않고 등장하는 개념이 바로 이 추측 디코딩인데요. 이번 포스팅에선 Speculative Decoding (이하 추측 디코딩)에 대해서 개념과 실전에서 사용할 때 주의해야할 점에 대해서 서술해볼까합니다. 

 

Speculative Decoding

추측 디코딩은 transformer 기반의 LLM 모델들이 반복적인 문맥 확인을 위해 모든 문장을 확인하면서 (사실 모든 문장은 아닙니다. n_ctx에 해당하는 토큰만큼 확인합니다) 한단어씩 내뱉기 때문에 생기는 문제를 해결하기위한 기술로서, 한 단어씩 검수하는 것과 열 단어씩 검수하는 것이 별 차이 없는 GPU의 성질을 적극 활용하여 추론 속도를 끌어올리는 방법론입니다. 

 

기본적으로 LLM 모델은 생성되는 여러개의 단어들을 보고 그 단어가 원래 본인이 뱉으려던 단어와 일치하면 통과, 그렇지 않으면 수정함으로써 답변 전체의 퀄리티는 그대로 유지하면서 속도는 빠르게 증가시키는 기술인데요. 

 

그럼 그 단어들은 조상님이 만들어주냐?

 

한번에 빠르게 만드는데 특화된 작은 모델(드래프트 모델)을 사용해서 단어를 여러개 한번에 뱉고 그걸 큰 모델(타겟 모델)이 빠르게 확인하는 기술입니다. 이런 장점 때문에 Apple Slicon 진영, Windows 진영과 NVIDA 진영 모두 이 추측 디코딩을 활발하게 지원해주고 있습니다. 

 

추측 디코딩을 적용했을 때 이론적으로 TPS가 적용하기 전보다 2~3배 가까이 성능 개선이 이루어지고 조금 극단적인 환경(모든 환경이 최상으로 맞춰진 경우)에서는 4배까지도 성능 개선이 이루어집니다. 

 

여기서 짚고 넘어가야할 점이 있죠. 바로 "답변의 퀄리티가 그대로 유지된다" 라는 점인데요. 정말일까요? 

 

Rejection Sampling

LLM이라는 것이 등장하기 이전에 등장한 개념으로 단순하게 말해서 수학적 트릭입니다. 확률 분포에 일치하는 것은 수용하고 일치하지 않는 것은 거절하는 로직인데 이 개념이 AI 엔지니어링에서도 적용되었습니다. 

 

이 때문에 추론 속도가 필요한 서비스에서 주로 사용하는데 국내에서 좋은 사용 사례는 네이버 클로바의 클로바 노트에서 음성을 텍스트로 찍어주는 서비스에서 이 기술을 이용해서 톡톡히 재미를 본 것 같습니다. 

 

Speculative Decoding 실전 사용시 유의사항

꽤나 흥미로운 기술인 것과 다르게 실전에서 신경써야 할 부분이 꽤 있습니다. 다만, 지금부터 나열할 유의사항은 VRAM이 넉넉한 환경에서는 전혀 해당하지 않습니다. 단지 한정된 VRAM으로 개발하던 저의 발버둥이라고 생각해주시면 됩니다. 

 

 

타겟 모델과 드래프트 모델의 토크나이저 일치

첫번째로 큰 모델과 작은 모델간에 토크나이저가 일치해야 답변 퀄리티가 상당히 깨지지 않는다는 점을 유의해야합니다. 토크나이저가 일치해야한다는 것은 두 모델이 서로 같은 확률 분포 곡선의 형태를 띄고 있어야한다는 것이고 이는 만약 타겟 모델에 LLama를 썼다면 드래프트 모델도 LLama를 써야한다는 것입니다. 

 

추측 디코딩을 사용할 때 가장 간단하면서도 지키지 않았을 때 답변 퀄리티에 치명적인 결함을 발견할 수 있는 가장 중요한 유의사항입니다. 

 

Speculative Decoding과 양자화

두번째는 타겟 모델과 드래프트 모델간의 양자화 정도에 대한 일치가 있어야합니다. 예를 들어서 타겟 모델은 4비트 양자화 버전인데 드래프트 모델은 8비트 양자화 모델이면 답변 퀄리티에 결함이 생깁니다. 

 

양자화는 확률 분포에 노이즈를 만든다는 의미이고 이는 부동소수점 이하 부분을 플랫하게 눌러주는 것이기 때문에 서로 양자화 정도가 맞지 않으면 타겟 모델이 드래프트 모델의 답변을 수락할 확률이 떨어져 TPS적으로 큰 향상을 이뤄낼 수 없습니다. 

 

TPS의 극단적인 향상을 위한다면 드래프트 모델은 최대한 작게

많은 개발자들이 권장하는 타겟 모델과 드래프트 모델간의 비율은 100:1입니다. 만약 100B짜리 타겟 모델을 사용한다면 드래프트 모델로 1B를 사용하라는 이야기이죠. 

 

드래프트 모델의 주 역할은 답변의 퀄리티를 올리는 것이 아니고 얼마나 빠르게 드래프트 토큰을 생성하느냐입니다. 때문에 타겟 모델과 드래프트 모델간 격차가 크면 클수록 TPS는 기존에 비해 더 극단적인 향상을 이뤄냅니다. 

 

저의 경우 12B를 사용했는데 1B의 드래프트 모델을 사용하니 그렇게 큰 성능 향상은 얻지 못했습니다. 

 

웬만하면 NVIDA 환경, 그리고 서버에서 사용할 것

Apple Silicon 진영과 Windows에서 사용하는 llama.cpp는 vLLM과 다르게 타겟 모델과 드래프트 모델을 왔다갔다 하면서 생기는 컨텍스트 스위칭 비용이 꽤나 크게 작용합니다. 이 때문에 생기는 문제도 크지만 개인용 PC와 서버간의 하드웨어적인 점도 유의해야합니다. 

 

개인 PC의 경우 아무리 메모리 대역폭이 좋아봐야 200GB/s인 반면 일반적으로 서버용 하드웨어에서의 메모리 대역폭은 3000GB/s에 달합니다. 추측 디코딩은 메모리에서 가중치를 읽어오는 횟수가 늘어나는 작업이라 대역폭이 낮은 환경에서는 소프트웨어의 최적화보다 하드웨어의 대역폭 한계가 TPS에 결정적인 요인이 됩니다. 

 

VRAM이 부족하다면 사용하지 말 것

어찌보면 당연한 얘기일 수도 있는데요. 기본적으로 LLM 모델을 단독으로 사용할 경우 모델을 VRAM에 올리는 것과 더불어 KV Cache를 VRAM에 올려야하는데 드래프트 모델까지 VRAM에 올리게 되면 메모리 압박이 심해져 성능 향상을 기대하기 어렵게 됩니다. 

 

vLLM의 경우 Paged Attention으로 어느정도 메모리 단편화를 막을 수 있지만 llama.cpp를 사용했던 저는 메모리 단편화가 심하게 생겨서 VRAM이 조금만 부족해져도 바로 OOM으로 뻗어버리는 일이 잦았습니다. 

 

그렇다고 VRAM의 점유를 줄이기 위해 KV Cache를 양자화하는 선택은 더 큰 병목으로 이어지는데요. 

 

KV Cache를 양자화하게 되면 다시 Dequantize하는 과정에서 심각한 오버헤드가 발생하면서 원했던 TPS가 안나올 수도 있습니다. 

 

결론

"VRAM이 빵빵한 NVIDA 그래픽카드 서버가 아니라면 사용하는 것이 조금 꺼려진다."

 

저의 경우 타겟 모델로는 Gemma-3-12b-it-Q8_0 모델을 사용했고 드래프트 모델로는 Gemma-3-1b-it-Q8_0를 사용했었는데요. 기존 9TPS가 나오던 것이 11TPS가 나오면서 아주 조금의 성능 향상은 이루어냈지만 그에 상응하는 VRAM의 부족이라던가 간헐적으로 컨텍스트가 너무 길어지면 생기는 OOM이 너무 치명적이어서 추측 디코딩은 포기했습니다. 

 

제 맥북도 VRAM을 24GB나 사용할 수 있는 어찌보면 개인이 사용할 수 있는 컴퓨터중 좋은쪽에 속했지만 VRAM은 정말 항상 부족하네요. (나도 H200줘라 ㅜㅜ)

 

대안으로 Medusa나 Eagle을 찾아봤지만 이것도 결국 NVIDA 환경에서 정확히는 vLLM 환경에 최적화 되어있기 때문에 결국 llama.cpp를 사용하는 저의 경우엔 타겟 모델 하나만 사용하는게 속편한 상황이 됐습니다. 

 

이리저리 온몸비틀기 해봤지만 결국 상처만 남아버렸죠... 

 

그래도 의미없는 경험은 아니었다고 생각합니다. 덕분에 추측 디코딩도 더 공부할 수 있었고 llama.cpp도 더 익숙해질 수 있었습니다. 저도 얼른 NVIDA 서버도 다뤄보고싶네요. 아직 vLLM이 미지의 영역이라 한번 꼭 H100이나 H200에서 개발해보고싶습니다. 

 

오늘 포스팅은 여기서 마치도록 하겠습니다. 긴 글 읽어주셔서 감사합니다. 오늘도 즐거운 하루 되세요!