근 관심을 두고 있는 부분 자료가 있어 정리해 봤습니다. 개발 중인 inference engine (LunarServ)이 아직 걸음마 단계이지만, 회사 내부 서비스와 결합해서 PoC를 해보려고 이제 첫발을 떼고 있는 중입니다. 그러다 보니 사용자 관점, 서비스 운영 관점에서 어떤 것들이 더 필요한가, 어떤 부분들이 pain point가 될 것인가를 나름 고민해 보게 되었는데 제가 생각하고 있던 것과 유사한 논문이 있어 읽어 봤습니다. 😁
이 논문에서 제안하는 QLM(Queue Management for LLM Serving)은 “어떻게 하면 LLM을 빠르고 안정적으로 서비스할 수 있을까 = SLO를 최대한 맞출 수 있을까"에 대한 고민에서 시작했습니다.
일단 기존 LLM 서빙 시스템(vLLM이나 TGI 등)은 대개 연속 배치(continuous batching)와 FCFS(선입선출) 위주로 작동합니다. 그러다 보니 요청이 몰리면, 뒤쪽 요청들이 앞에 있는 오래 걸리는 요청에 발이 묶여서 늦게 처리되는 HOL(Head-of-Line) 차단 문제가 생기죠. 논문에서는 이런 비효율을 해결하려면, 단순히 요청을 “오기만 하면 처리”하는 게 아니라 “어떤 요청을 언제, 어느 GPU에서 실행해야 좋은가”를 세밀하게 결정해야 한다고 말합니다.
HOLB 이슈 하면, 제가 또 할말이 많은데 SSD 과제랑 연관이 있어서 여기에 적을 수는 없겠네요 구글향 과제를 하면서 구글로부터 많이 배웠던 부분들이 있었거든요. 여러모로... 🫢
QLM의 핵심 아이디어는 크게 두 가지입니다. 첫째, 요청들을 비슷한 특성을 가진 그룹(Request Groups)으로 묶어서, 큐를 단순 FCFS가 아닌 “가상 큐(Virtual Queues)” 형태로 관리합니다. 둘째, 이 가상 큐를 재정렬할 때 확률적 프로그래밍(Stochastic Programming)을 활용한다는 점입니다. 출력 토큰 길이나 디코딩 시간이 정확히 정해져 있지 않기 때문에, 논문에서는 이를 확률 분포로 모델링하고, RCT(Request Completion Time) 추정기를 통해 각 요청(또는 요청 그룹)의 예상 완료 시간을 구합니다. 그리고 그걸 종합해 “플랜 생성기(Plan Generator)”가 최적의 큐 순서를 짜주는 식이죠.
논문에서는 LLM serving engine(system)들이 제공하는 여러 backend 동작들 중 몇개를 LSO(LLM Serving Operation)라고 해서, 모델 스왑(GPU-CPU Swapping), request eviction, model warm start 등 5개를 정의 했습니다. QLM은 이 액션들을 상황별로 어떻게 조합할지를 결정해서, 불필요한 모델 교체를 줄이고, latency가 길어지는 것을 막으며, gpu utilization을 높이고 있습니다. 멀티 모델 환경에서 자주 쓰이는 모델과 쓰임새가 적은(tail) 모델이 섞여 있을 때, 요청 그룹을 잘 배분해놓으면 같은 리소스로도 처리량이 훨씬 늘어나고, SLO를 만족하는 비율이 크게 오른다는 것을 보이고 있네요.
물론 QLM도 한계는 있습니다. 워낙 많은 요청이 들어오거나 GPU가 부족하면, 결과적으로 스케일 업(장비 증설)을 해야 하는 상황이 생길 수밖에 없는데요. 또 스케줄링 문제 자체가 NP-hard라서, 요청 그룹 크기(δ)를 너무 작게 잡으면 계산 오버헤드가 커지고, 너무 크게 잡으면 결정의 정밀도가 떨어지는 식의 트레이드오프도 있습니다.
그래도 전체적으로 보니, “LLM 서빙을 효율화”하려고 큐 관리부터 확률 모델링까지 다뤘다는 점에서 꽤 실무 지향적인 느낌이 들었습니다. 모델 하나만 쓰는 간단한 상황부터, 여러 모델을 동시에 돌려야 하는 복잡한 환경까지 고려하고 있으니까요. 개인적으로는 vLLM이 여러모로 대단한 엔진이지만, 실무 단계에서 사용하기에 (SLO 측면에서) 어려움이 있지 않을까? 하는 궁금증이 있었거든요. 실제 서비스에 사용하는 것 같긴 하지만요. 🤷🏻♂️
QLM의 실험 결과를 보면, FCFS나 단순 EDF에 비해 훨씬 높은 처리량과 SLO 만족률을 보여줍니다. 특히 멀티 모델 서빙에서 모델 스왑을 최소화해 GPU 메모리를 안정적으로 활용하는 부분이 흥미롭더라고요.
LLM 서빙 하시는 분들은 멀티 모델 지원 관련해서 이런 고민을 많이 하셨을 것 같은데 다들 어떻게 하시는지 궁금하네요.
정리하자면, QLM은 LLM 서빙에 있어서 “어떤 요청이 언제 들어왔으니 그냥 처리하자” 수준을 넘어, “대기열과 모델 로딩, 토큰 길이까지 종합적으로 고려해보자”라는 전환점을 제시한 시스템으로 보입니다. 만약 LLM 서빙 관련해서 고민이 있으시면, 이 논문에서 제안하는 Request Groups, Virtual Queues, 그리고 확률적 프로그래밍 기반의 플랜 생성 방식을 한 번 참고해보셔도 좋을 것 같습니다. 간단하게 꽤 좋은 효율을 보여주고 있는 것 같네요 😄