모든 AI 모델(클래식 ML, 딥러닝, 에이전트)을 위한 단일 플랫폼 - 30만+ QPS, 10ms 미만 대기 시간, 튜닝 불필요
작성자: Anshul Gupta
머신러닝 모델을 프로덕션에 배포할 때는 일종의 계약을 맺는 것과 같습니다. 트래픽 급증에 관계없이 모든 요청이 수 밀리초 내에 완료되고, 트래 픽이 적을 때는 비용이 낮게 유지된다는 계약 말이죠. 모델 서빙은 이 계약을 지켜주는 인프라입니다. 업계 역사상 이 계약을 유지하는 것은 모델을 구축하는 것만큼이나 어려웠습니다.
커스텀 모델은 파운데이션 모델과 근본적으로 다릅니다. 파운데이션 모델(Llama, Mistral, CLIP 변형 등)을 호스팅하는 플랫폼은 아키텍처, 메모리 사용량, 추론 특성 등 자신이 무엇을 실행하고 있는지 정확히 알고 있으므로 해당 모델 하나에 대해 깊이 있게 최적화할 수 있습니다. 커스텀 모델 플랫폼은 그 반대입니다. 동일한 플랫폼이 단일 CPU 코어에서 2 MB 크기의 scikit-learn 분류기를 서빙하는 동시에, 8개의 GPU에서 미세 조정된 70B LLM을 서빙해야 합니다. 대기열을 허용하지 않는 저지연 랭커와 적극적인 배칭을 통해 성능이 극대화되는 임베딩 모델을 모두 처리해야 합니다. 리소스 프로필, 트래픽 형태, 지연 시간 예산이 제각각인 온갖 종류의 모델을 모두 서빙할 수 있는 플랫폼이어야 하는 것입니다.
기존 플랫폼은 레플리카 수, 레플리카당 동시성, 오토스케일링 임계값 설정 등 이러한 복잡성을 고객에게 떠넘깁니다. 이는 추상화 수준만 높아졌을 뿐 여전히 직접 해결해야 하는 DIY 작업입니다. 게다가 끝이 없습니다. 새로운 모델이 나오거나 트래픽이 바뀔 때마다 프로파일링과 튜닝을 다시 해야 하므로, 우수한 엔지니어들이 배포 전후로 프로덕션 장애 대응에 매달려야 하고, 결국 서빙이 모든 출시를 가로막는 걸림돌이 됩니다. 그 결과 가장 뼈아픈 비용이 발생합니다. 개발 단계에서 검증된 모델이 프로덕션에 도달하기까지 몇 주 동안 방치되는 것입니다.
서빙 인프라를 수동으로 재튜닝하는 것은 조직이 운영하는 모든 모델에 부과되는 세금과 같습니다. 규모가 커지면 이는 구조적인 문제가 되며, 모델을 프로덕션에서 안정적이고 성능 좋게 유지하는 것만을 전담하는 서빙 팀을 따로 구성해야 할 정도가 됩니다. 우리는 이를 ML 스택 세금이라고 부릅니다.
Databricks Custom Model Serving은 MLflow에 패키징된 모든 모델을 위한 완전 관리형 실시간 추론 플랫폼입니다. 우리의 미션은 모델 수명의 세 단계에 걸쳐 이 세금을 없앰으로써 고객의 서빙 팀이 더 정교하고 가치 있는 작업에 집중할 수 있도록 하는 것입니다.

이것이 가능한 이유는 Custom Model Serving이 Databricks에 네이티브로 내장되어 있기 때문입니다. 데이터, 피처, 학습, MLflow 패키징, 서빙, 에이전트가 서로 다른 시스템을 짜깁기한 것이 아니라 하나의 거버넌스된 스택으로 통합되어 있습니다.
이 글에서는 별도의 설정 없이 다양한 모델에서 어떻게 저지연으로 300K+ QPS에 도달하는지에 대한 두 번째 단계를 다룹니다. 이것이 바로 세금을 사라지게 만드는 비결입니다.
아키텍처의 모든 결정은 저지연, 대규모 확장성, 비용 효율성이라는 세 가지 제약 조건에 따라 이루어집니다. 이들은 서로 상충 관계에 있으며(지연 시간을 줄이는 쉬운 방법은 오버프로비저닝하는 것이고, 비용을 줄이는 쉬운 방법은 언더프로비저닝하는 것입니다), 리소스 낭비 없이 모든 종류의 모델에 대해 이 세 가지를 동시에 만족시키는 것이 진정한 엔지니어링 과제입니다.

이를 가능하게 하는 세 가지 요소는 다음과 같습니다.
앞의 두 가지는 단일 요청을 빠르게 유지하고, 세 번째는 모델과 트래픽이 변하더라도 전체 시스템을 빠르고 비용 효율적으로 유지합니다. 이 섹션의 대부분은 세 번째 요소에 대한 내용입니다.
모든 서빙 엔드포인트는 자체 pod와 모델 버전에 특화된 컨테이너 이미지를 갖는 완전히 격리된 Kubernetes 배포입니다. 이러한 격리는 의도된 것입니다. 한 엔드포인트의 트래픽, 장애 또는 리소스 압박이 다른 엔드포인트에 영향을 미칠 수 없으므로 커스텀 워크로드를 안전하게 보호합니다.
지연 시간은 모든 레이어에서 최우선 제약 조건이므로 경로 자체는 가능한 한 짧게 유지됩니다. 요청은 PoP 프록시를 통해 들어오며, 인증이 완료되면 연결 관리를 위한 공유 로드 밸런서를 거쳐 이를 서빙하는 pod에 즉시 도달합니다. 또한 각 pod는 플랫폼 모니터링 및 고객용 대시보드를 위해 메트릭, 로그, 페이로드 로그, 트레이스를 내보내는 관측성 사이드카를 실행합니다.

각 pod 내부에서 모델은 해당 유형에 가장 적합한 추론 엔진에서 실행됩니다. 클래식 ML 모델을 위한 비동기 Gunicorn MLflow 서버부터 vLLM, Triton 또는 고객 자체 런타임을 지원하는 대형 모델용 GPU 최적화 엔진에 이르기까지, 이 모든 것이 하나의 일관된 서빙 인터페이스 뒤에서 작동합니다.

자체 제작한 커스텀 Kubernetes 컨트롤러인 AutoPilot Pod Autoscaler (APA)가 플랫폼의 중심에 위치합니다. 이 컨트롤러는 로드 밸런서(활성 동시성, 대기열 깊이)와 pod 자체(CPU 사용률, GPU 사용률, GPU 메모리 등)로부터 지속적으로 신호를 수집하여 스케일링 결정을 내립니다.
이 오토스케일러는 두 가지 예측 불가능성을 동시에 흡수하기 위해 존재합니다.
이것이 바로 오토스케일러가 시스템의 핵심인 이유입니다. 플랫폼의 모든 모델에 대해 지연 시간, 규모, 비용이라는 세 가지 제약 조건을 동시에 만족시키는 유일한 구성 요소이기 때문입니다.
기존의 오토스케일러는 요청 기반 또는 리소스 기반 오토스케일링을 수행하지만, 각각 단점이 있습니다. 요청 기반 스케일링은 빠르게 반응하지만 비효율적입니다. 각 레플리카의 부하 상태에 관계없이 모든 요청을 동일하게 처리하므로 오버프로비저닝이 발생하거나 레플리카 수가 요동치게 됩니다. 리소스 기반 스케일링(CPU, GPU 사용률)은 효율적이지만 지연이 발생합니다. 사용률 메트릭은 트래픽보다 뒤늦게 반영되므로, 오토스케일러가 작동할 때쯤에는 이미 p99 지연 시간에 타격을 입은 후입니다.

수평 스케일링은 요청에 반응합니다. 엔드포인트당 활성 동시 요청 수를 모니터링하고 수요가 변화하는 순간 레플리카를 추가하거나 제거합니다. 공식은 Kubernetes Horizontal Pod Autoscaler를 따릅니다.
모델 인식형 수직 스케일링은 모델의 특성에 반응합니다. 오토스케일러는 주기적으로 일련의 메트릭을 살펴보고 단일 레플리카가 실제로 처리할 수 있는 부하가 어 느 정도인지 판단한 다음, 위의 공식에서 target_concurrency를 이에 맞게 조정합니다. 이는 하드웨어 유형을 변경하는 기존의 수직 스케일링과는 근본적으로 다릅니다. 여기서는 하드웨어가 동일하게 유지되며, 변경되는 것은 각 파드가 수용하는 동시 요청 수로, 이는 해당 파드에서 실행 중인 모델의 리소스 프로필에 맞춰 조정됩니다.
저희가 활용하는 메트릭은 다음과 같으며, 이에 국한되지 않습니다:
안전 장치. 노드당 동시성 변경은 민감한 작업이며, 변동이 크거나 빈번하면 시스템 성능이 저하될 수 있습니다. 파드 메트릭은 일시적인 트래픽 변화나 모델에 따라 요청당 비용 차이가 클 때 변동될 수 있습니다. 저희는 이러한 메트릭 노이즈에 대비한 안전 장치를 마련했습니다. 일시적인 CPU 급증으로 인해 동시성 제한이 즉시 축소되었다가 몇 초 후에 다시 확장되어서는 안 됩니다. 이를 위해 세 가지 단계를 거칩니다:
동시성은 메트릭이 안정적인 임계값을 넘어설 때만 조정되며, 임계값은 메트릭별로 조정됩니다.
두 축은 서로 결합되어 있습니다: 수직 스케일링의 동시성 출력은 target_concurrency 분모를 통해 수평 스케일링 계산에 반영됩니다. 수평 스케일링은 트래픽이 변하는 순간 가용성과 낮은 지연 시간을 보장합니다. 모델 인식형 수직 스케일링은 각 노드가 효율적으로 사용되도록 하고, 모델 동작이 변화함에 따라 동시성 규모를 적절히 조정합니다. 이 두 가지가 결합되어 '빠르지만 낭비가 심한 방식'과 '효율적이지만 느린 방식' 사이에서 고민할 필요가 없어집니다.
기본적인 HPA 공식만으로는 충분하지 않습니다. 급증하는 트래픽에 유연하게 대처하지 못하기 때문입니다. 일시적인 10배 급증은 10배의 레플리카 증가를 계산하고, 일시적인 95% 감소는 95% 감소를 계산합니다. 두 경우 모두 비용이나 지연 시간 및 가용성 측면에서 위험합니다.
수평 스케일 업은 공격적으로 진행됩니다. 프로덕션 환경에서 높은 지연 시간은 비즈니스에 막대한 부정적 영향을 미칠 수 있습니다. 많은 사용 사례가 기본적으로 지원이 필수적인 급격한 스파이크성 트래픽 패턴을 보입니다. 이러한 스파이크를 처리하기 위해 저희는 1초마다 유입되는 요청을 수집하며, APA는 지난 20초 동안의 트래픽을 기반으로 5초마다 업스케일링 결정을 내립니다. 이를 통해 스파이크 발생 시 대기열 발생과 429 에러를 크게 줄일 수 있으며, 실제로 많은 고객이 최대 5배의 차이를 경험했습니다. 또한 현재 부하를 고려하여 단일 주기에서 스케일 업할 수 있는 범위를 제한합니다. 결과적으로, 60초 미만 만에 10 QPS에서 10K QPS로 확장할 수 있습니다(모델 로드 시간에 따라 다름).
스케일 다운은 보수적으로 진행됩니다. 트래픽 급증은 종종 더 많은 트래픽이 유입될 것이라는 신호입니다. 스케일 다운의 경우, APA는 여전히 5초마다 결정을 내리지만 레플리카를 제거하기 전에 지난 약 5분 동안의 트래픽을 고려합니다.
이러한 비대칭성은 의도된 것입니다. 급증은 갑작스럽게 발생하지만, 감소는 일시적인 경우가 많습니다. 조기 스케일 다운으로 인한 비용(가장 최악의 순간에 발생하는 콜드 스타트)이 몇 개의 유휴 레플리카를 일시적으로 유지하는 비용보다 훨씬 큽니다.

수직 동시성 스케일 업 및 스케일 다운. 수직 스케일링에도 동일한 비대칭 철학이 적용됩니다. 파드에 과부하가 걸리면 동시성을 빠르게 줄이되(이미 부하가 걸린 레플리카로 라우팅되는 요청을 줄여 지연 시간을 보호함), 최소값 미만으로는 낮추지 않습니다. 이러한 결정은 5초 주기의 수평 루프보다 느린 30초 간격으로 실행됩니다. 이는 의도된 것입니다. 수직 스케일링은 스파이크에 실시간으로 반응하는 것이 아니라, 시간이 지남에 따라 모델의 리소스 프로필에 적응하는 정상 상태 최적화이기 때문입니다.
콜드 스타트는 서빙 시스템에서 최악의 지연 시간 이벤트입니다. 일단 발생하면 최적화만으로는 해결하기 어렵습니다. 저희는 두 가지 방향에서 이 문제에 접근합니다. 가능한 한 많은 부분을 미리 준비(pre-warm)된 상태로 유지하고, 피할 수 없는 부분은 최대한 빠르게 처리하는 것입니다.
웜 노드 풀. 예측 알고리즘은 기본 런타임 이미지가 미리 로드된 사전 프로비저닝된 노드 풀을 Databricks 클러스터별로 유지합니다. 오토스케일러가 레플리카를 추가할 때 이 풀에서 선택합니다. 노드는 이미 가동 중이고 기본 이미지는 이미 풀(pull)되었으므로 남은 작업은 모델을 다운로드하는 것뿐입니다. 저희는 고객에게 웜 풀 용량에 대한 비용을 청구하지 않으며, 이는 고객이 Databricks로부터 얻을 수 있는 직접적인 가치입니다.
빠른 모델 다운로드. 모델 컨테이너 이미지는 클라우드 스토리지의 핫 캐시 레이어에 저장되며 파드 시작 시 병렬 청크로 풀(pull)되므로, 대규모 모델 컨테이너의 이미지 풀 시간을 크게 단축합니다. 모델이나 모델의 종속성에 영향을 미치지 않는 구성 변경(엔드포인트 메타데이터 업데이트, 라우팅 규칙 변경)은 파드를 전혀 재시작하지 않고 적용됩니다. 재시작을 피하는 것이야말로 가장 완벽한 웜 스타트이기 때문입니다.
프로비저닝된 동시성. 콜드 스타트를 전혀 허용할 수 없는 지연 시간에 민감한 엔드포인트의 경우, 사용자는 최소 동시성 하한선을 구성할 수 있습니다. 이를 통해 모델이 로드되고 즉시 서빙할 준비가 된 파드의 기준선을 완전히 유지하므로, 첫 번째 요청 시 대기열이 발생하지 않습니다.
제로 다운타임 업데이트 및 유지 관리. 업데이트 및 유지 관리는 완전히 중 단 없이(zero-downtime) 진행됩니다. 트래픽이 기존 파드에서 이동하기 전에 새 모델 버전이 적용된 모든 파드가 가동되어 준비를 마칩니다.
고객들은 모든 차원에서 이점을 경험했습니다.
이축 오토스케일러는 다양한 모델 유형에 걸쳐 일반화됩니다. CPU 분류기부터 GPU LLM에 이르기까지 모든 모델에 수평 + 수직 접근 방식이 적용될 수 있을지 확신하지 못했습니다. 하지만 실제로 적용되었습니다. 수평 축은 모든 모델에 대해 동일한 방식으로 트래픽을 처리하는 반면, 수직 축은 가벼운 모델에는 더 높은 동시성을, GPU 집약적인 모델에는 더 낮은 동시성을 적용합니다. 동일한 컨트롤러, 동일한 로직으로 각 모델에 맞는 최적의 동작을 수행합니다.
대부분의 모델은 균질합니다. 저희는 동시성 제한이 트래픽에 따라 계속 변할 것이라고 생각했지만, 실제로는 동일한 부하에서 모델의 리소스 프로필이 대부분 비슷하게 유지되었습니다. 수직 축은 온보딩 중에 제 역할을 톡톡히 해낸 후 조용해집니다.
콜드 스타트를 완전히 없애도록 최적화할 수는 없습니다. 저희는 웜 풀, 병렬 이미지 풀, 배포 재사용을 통해 콜드 스타트를 거의 제로에 가깝게 줄일 수 있을 것으로 기대했습니다. 이러한 방법들이 큰 도움이 되지만, 물리적인 한계가 존재합니다. 파드를 가동하는 데는 모델 크기에 비례하여 시간이 걸리며, 대규모 GPU 모델의 경우 몇 분이 소요되기도 합니다. 그 한계를 넘어서면 유일한 해결책은 최소 용량을 완전히 준비된 상태로 유지하는 것이며, 이것이 바로 최소 프로비저닝된 동시성이 존재하는 이유입니다.
트래픽은 보기보다 더 예측 가능합니다. 적절한 최소값은 고정되어 있지 않습니다. B2C 앱은 밤사이에 한산해지고, 배치 파이프라인은 일정에 따라 실행됩니다. 이러한 패턴은 학습이 가능하며, 저희는 수요를 뒤쫓는 대신 수요에 앞서 최소 동시성을 높일 수 있도록 트래픽 예측 기능을 구축하고 있습니다. 앞으로의 업데이트를 기대해 주세요.
저희는 끝없는 재조정과 이를 위해 필요한 전담 서빙 팀을 의미하는 ML 스택 세금(ML Stack Tax)을 제거하고자 했습니다. 오늘날 Custom Model Serving에서 실행되는 매우 다양한 모델에 대해, 이축 오토스케일러, 웜 풀, 제로 다운타임 배포가 바로 그 역할을 해냅니다. 인프라가 모델에 맞춰 조정되며, 그 반대가 아닙니다. 모델을 가져와 동시성 범위를 설정하기만 하면 플랫폼이 나머지를 알아서 처리합니다.
하지만 모델 서빙은 아직 완전히 해결된 분야가 아닙니다. 더 거대한 모델, 새로운 하드웨어, 에이전트 기반(agentic) 워크로드는 기존 서빙 인프라가 감당하도록 설계된 수준을 넘어서는 규모와 복잡성을 계속해서 요구하고 있습니다. 해결해야 할 과제들은 실재하며 저희의 목 표는 원대합니다. 콜드 스타트 시간 단축, 예측 스케일링을 위한 트래픽 예측, 엔드포인트당 1M+ QPS 및 클러스터당 10M+ QPS 달성, 이기종 GPU 워크로드의 더 스마트한 빈 패킹(bin-packing), p99 지연 시간을 5ms 미만으로 단축하는 것 등이 있습니다.
그리고 이는 Databricks가 독보적인 역량으로 해결할 수 있는 문제입니다. 인프라를 모델에 맞추려면 모델을 이해해야 합니다. 즉, 모델이 어떻게 학습되었는지, 무엇에 의존하는지, 부하가 걸렸을 때 어떻게 작동하는지 알아야 합니다. Databricks에서는 이 모든 것이 단일 거버넌스 플랫폼 내에 존재합니다. 데이터와 피처, 학습, MLflow 패키징, 서빙, 에이전트, 그리고 이들을 모니터링하는 텔레메트리까지 모두 포함됩니다. 독립형 서빙 레이어는 컨테이너만 보지만, 저희는 전체 라이프사이클을 봅니다. 이러한 맥락이 있기에 플랫폼이 각 모델에 맞게 자체적으로 최적화할 수 있으며, 다른 어떤 추가적인 서빙 제품도 ML 스택 비용(ML Stack Tax)을 이만큼 해결할 수 없는 것입니다.
이러한 인프라 문제를 해결하는 데 관심이 있으시다면, 현재 채용 중이니 지원해 보세요.
(이 글은 AI의 도움을 받아 번역되었습니다. 원문이 궁금하시다면 여기를 클릭해 주세요)
블로그를 구독하고 최신 게시물을 이메일로 받아보세요.