프로덕션 환경에서의 LLM 추론 라우팅: 엔진 시그널부터 정책까지 — Qianru Lao & Lu Zhang, OpenAI

AAI Engineer
AI/미래기술컴퓨터/소프트웨어

스크립트

00:00:00- 안녕하세요, 발표에 참석해 주셔서 감사합니다.
00:00:14저는 루이고, 제 동료 체인루입니다.
00:00:17오늘 저희가 다룰 주제는
00:00:20저희 둘 다 OpenAI의 추론 팀에서 일하고 있는데요,
00:00:23오늘 이야기해 볼 주제는
00:00:24프로덕션 환경에서의 LLM 추론 라우팅입니다.
00:00:27구체적으로는 저희 시스템이 어떻게 진화했는지,
00:00:29엔진 신호 기반 피드백 루프 라우팅에서
00:00:32더 명확하고 예측 가능한 정책으로
00:00:35어떻게 발전했는지 이야기하려 합니다.
00:00:37여전히 엔진 신호의 정보를 활용하긴 하지만
00:00:39그 신호를 활용하는 방식 자체가 달라진 셈이죠.
00:00:43오늘 아젠다를 말씀드리면,
00:00:44우선 추론 로드 밸런서가
00:00:46무엇인지 소개하며 시작할 것입니다.
00:00:48어떤 역할을 하고 어떻게 진화해 왔는지 말이죠.
00:00:51이어서 체인루가 새로운 제어 평면과
00:00:53데이터 평면 기반 아키텍처를 설명하고,
00:00:56각각의 역할이 무엇인지 알아본 뒤
00:00:59글로벌 네트워크 오버헤드를 줄인
00:01:01구체적인 사례 연구를 살펴보겠습니다.
00:01:05마지막에는 제가 다시 돌아와서
00:01:07프로덕션 수준의 부하 속에서도 시스템을 안정적으로
00:01:10유지해 주는 보호 메커니즘을 설명하겠습니다.
00:01:13우선, 추론 로드 밸런서란 무엇일까요?
00:01:17그리고 어디에 위치할까요?
00:01:20이것은 저희가 다루는 시스템의 매우 개략적인 다이어그램입니다.
00:01:25왼쪽 편에는 프론트엔드 클러스터들이 있습니다.
00:01:29아 죄송합니다, GPU가 아니라 CPU 클러스터들로,
00:01:33저희 시스템의 게이트웨이 역할을 합니다.
00:01:36사용자 요청을 받아 추론 엔진이 처리할 수 있는
00:01:42추론 요청의 형태로 준비하죠.
00:01:44그리고 오른쪽 편에는 엔진 클러스터들이 있습니다.
00:01:47보통 GPU 클러스터이며, 각각 여러 추론 엔진을 호스팅합니다.
00:01:53그래서 엔진 클러스터라는 이름이 붙은 것이죠.
00:01:56잘 아시겠지만 요즘 GPU는 인기도 많고 매우 비쌉니다.
00:02:02그 중간에 위치한 것이 바로 IRB, 즉 추론 로드 밸런서입니다.
00:02:07실제로는 프론트엔드 클러스터에서 동작하지만, 추론 스택으로 이어지는 다리 역할도 합니다.
00:02:14핵심 역할은 두 가지입니다. 엔진 선택과 요청 근사화죠.
00:02:19이번 발표에서는 엔진 선택 부분에 집중해 보겠습니다.
00:02:23어떤 면에서 IRB는 매우 전통적인 로드 밸런서와 유사합니다.
00:02:28요청은 보통 하나의 모델을 타깃으로 하고, 모델 뒤에는 여러 엔진이 받쳐주고 있으니까요.
00:02:35이 엔진들은 서로 다른 지역의 클러스터나 대륙 건너편에 존재할 수도 있습니다.
00:02:40지역적 성능 저하나 클러스터 장애에 대해 훌륭한 복원력을 제공하기 때문이죠.
00:02:46하지만 추론 스택 혹은 추론만의 특수성으로 인해 수많은 세부사항이 발생합니다.
00:02:53실시간으로 보고되는 여러 신호를 고려해야 하기 때문인데요,
00:02:59잘 알려진 첫 토큰 생성 시간(TTFT), 출력 토큰 간격 시간,
00:03:05즉 토큰 처리량이나 토큰 간격 시간(TBT) 외에도,
00:03:08기타 부하 상태 및 사용률 신호 등이 있습니다.
00:03:11또한 매우 중요한 개념인 KV 캐시라는 것도 잘 알려져 있죠.
00:03:16예를 들어 대화에 유용한 컨텍스트가 이미 특정 엔진에 캐시되어 있다면,
00:03:22동일한 대화의 후속 요청을 다시 동일한 엔진으로 보내는 것이
00:03:27재계산을 방지하고 효율성을 높이며 지연 시간을 줄여줍니다.
00:03:32따라서 성능, 신뢰성, 데이터 인접성, 캐시 인지의 조합이 이 문제를 흥미롭게 만드는 요소입니다.
00:03:39그렇다면 저희가 이 문제에 어떻게 접근했는지 초기 시절을 살펴보겠습니다.
00:03:45솔직히 말씀드리면 이 분야에서 초기라고 하면 실제 지나간 시간보다 훨씬 아득하게 느껴지네요.
00:03:51당시의 라우팅 프로세스는 필터링부터 시작했습니다. 모든 요청을 모든 엔진이 처리할 수 있는 것은 아니었으니까요.
00:04:01성능상의 제약이나 컴퓨팅 자원, 데이터 거주성 문제로 인한 지리적 제한이 원인이었죠.
00:04:08그리고 남아있는 엔진들 중에서, IRB는 가중치가 적용된 일관된 해싱을 사용해 특정 사용자의 요청을 처리할 최선의 대상 엔진을 선택했습니다.
00:04:19그러면 그 가중치는 어디서 오는지 중요한 질문이 생깁니다.
00:04:24가중치는 주기적인 피드백 루프에 의해 생성되었습니다.
00:04:27앞서 언급했듯 추론 엔진은 관심 대상이 되는 온갖 종류의 신호를 보고합니다.
00:04:33그리고 컨트롤러는 주기적으로 이 신호들을 평탄화하여 성능 점수를 계산합니다.
00:04:40이 성능 점수를 전체 플릿의 평균과 비교하게 되는 것이죠.
00:04:45그런 뒤 가중치가 조정됩니다. 기본적으로 성능이 더 좋아지면
00:04:52가중치가 올라가고, 플릿 평균보다 나쁘면 가중치가 내려가는 방식입니다.
00:04:57이렇게 생성된 가중치는 라우팅에 영향을 주며, 기본적으로 하나의 제어 루프를 이룹니다.
00:05:05개념적으로는 PID 제어기와 매우 유사합니다.
00:05:10참고로 이 PID 제어기는 리눅스 프로세스를 강제 종료(kill)하는 데 쓰이지는 않고요.
00:05:13대신 시스템을 원하는 상태로 지속적으로 유도하는 고전적인 제어 이론 기술입니다.
00:05:20저희는 이 중요한 개념 중 비례(Proportional) 제어 부분을 가져와 시스템에 적용한 것이죠.
00:05:27그래서 이 방식은 매우 훌륭한 특성들을 많이 가지고 있습니다.
00:05:33예를 들어 우리가 신경 쓰는 유용한 신호들을 단일 라우팅 결정으로 결합할 수 있었습니다.
00:05:40그리고 관찰된 성능에 맞춰 적응하기 때문에, 앞서 말씀드렸듯 많은 제약 조건이 존재하더라도 말이죠.
00:05:45그러한 제약으로 인해 일부 엔진은 다른 엔진보다 더 다양한 요청을 처리할 수 있어서 더 바빠질 수 있습니다.
00:05:53하지만 바쁜 상태의 신호가 다음 루프에 반영되면, 제약이 적은 요청들이 이러한 유형의 엔진으로 더 많이 이동하게 됩니다.
00:06:03결과적으로 알아서 균형을 찾아가는 것이죠.
00:06:05어느 정도는 수동 개입을 많이 할 필요가 없다는 의미입니다.
00:06:11그냥 잘 동작하니까요.
00:06:12하지만 그런 적응성에는 큰 트레이드오프가 따릅니다.
00:06:16너무 많은 신호를 조합한다는 바로 그 이유 때문에 특정 라우팅 결정을 이해하기가 매우 까다롭고,
00:06:22특정 엔진이 왜 예상보다 더 높은 가중치를 받았는지 원인을 파악하기 어렵습니다.
00:06:28그리고 특정 측면을 미세 조정하려 할 때마다 다른 부분에 영향을 주지 않기가 거의 불가능했습니다.
00:06:36또한 부하가 항상 고르게 분산되는 것은 아닌데, 때로는 하나의 모델이 서로 다른 GPU 규모의 엔진에서 제공되고
00:06:48그 엔진들이 각기 다른 특성을 가지고 있어서 문제가 훨씬 더 까다로워집니다.
00:06:53게다가 피드백 루프가 때로는 심한 진동을 일으킵니다. 트래픽을 특정 엔진에서 다른 곳으로 돌리면
00:07:03해당 엔진의 부하가 식게 되고, 이 신호가 컨트롤러에 전달됩니다.
00:07:08그러면 컨트롤러는 “아, 이 엔진이 트래픽을 훨씬 더 받겠구나”라고 판단하죠.
00:07:12그러고는 트래픽이 몇몇 엔진 사이를 오가며 요동치게 되고, KV 캐시 활용을 방해하게 됩니다.
00:07:20이러한 모든 한계로 인해 저희는 아키텍처를 재검토하고 이 문제를 해결할 새로운 방법이 있는지 고민하게 되었습니다.
00:07:29이제 체인루에게 마이크를 넘겨 저희가 시도해 본 새 아키텍처를 자세히 들어보겠습니다.
00:07:38네, 감사합니다 루.
00:07:40저는 로드 밸런서의 아키텍처와, 라우팅 알고리즘을 통해 전체 오버헤드를 어떻게 줄였는지 말씀드리겠습니다.
00:07:50로드 밸런서는 한 가지 질문에 답합니다.
00:07:53CPU 클러스터에서 들어오는 각 요청을 어떤 엔진이 처리해야 할까요?
00:07:59가장 단순한 기준은 엔진에 요청을 균등하게 보내는 라운드 로빈일 것입니다.
00:08:06하지만 조금만 더 생각해 보면 이건 적절하지 않습니다.
00:08:09엔진은 동질적이지 않고, 하드웨어 성능과 용량이 다를 수 있으며
00:08:15상태도 다르고 CPU 클러스터와의 거리도 제각각이기 때문이죠.
00:08:19또한 라운드 로빈은 캐시 지역성을 깨뜨릴 수 있습니다.
00:08:24동일한 엔진 캐시를 재사용할 수 있는 연관된 요청들이 서로 다른 엔진으로 보내질 수 있으니까요.
00:08:30더 나은 해결책은 각 CPU 클러스터가 자체 로컬 관점에서 가장 좋은 엔진을 선택하는 것일 수 있습니다.
00:08:39하지만 그것만으로도 부족합니다.
00:08:41극단적인 경우를 생각해 보세요. 여러 CPU 클러스터가 트래픽을 독립적으로 동일한 엔진에 보낸다면,
00:08:48해당 엔진은 과부하가 걸리고 다른 엔진들은 충분히 활용되지 못할 수 있습니다.
00:08:53따라서 우리에게 필요한 것은 전역적으로 최적화된 솔루션입니다.
00:08:57모든 CPU 클러스터와 GPU 엔진을 아우르는 전역 뷰를 가진 제어 평면이 필요하며,
00:09:02전역적으로 최적화된 라우팅 결과값을 계산할 수 있어야 합니다.
00:09:06그리고 데이터 평면은 제어 평면에서 가져온 답을 바탕으로 라우팅 결정을 빠르게 내릴 수 있죠.
00:09:18이제 제어 평면과 데이터 평면 내부를 살펴보겠습니다.
00:09:22데이터 평면에는 각 요청에 맞게 엔진을 선택하는 엔진 셀렉터가 있습니다.
00:09:28이 셀렉터는 후보 엔진들과 각 후보 엔진의 라우팅 가중치가 포함된 로컬 라우팅 상태를 읽습니다.
00:09:37이 두 가지 정보는 모두 백그라운드에서 비동기적으로 갱신됩니다.
00:09:41따라서 각 요청에 대한 라우팅 결정을 내리기 전에 제어 평면에 물어볼 필요가 없습니다.
00:09:48또한 데이터 평면은 준비된 복제본 수, 엔진 상태 등과 같은 실시간 엔진 신호를 수집하여
00:09:56빠른 로컬 가드레일 역할을 하도록 합니다.
00:10:00제어 평면에서는 데이터 로더가 실시간 엔진 신호와 네트워크 오버헤드를 결합합니다.
00:10:06그리고 용량, TTFT, TBOT에 대한 오프라인 회귀 분석을 통해 옵티마이저가 이 데이터들을
00:10:14라우팅 가중치로 변환합니다.
00:10:16그러면 제어 평면은 각 데이터 평면이 가져갈 수 있도록 라우팅 가중치를 게시합니다.
00:10:21이러한 방식을 통해 어떤 요청도 데이터 평면에서 대기할 필요가 없습니다.
00:10:26제어 플레인은 지속적으로 다음의 전역 최적화된 라우팅 가중치 스냅샷을 계산하고,
00:10:32데이터 플레인은 로컬에 이미 적용된 최신 스냅샷을 기반으로 라우팅 결정을 내립니다.
00:10:42요약하자면, 시스템에는 세 가지 중요한 경로가 있습니다.
00:10:46첫 번째 경로는 추론 요청 경로입니다.
00:10:49요청이 CPU 클러스터에 도달하면, CPU 클러스터 내부의 데이터 플레인이
00:10:55로컬 라우팅 상태를 기반으로 해당 요청을 처리할 엔진을 선택하고, 선택된 엔진으로 요청을 전달합니다.
00:11:03두 번째 경로는 엔진 신호 경로입니다.
00:11:06시스템은 TTFT, TPOT, 준비된 복제본 수,
00:11:15엔진 상태 등 실시간 엔진 신호를 지속적으로 수집합니다.
00:11:17두 플레인 모두 이러한 실시간 엔진 신호가 필요합니다.
00:11:20제어 플레인은 전역 최적화된 라우팅 가중치를 계산하기 위해 신호가 필요하고, 데이터 플레인은
00:11:26빠른 로컬 가드레일을 운영하기 위해 신호가 필요합니다.
00:11:29그리고 세 번째 경로는 라우팅 가중치 경로입니다.
00:11:32제어 플레인이 라우팅 가중치를 계산하여 게시하면, 데이터 플레인은
00:11:38업데이트를 가져와 로컬 캐시에 저장합니다.
00:11:41따라서 첫 번째 경로만 동기식이지만, CPU 클러스터의 데이터 플레인 내부에서만 이루어지므로 매우 빠릅니다.
00:11:49나머지 두 루프는 비동기식 루프이며, 향후의 라우팅 결정을 개선하기 위한 것입니다.
00:11:59아키텍처 부분은 이 정도입니다만, 아직 질문 하나가 남아 있습니다.
00:12:04이러한 라우팅 가중치는 어떻게 계산할까요?
00:12:10그 질문에 답하기 전에 다른 질문부터 먼저 살펴보겠습니다.
00:12:15그냥 가장 가까운 엔진으로 요청을 보내면 안 될까요?
00:12:20트래픽 수요와 GPU 용량이 지리적으로 균형을 이루지 않기 때문입니다.
00:12:27예를 들어 리전 1에서는 CPU 클러스터 A가 90 RPS를 보내고, 인근 엔진 A는 100 RPS를 처리할 수 있습니다.
00:12:36따라서 이 경우에는 가장 가까운 곳으로만 전달해도 괜찮습니다.
00:12:40반면 리전 2에서는 CPU 클러스터 B가 120 RPS를 보내는데, 인근 엔진 B는 100 RPS만 처리할 수 있습니다.
00:12:49이 경우 모든 것을 로컬에서 처리하려고 고집하면, 초과된 20 RPS는 과부하 상태인
00:12:57엔진 B에서 대기해야 합니다. 한편 리전 3에서는 80 RPS 용량의 엔진 C에서 40 RPS만 사용하고 있습니다.
00:13:05여전히 40 RPS의 여유가 남아 있죠.
00:13:08따라서 클러스터 B의 초과 20 RPS를 엔진 C로 보내면 네트워크 거리는 늘어나지만,
00:13:16엔진 측에서 발생할 수 있는 훨씬 더 큰 대기 시간을 방지할 수 있습니다.
00:13:22따라서 이런 경우에는 더 먼 엔진을 이용하는 것이 엔드투엔드로 더 빠를 수 있습니다.
00:13:27이것이 바로 최단 거리 전송보다 더 나은 라우팅 방식이 필요한 이유입니다.
00:13:34이제 옵티마이저의 블랙박스를 열어보겠습니다.
00:13:39옵티마이저는 네 가지 유형의 입력을 받습니다.
00:13:44각 CPU 클러스터의 요청, 각 엔진까지의 네트워크 지연 시간,
00:13:50사용 가능한 엔진 용량 및 상태, 그리고 TTFT/TPOT 지연 시간 프로필입니다.
00:13:57이를 통해 부하가 증가함에 따라 엔진 측 지연 시간이 어떻게 변하는지 알 수 있습니다.
00:14:04그리고 이러한 입력을 받아 옵티마이저는 출력값인 라우팅 가중치로 변환합니다.
00:14:10라우팅 가중치는 각 CPU 클러스터의 트래픽 중 얼마만큼을 각 GPU 엔진으로 보낼지 나타냅니다.
00:14:19최적화 목표는 명확합니다.
00:14:22모든 라우팅 트래픽 전체의 예상 엔드투엔드 지연 시간을 최소화하는 것입니다.
00:14:28중요한 점은 엔드투엔드 지연 시간에 네트워크 거리와 엔진 측 지연 시간이 모두 포함된다는 것입니다.
00:14:36즉, 인근 엔진이 트래픽을 처리할 여유가 있을 때는 매력적인 선택지이지만,
00:14:43인근 엔진이 모두 포화에 가까워지면 먼 엔진으로 보내는 것이 더 나을 수 있습니다.
00:14:50또한 옵티마이저는 몇 가지 엄격한 제약 조건을 준수해야 합니다.
00:14:56첫째, 모든 트래픽 수요를 라우팅해야 합니다.
00:14:59둘째, 모든 엔진이 유효 용량 범위 내에서 유지되도록 해야 합니다.
00:15:05셋째, 라우팅 가중치를 0 이상으로 유지해야 합니다.
00:15:09이를 통해 제어 플레인은 옵티마이저로부터 라우팅 가중치를 받아 게시합니다.
00:15:17그리고 데이터 플레인은 이를 가져와 전역 최적화된 라우팅 결정을 내리는 데 사용합니다.
00:15:24제 발표 내용은 여기까지입니다.
00:15:26이어서 루 님이 시스템의 보호 메커니즘에 대해 설명해 드리겠습니다.
00:15:33감사합니다, 천루 님.
00:15:34AI 엔지니어로서 우리 모두 알고 있듯이, 프로덕션 환경이 이상적으로만 동작하는 경우는 많지 않습니다.
00:15:45클러스터에 장애가 발생하거나, GPU나 개별 노드의 성능이 저하되거나, 네트워크에 온갖 알 수 없는 문제가 생길 수 있죠.
00:15:55그렇다면 과부하 상태에서도 프로덕션 시스템을 최대한 정상적으로 유지하려면 어떻게 해야 할까요?
00:16:02우리가 사용하는 첫 번째 장치는 페널티입니다.
00:16:05기본적으로 특정 엔진에 이상이 감지되면, 이를 감지하여 해당 엔진으로 향하는 라우팅 가중치를 줄입니다.
00:16:13그렇게 하면 일시적인 문제일 경우 엔진 스스로 회복할 기회를 줄 수 있고,
00:16:22작업자가 개입하여 교체하거나 결함이 있는 하드웨어를 수리할 수도 있습니다.
00:16:28두 번째는 재시도 메커니즘으로, 문제를 완화하는 데 흔히 쓰이는 기술입니다.
00:16:34하지만 때에 따라서는 상황을 오히려 악화시킬 수도 있습니다.
00:16:39시스템이 마비 직전이거나 사용률이 매우 높은 경우가 그렇습니다.
00:16:45재시도는 더 많은 부하를 만들어냅니다.
00:16:47그리고 이 늘어난 부하는 더 많은 실패와 재시도를 불러오며 악명 높은 재시도 폭풍을 일으키죠.
00:16:52그래서 저희는 상한선이나 버짓을 구현하여 재시도를 허용 가능한 수준으로 제한했습니다.
00:17:00또한 이는 동적으로 작동해야 하는데, 시스템이 원활하거나 정상적인 상태일 때는
00:17:07부하가 높을 때보다 훨씬 더 많은 재시도를 감내할 수 있기 때문입니다.
00:17:12마지막으로 부하 차단(Load Shedding)이 있는데, 이는 프로덕션 용량이
00:17:20증가하는 추론 요청량을 감당할 수 없을 때 사용하는 최선의 수단입니다.
00:17:24전체 시스템을 다운시키는 대신,
00:17:27트래픽의 일부를 선제적으로 차단하여 시스템이 완만하게 성능을 낮추며 유지되도록 합니다.
00:17:35이것으로 오늘 발표를 마치겠습니다.
00:17:38참석해 주셔서 감사합니다.
00:17:40저희 둘 다 오늘 오후에 부스 쪽에 있을 예정입니다.
00:17:45추가 질문이 있으시면 언제든 오셔서 이야기 나누어 주시기 바랍니다.
00:17:50감사합니다.
00:17:51감사합니다.

핵심 요약

OpenAI는 과부하 시 KV 캐시 효율을 저해하던 초기 피드백 루프 라우팅의 한계를 극복하기 위해, 비동기 제어 평면에서 네트워크 거리와 엔진 지연 시간을 통합 최적화하는 글로벌 라우팅 정책 아키텍처로 전환했다.

하이라이트

  • 추론 로드 밸런서(IRB)는 CPU 기반 프론트엔드 클러스터와 GPU 기반 엔진 클러스터 사이에서 엔진 선택과 요청 근사화를 수행한다.

  • 초기 피드백 루프 기반 비례 제어(PID) 방식은 시스템 유연성은 높았으나 신호 중복으로 인해 가중치 변동 원인 파악이 어렵고 가중치가 요동쳐 KV 캐시 활용을 방해했다.

  • 새로 도입한 아키텍처는 비동기 제어 평면이 전역 최적화 가중치를 계산하고, 데이터 평면이 이를 로컬 상태로 즉시 조회하여 동기 대기 시간을 없앤다.

  • 네트워크 거리가 멀더라도 대기 시간이 짧은 GPU 엔진으로 트래픽을 우회 라우팅하는 것이 엔드투엔드 지연 시간을 줄이는 데 유리하다.

  • 과부하 및 장애 상황에 대응하기 위해 엔진 가중치 감소 페널티, 동적 상한선 기반 재시도 버짓, 선제적 트래픽 차단(Load Shedding) 메커니즘을 적용한다.

타임라인

추론 로드 밸런서의 역할과 초기 피드백 루프 라우팅의 한계

  • 추론 로드 밸런서는 CPU 프론트엔드와 GPU 엔진 클러스터 사이에서 엔진 선택을 담당한다.
  • 초기에는 엔진 신호를 통합한 비례 제어 피드백 루프로 가중치를 동적 조정했다.
  • 피드백 루프 방식은 트래픽 진동을 유발하여 KV 캐시 활용을 저해하는 치명적인 단점이 존재했다.

추론 로드 밸런서(IRB)는 사용자 요청을 처리 가능한 형태로 전환하는 CPU 게이트웨이와 실제 모델을 실행하는 GPU 클러스터 사이에 위치한다. 초기 라우팅은 TTFT, TBT, 부하율, KV 캐시 상태 등을 수집한 후 PID 제어 방식의 비례 제어를 통해 엔진 가중치를 수동 개입 없이 자동 조정하는 방식이었다. 그러나 복잡한 신호 혼합으로 인해 특정 가중치 산출 원인을 추적하기 어렵고, 트래픽 이동 시 부하 변동에 따라 가중치가 요동치는 진동 현상이 발생하여 KV 캐시 재사용성이 크게 떨어졌다.

제어 평면과 데이터 평면 분리 아키텍처

  • 라운드 로빈이나 로컬 관점 라우팅은 하드웨어 편차와 과부하 문제를 해결하지 못한다.
  • 비동기 제어 평면이 전역 라우팅 가중치 스냅샷을 지속적으로 계산하여 배포한다.
  • 데이터 평면은 로컬 캐시된 라우팅 가중치를 사용하여 동기식 블로킹 없이 요청을 전달한다.

단순 라운드 로빈은 엔진 간 성능 차이나 위치, KV 캐시 지역성을 반영하지 못하며, 각 CPU 클러스터가 로컬 관점으로만 선택하면 특정 GPU 엔진에 과부하가 집중될 위험이 있다. 이를 해결하기 위해 전체 CPU 및 GPU 상태를 조망하는 제어 평면과 요청을 즉각 전달하는 데이터 평면을 분리했다. 제어 평면은 오프라인 회귀 분석과 실시간 신호를 결합해 최적의 라우팅 가중치를 비동기식으로 산출하며, 데이터 평면은 이 가중치를 로컬 캐시에서 즉시 읽어 라우팅을 수행함으로써 요청 대기 시간을 최소화한다.

엔드투엔드 지연 시간 최소화를 위한 옵티마이저 라우팅

  • 지리적 최단 거리 전송이 항상 가장 빠른 응답 시간을 보장하지 않는다.
  • 옵티마이저는 네트워크 지연과 엔진 측 대기 시간을 합산하여 전체 엔드투엔드 지연 시간을 최소화한다.
  • 수요 완전 라우팅 및 유효 용량 준수 등 엄격한 제약 조건을 하에서 가중치가 결정된다.

트래픽 수요와 GPU 컴퓨팅 용량은 지역적으로 불균형을 이룬다. 인근 GPU 엔진이 포화 상태일 때 요청을 가까운 곳에 고집하면 엔진 대기 시간이 급증하므로, 물리적 거리가 멀더라도 여유가 있는 다른 지역의 GPU 엔진으로 보낼 때 엔드투엔드 처리 속도가 더 빨라진다. 옵티마이저는 CPU 클러스터 수요, 네트워크 RTT, 엔진 용량, TTFT 및 TPOT 지연 시간 프로필을 입력받아 모든 요청의 전체 지연 시간을 최소화하는 라우팅 가중치를 수학적으로 계산한다.

프로덕션 환경을 위한 안정성 보호 메커니즘

  • 이상 엔진의 라우팅 가중치를 즉시 낮추는 페널티 제도를 운영한다.
  • 재시도 폭풍을 방지하기 위해 시스템 부하에 따라 동적으로 상한선을 조정하는 재시도 버짓을 적용한다.
  • 용량 초과 시 선제적으로 트래픽 일부를 차단하는 부하 차단(Load Shedding)으로 전면 장애를 막는다.

GPU 장애나 네트워크 이상 등 실제 프로덕션의 불확실성에 대비해 다중 보호 장치를 배치한다. 성능 저하가 감지된 엔진에는 라우팅 페널티를 부여해 트래픽을 줄임으로써 복구 시간을 벌어준다. 또한 장애 발생 시 재시도로 인해 부하가 폭증하는 '재시도 폭풍'을 막고자 전체 시스템 상태에 따라 가변적으로 작동하는 재시도 제한(Budget)을 둔다. 시스템 전체가 감당 가능한 한계를 넘어서는 초과 부하가 발생할 경우, 일부 트래픽을 선제적으로 차단하는 부하 차단을 실행해 전체 시스템이 마비되지 않고 안정적으로 작동하도록 유지한다.

커뮤니티 글

아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!

이 영상에 대해 글쓰기