Company
Indexing 3.0 설계 비하인드: 통합, 패키징, 실행, 그리고 배포

스튜 스튜어트 (Stu Stewart), 조아브라함 (Abraham Jo), 김성중 (SJ Kim), 패리토시 모한 (Paritosh Mohan)
Twelve Labs는 서비스 경계를 통합하여 확장성을 개선한 이유, 단일 컨테이너 패키징이 다양한 배포 환경에서 지원하는 기능, 통합 실행 레이어로서 Ray Serve를 채택할 때 발생하는 실제 비용, 그리고 시스템이 별도의 코드베이스로 파편화되지 않으면서 여러 배포 대상을 지원하는 기법 등 Indexing 3.0 설계 과정에서의 구체적인 결정 사항들을 자세히 공유합니다.
Twelve Labs는 서비스 경계를 통합하여 확장성을 개선한 이유, 단일 컨테이너 패키징이 다양한 배포 환경에서 지원하는 기능, 통합 실행 레이어로서 Ray Serve를 채택할 때 발생하는 실제 비용, 그리고 시스템이 별도의 코드베이스로 파편화되지 않으면서 여러 배포 대상을 지원하는 기법 등 Indexing 3.0 설계 과정에서의 구체적인 결정 사항들을 자세히 공유합니다.

목차
뉴스레터 구독하기
뉴스레터 구독하기
영상 이해 분야의 최신 기술 업데이트, 튜토리얼 및 인사이트를 받아보세요.
영상 이해 분야의 최신 기술 업데이트, 튜토리얼 및 인사이트를 받아보세요.
AI로 영상을 검색하고, 분석하고, 탐색하세요.
2026. 3. 25.
13분
링크 복사하기
파트 1에서는 이전의 인덱싱 플랫폼이 "작동"했음에도 불구하고 왜 스케일링 한계에 부딪혔는지 보여주었습니다. 제한 요인은 원시 모델 처리량이 아니라, 애플리케이션에 인프라 가정이 내장된 마이크로서비스 중심 시스템의 운영 및 조직적 오버헤드였습니다. 팀과 제품 영역이 성장함에 따라 조정 비용, 서비스 간 디버깅, 배포 결합이 일상적인 엔지니어링 속도를 지배하기 시작했습니다. 핵심적인 재구성은 인덱싱을 일관되고 이식 가능한 시스템으로 취급하는 것이었습니다. 즉, 마이크로서비스 메시에서 애플리케이션 로직은 가독성을 유지하고, 실행 레이어는 분산을 처리하며, 인프라는 정의적인 존재가 아니라 교체 가능한 레이어가 되는 간소화된 레이어로 이동하는 것이었습니다. 이러한 레이어화된 관점은 컨트롤 플레인 상호 작용에서 동작을 다시 유도할 필요 없이, 비디오 → 재사용 가능한 표현 → 다운스트림 검색/생성에 이르는 엔드투엔드 경로를 보다 쉽게 논리적으로 파악할 수 있게 해줍니다.
파트 2에서는 이러한 재구성을 실현한 구체적인 설계 선택을 파헤쳐 보겠습니다. 통합이 확장성을 줄이는 대신 어떻게 확장성을 향상시켰는지, 패키징 제약 조건으로서 "단일 컨테이너"가 의미하는 바는 무엇인지, 통합 실행 레이어에 베팅할 때 얻는 것과 치르는 대가는 무엇인지, 그리고 플랫폼을 파편화하지 않고 여러 배포 환경을 지원하도록 설계한 방법에 대해 설명합니다.
1 - 이데올로기가 아닌 동력으로서의 통합

그림 1: 경계가 줄어들수록 더 빨라지는 추론
우리는 파트 1에서 Indexing 2.0의 실제 비용이 "컴퓨팅의 부족"이 아니라고 주장했습니다. 그것은 경계의 축적이었습니다. 모든 단계가 그 자체로 추론해야 할 서비스 계약, 배포 아티팩트, 실패 모드로 변했습니다. 각 단계가 별도의 서비스 경계가 되자, 시스템은 디버깅하기 더 어려워지고, 패키징하기 더 어려워졌으며, 발전시키기 더 용이하지 않게 되었습니다.
Indexing 3.0은 경계 표면적을 줄이기 위한 레버로 통합을 사용합니다. 이는 "그저 모놀리스를 지향하는 것"이 아닙니다. 핵심은 중요한 부분에서 시스템 유연성을 유지하되, 진정한 독립성을 보장하지 못하는 곳에서 조정 오버헤드를 지불하지 않는 것입니다.
더 적은 경계가 유연성을 제한하지 않고 오히려 향상시킨 이유
프로덕션 ML 시스템에서의 유연성은 가장 많은 박스를 갖는 데서 오지 않습니다. 플릿의 절반을 동기화하지 않고도 동작을 변경할 수 있는 능력에서 나옵니다.
통합은 다음과 같은 방식으로 도움이 되었습니다:
변경 시 안정적으로 유지되어야 하는 서비스 간 데이터 계약의 수를 줄입니다.
런타임, 트레이싱 시스템 및 배포 파이프라인 간의 변환만을 위해 존재하는 "글루 코드(glue code)"를 제거합니다.
엔드투엔드 인덱싱 경로를 하나의 일관된 흐름으로 더 쉽게 이해할 수 있도록 만듭니다.
개발자 경험의 배율기 역할을 하는 통합
우리는 파트 1에서 언어 및 런타임 경계(일부 배관에는 Go 개발, ML 워크플로우에는 Python 사용)가 인터페이스의 깔끔하지 못함으로 인해 마찰을 유발했음을 지적했습니다.
통합은 이러한 마찰을 은퇴시키는 방법입니다.
실무적으로 이는 다음을 개선합니다:
디버깅: 에러가 직렬화되고, 래핑되고, 재시도되면서 컨텍스트를 잃을 수 있는 지점이 줄어듭니다.
프로파일링: 서비스 전반에 걸쳐 로그를 짜 맞추지 않고도 여러 단계에 걸친 지연 시간과 리소스 리용률을 더 쉽게 추적할 수 있습니다.
온보딩: 엔지니어가 하나의 코드 경로를 따라가며 멘탈 모델을 더 빠르게 구축할 수 있습니다.
의도적으로 좁힌 영역 표면
통합은 시스템의 목적이 명확하게 제한되어 있을 때만 작동합니다. 인덱싱은 변환 레이어로서 비디오를 입력받아 재사용 가능한 표현으로 출력합니다. 이 범위를 명확히 유지하면 코드가 모든 것을 담는 잡동사니가 되지 않으면서도 수반되는 우발적인 복잡성을 낮출 수 있습니다.
2 - 패키징의 재고: "단일 컨테이너"가 실제로 의미하는 바

그림 2: 환경 전반에서 독립적인 단위로 실행
파트 1에서 주장한 바와 같이, 배포 유연성은 있으면 좋은 것이 아니라 최우선적인 제약 조건으로 드러났습니다. 어떤 환경은 "전체 플랫폼"처럼 보이고, 다른 환경은 "컨테이너 런타임과 몇 개의 노브"처럼 보입니다. Indexing 3.0은 이 전체 스펙트럼에서 실행되어야 했습니다.
"단일 컨테이너"는 이 제약 조건을 요약한 패키징 표현입니다.
"단일 컨테이너"는 압축이 아니라 디커플링에 관한 것입니다
목표는 모든 컴포넌트를 하나의 거대한 프레임워크 이미지에 쑤셔 넣는 것이 아닙니다. 목표는 인프라에 구애받는 컨트롤 플레인 프리미티브에 의존하지 않고 인덱싱 시스템을 실행 가능하게 만드는 것입니다.
실질적인 정의는 다음과 같습니다:
시스템이 독립적인 단위로 배포될 수 있습니다.
핵심 오케스트레이션을 수행하기 위해 Kubernetes API(또는 이와 유사한 것)를 별도로 요구하지 않습니다.
아키텍처의 포크(fork) 없이 최소한의 환경에서도 실행할 수 있습니다.
이것은 배포가 애플리케이션 로직으로 새어 나가는 제약 조건이 아니라 가장 아래 레이어의 속성이 되도록 하는 우리의 핵심 프레임과 일치합니다.
앱 레이어 내부로 오케스트레이션 이동
마이크로서비스 메시에서 오케스트레이션은 대개 애플리케이션 외부에 존재하며, 라우팅, 컨트롤러 및 플랫폼 동작 전반에 걸쳐 분산되어 있습니다.
파트 1의 레이어화된 모델에서는 오케스트레이션이 안쪽으로 이동합니다:
인덱싱 애플리케이션은 "무엇이 실행되어야 하는지" 정의합니다.
실행 레이어는 이를 실행하고 스케일링을 관리합니다.
인프라는 기저의 물리적인 기질 역할을 합니다.
이러한 도치가 이식성을 가능하게 만드는 원동력입니다. 시스템이 더 이상 단일 운영 환경에 종속되지 않기 때문입니다.
이것이 처음 생각했던 것보다 훨씬 더 중요했던 이유
패키징은 단지 어디서 실행할 수 있는지에만 영향을 미치는 것이 아니라 다음에도 영향을 미칩니다:
로컬 개발이 얼마나 단순한지.
여러 환경 전반에서 동작이 얼마나 일관적인지.
새로운 배포 방식이 얼마나 많은 운영 리소스를 그대로 상속받는지.
패키징이 더 단순해지면, 롤아웃, 디버깅, 지원, 온보딩에 이르는 다운스트림의 모든 과정 역시 단순해집니다.
3 - 단일화된 실행 레이어 선택: 약속 대 현실

그림 3: 라우팅, 스케일링, 안정성을 위한 단일 기질
파트 1에서는 Indexing 3.0을 마이크로서비스 메시에서 간소화된 레이어로의 전환으로 프레이밍했습니다. 여기서는 애플리케이션 로직이 일관되게 유지되고, 실행 레이어가 배포를 처리하며, 인프라 레이어는 교체 가능한 존재인 구조입니다.
이 섹션은 그 이야기의 다소 민감할 수 있는 현실적인 과정입니다: 즉, "우리의 인덱싱 로직"과 "고객이 제공한 컴퓨터 자원" 사이에 위치할 실행 레이어를 선택한다는 것이 실제로 무엇을 유의하는지 설명합니다. 우리는 그 단일 레이어로 Ray Serve(Ray Core 및 Ray Serve의 호스팅 프로바이더로 Anyscale 협력)를 선택했습니다. 이 결정은 확실한 레버리지를 제공했으나, 정면으로 마주해야 했던 몇 가지 대가 역시 치러야 했습니다.
단 하나의 추상화가 주는 약속
단일화된 실행 레이어의 핵심 약속은 매우 간단합니다: 늘어나는 서비스 군대 전반에 걸쳐 동시성, 스케일링, 결함 처리 메커니즘을 매번 재구축하는 대신, 단 한 곳에서 이를 쉽게 표현할 수 있도록 구조를 통일해 주는 것입니다.
Ray Serve의 서빙 모델은 이 약속을 구체화합니다:
요청은 HTTP(또는 gRPC) 프록시를 통해 유입되고 큐에 적재된 뒤 가용한 복제본(replica)으로 라우팅되어, 유저 코드를 실행하는 복제본 액터(Actor)에 의해 처리됩니다.
Serve는 단일 인그레스 포인트뿐만 아니라 스케일링 및 고가용성을 위해 다중 프록시를 지원합니다.
모델 구성을 위해 서비스가
DeploymentHandles를 통해 서로를 호출할 때도 동일한 요청 경로가 적용되므로, 내부 구성이 라우팅 및 배칭 동작을 공유할 수 있습니다.
인덱싱 플랫폼을 구축할 때 이 점은 상당한 매력으로 다가옵니다. 인덱싱은 단순한 하나의 모델 호출이 아니라 다단계 흐름이며, 세부적인 각 단계마다 동시성 제어와 실패 처리가 필요하기 때문입니다. 단일화된 실행 레이어는 "수많은 임시 스케줄러를 임시방편으로 엮어 만든 시스템"과 "표준화할 수 있는 강력한 단일 스케줄링 기질을 갖춘 시스템"의 차이를 만듭니다.
이것은 파트 1에서 다룬 패키징 및 배포 동인과도 긴밀하게 정렬됩니다. 오케스트레이션 로직이 Kubernetes 컨트롤러나 마이크로서비스 간 접착 코드에 흩어지지 않고 실행 레이어 안쪽에 위치한다면, 아키텍처를 새로 쓰지 않고도 서로 다른 환경에서 원활하게 작동하는 이식성 높은 시스템에 더욱 가깝게 확장할 수 있습니다.
인덱싱 워크로드의 현실
과소평가하기 쉬운 부분은 실행 레이어가 마냥 공짜가 아니라는 점입니다. 프레임워크 자체의 요청 경로, 컨트롤 플레인, 그리고 동작 성능 특징이 추가로 발생합니다. Ray Serve 공식 문서 역시 요청 경로에서의 높은 지연 시간과 낮은 처리량이 가장 흔히 발생하는 문제라고 언급하며, 면밀히 검토해야 할 라우터 및 처리 시간 성능 지표를 명시하고 있습니다.
비디오 인덱싱 환경에 있어 이 점은 매우 치명적인데, 워크로드의 형태가 종종 이 프레임워크 자체의 오버헤드를 배로 키우기 때문입니다.
현실 #1: 요청 라우팅 오버헤드는 실재하며, 때로는 뼈아픕니다
Ray Serve 아키텍처는 요청을 프록시를 통해 라우팅하고, 큐에 대기시킨 뒤 가용한 복제본을 선택해 실행합니다. 범용 서빙을 위해서는 타당한 기본 설계이지만, 이는 실제 작성한 코드가 실행되기도 전에 프레임워크에 의한 자체적인 연산 작업이 개입됨을 뜻합니다.
만약 애플리케이션의 단계 사이에 무수히 많은 짧은 전송 홉("small hops")이 존재한다면, 이러한 라우팅 오버헤드가 전체 엔드투엔드 지연 시간 중 무시할 수 없는 비중을 차지하게 됩니다. 추상화가 시스템을 조립하는 데는 유용하지만 동시에 조립 작업 자체에 필요한 비용도 예산에 반영해야 함을 상기시켜 줍니다.
이것은 단순한 가설이 아닙니다. Ray의 성능 튜닝 가이드에서도 요청 경로의 병목 진단을 상세히 논의하며, 라우터 처리량 및 큐 대기 지연 시간을 경고 신호로 지목합니다. 또한 Ray 생태계는 지연 요구량이 까다로운 서빙 제품군을 위해 맞춤형 custom 라우팅 공식 지원 기능을 추가하는 등 가용 경로 개선에 지속적인 투자를 이어가고 있습니다.
인덱싱 관점에서의 실질적인 교훈은 다음과 같습니다: 프레임워크의 오버헤드 또한 시스템의 한 부분이라는 점입니다. 특히 전체 수행 시간 중 오버헤드 비율이 치솟을 수밖에 없는 다수의 짧은 태스크들이 워크로드에 섞여 있을 때, 이를 명확히 측정하고 프로파일링하며 우회해서 설계해야 합니다. 실제로 이와 같은 "짧은 비디오 셋업 비용 페널티"는 파트 1에서 설명했던 한계 돌파 지점이기도 했습니다.
현실 #2: 비디오 디코딩은 핵심이며, 대개 CPU 병목을 유발합니다
비디오 인덱싱을 단지 "GPU 추론과 약간의 주변 연산" 정도로 가볍게 보기는 쉽습니다. 하지만 프로덕션 환경의 디코딩은 전체 파이프라인에서 가장 결과론적인 영향을 미치는 영역 중 하나이며, 코덱 종류, 포멧 구성, 하드웨어 디코딩 가용 여부에 따라 예외 없이 높은 CPU 자원을 소모합니다.
NVIDIA의 NVDEC 공식 문서 역시 디코딩을 NVDEC로 넘겼을 때 비로소 다른 태스크를 실행하기 위한 CPU 자원이 안전하게 확보된다는 점을 분명히 합니다. 즉, 하드웨어 오프로딩이 없는 기본 디코딩 경로는 많은 연산 비용을 요구한다는 의미입니다.
심지어 최신 PyTorch 생태계 진영에서도 CUDA 디코딩을 더 빠른 최적 가속 경로로 제안하지만, 치명적인 함정이 존재합니다: 코덱 규격이나 비디오 포맷이 탑재된 하드웨어 디코더에 공식 매칭되지 않는 경우, 조용히 기존의 가벼운 소프트웨어 CPU 디코딩 방식으로 강제 폴백(fallback)될 수 있습니다.
인덱싱 플랫폼 입장에서 CPU 가용성은 있으면 좋은 보조 리소스가 아닙니다. 겉보기에는 "GPU 모델 작동"이 핵심인 것처럼 보여도, 최선두에서 실시간 병목을 일으킬 수 있는 주요 요인이기 때문입니다. 심지어 CPU 디코딩 능력이 한계까지 포화되어 정작 비싼 GPU가 할 일 없이 대기하는 최악의 사용률 참사가 발생하기도 합니다. "이종 리소스 프로파일(heterogeneous resource profiles)"이 추상적인 논점에 머무르지 않고, 디코딩 연산 단 하나만으로도 CPU를 1등급 리소스 스케줄링 차원으로 엄격히 다루어야 하는 강력한 이유입니다.
현실 #3: 다양한 리소스 특성을 지닌 단계들은 명시적인 리소스 모델링을 요구합니다
인덱싱 워크로드는 본질적으로 서로 다른 성격의 하드웨어 리소스를 사용합니다:
다운로드 및 I/O 중심 구간
CPU 점유가 지배적인 디코딩 구간
GPU 점유가 지배적인 임베딩 추출 구간
CPU 및 메모리 부하가 심하게 스윙하는 후처리 구간
단일화된 실행 레이어는 우리가 이러한 필요 사양을 물리적으로 명시해 주어야 비로소 의미 있게 작동합니다. Ray Core는 태스크 및 액터에 필요한 CPU, GPU 등의 논리적 리소스 요구 사항 지정을 공식 지원하며, 오직 해당 조건이 안전하게 확보된 하이브리드 노드 환경에만 스케줄링되도록 조정합니다. 한 태스크가 다른 태스크의 리소스를 방해하거나 병목 단계 앞단에 동시 실행이 걸려 병목이 폭증하는 비극적인 실패 시나리오를 방지하려면 이 성능은 필수 불가결합니다.
이것이 바로 파트 1의 "간소화된 레이어" 재구성 설계가 운영 현장에서 살아 숨 쉬는 모습입니다. 단순히 코드만 조각내는 것이 아니라, 컴퓨팅 자원의 의미론(resource semantics)을 논리적으로 통일하는 작업입니다: 인덱싱 플랫폼은 파이프라인 흐름을 기술하고, 실행 레이어는 동시성과 물리적 배치를 제어하며, 인프라 레이어는 온전한 기하학적 리소스만을 묵묵히 공급합니다.
얻은 교훈: 추상화는 엔지니어링 리소스를 파괴하는 것이 아니라 재배치할 뿐입니다
훌륭한 실행 레이어를 도입하더라도 전체 엔지니어링 투여량이 마법처럼 제로가 되지는 않습니다. 대신 일하는 위치가 한 단계 격상됩니다. 자체 오케스트레이션 코드를 매번 밑바닥부터 짜는 수고를 덜어내는 대신, 요청 처리 경로의 온전한 파악, 원격 계측(instrumentation) 및 성능 고도화 튜닝, 파이프라인 로직과 프레임워크 스케줄러 간의 특성 매칭 고도화에 인적 자원을 더욱 가치 있게 활용할 수 있게 됩니다.
동시에 겪었던 아주 솔직하고 값진 경험이 하나 더 있습니다: 개발 주기 극초반에 허리가 될 단일 통합 실행 레이어를 결정했다면, 해당 기술을 뒤에서 전력으로 개발 및 공급하는 핵심 플랫폼 전담 엔지니어 팀 또한 우리 내부 팀의 실질적인 연장선이라 믿고 밀접히 관계를 이어가야 합니다.
Ray Serve와 Anyscale 서비스는 우리에게 막강한 동력을 주었지만, 예측 불가능하고 무거운 비디오 워크로드를 극한까지 소화하면서 현실 필드의 다채로운 엣지 케이스들을 꽤 마주하기도 했습니다. 우리는 Anyscale 내 Ray Serve 핵심 개발팀과 적극적으로 원격 협력을 유지하면서 원인 모를 병목 현상을 규명하고, 그대로 똑같이 재현 가능한 코드로 협업 사례를 피드백하였으며, 패치 릴리즈 과정을 빈틈없이 단축했습니다. 초기 세팅의 시행착오는 고됐으나, 이러한 전사적 파트너 파이프라인 협업 구조 전반이 최종 승부에서 이 베팅을 영리하게 증명해 낼 수 있었던 아키텍처의 강력한 일부였습니다. 급변하는 서빙 코어 스택에서 기술 파트너십은 부차가 아니라 설계의 실질적 본질입니다.
4 - 중단 없는 다중 배포 환경 지원

그림 4: 하나의 개념적 플랫폼, 다양한 실행 환경
우리는 파트 1에서 다음과 같은 과감한 주장을 했습니다: 배포 형태는 시스템의 정의적 특징이 아니라 하나의 변수여야 한다. 이 섹션은 이를 실제로 어떻게 조율하고 구체화했는지 다룹니다.
배포는 나중에 끼워 맞추는 과정이 아니라 주요 설계 방향성입니다
고객이 인덱싱 파이프라인 출력물에 본격적으로 의존하기 시작하면, 이미 구축된 배포 제약 조건을 뜯어고치는 작업은 막대한 비용을 요구하게 됩니다. 특정 환경의 단일 컨트롤 플레인에 시스템이 완전히 잠겨 버리는 순간, 새로운 온프레미스나 엣지 환경 대응 요구는 필연적으로 전체 재작성이나 파편 포크(fork)로 이어집니다.
Indexing 3.0은 개발 완료 후 도커 패키징 작업을 시작할 때가 아니라, 아키텍처 기초 설계 첫 줄을 그을 때부터 "이것이 향후 어디서 굴러갈 것인가"를 최우선 기능 요구 사양으로 상정했습니다.
파편화 없는 높은 소화력
여러 시스템 환경을 호환한다는 것은, 각 환경에 맞춰진 N개의 서로 다른 변종 플랫폼을 매번 눈물겹게 병렬 유지 보수한다는 소리가 아닙니다.
진정한 목적은 단 하나의 관념적 핵심 구조를 완전히 통일한 상태에서, 환경별 개별 성격들은 최대한 가장 바닥에 있는 물리 어댑터 레이어로 가볍게 밀어내는 것입니다. 파트 1에서 설명한 깔끔한 모듈식 레이어 아키텍처의 원리와 일맥상통합니다: 인프라가 어떻게 물리적으로 설계되어 있든, 최상위 애플리케이션 핵심 구동 로직은 요동 없이 고고하게 보존되어야 합니다.
실 구현 관점에서 이는 다음을 실천하는 것을 뜻합니다:
운영 환경이 어떻게 달라지든 인덱싱의 핵심 수행 동작은 완벽히 대칭되도록 일관성을 지키는 것.
특이 환경의 성격들은 가벼운 설정 파일 단위, 개별 실행 헬퍼 도구, 그리고 얇은 어댑터 단독 코드로 완벽히 매몰 격리시키는 것.
시간이 지나면서 결국 두터운 레거시 편차를 낳고 마는 "특정 고객 전용 예외 처리 분기 코드"를 극도로 경계하고 방지하는 것.
구동 인프라 환경의 다양성을 눈감았을 때 치르는 숨겨진 세금
눈앞의 배포 다양성을 외면하고 단순 편의를 좇는다면, 플랫폼은 결국 더 악성으로 파편화됩니다. 온갖 개별 환경 맞춤형 하드코딩 패치, 독점 임시 릴리즈, 특정 고객 환경 전용의 복잡한 운영 오케스트레이션 매뉴얼 등의 부채가 켜켜이 쌓이게 됩니다.
아키텍처 선행 단계에서 애초에 다중 구동 환경 유연성을 계산해 두는 설계 총합 비용이, 향후 이로 인해 무너지는 플랫폼 파편화 파멸 비용을 변제하는 것보다 압도적으로 저렴합니다. 이는 향후 비즈니스 가치가 달라지고 요구 인프라 정책이 크게 선회해도, 시스템 전체를 통째로 부수지 않고 지속 가능하게 진화 변형시켜 나가는 결정적 무기가 됩니다.
결론: 휴먼 리소스 제약을 푸는 인프라가 결국 모든 엔지니어링 한계를 풉니다
Indexing 3.0 프로젝트는 무조건 고비용의 극단적 성능 지표 도달을 목표로 시작되지 않았습니다. 수많은 고성장 ML 인프라 팀이 파국에 이르러 마주하는 가장 본질적인 질문에서 출발했습니다:
시스템은 어떻게든 돌아가고 있는데, 코드 전체 구조를 제대로 정확히 꿰뚫는 엔지니어는 단 몇 명뿐이고, 심지어 특정 클라우드 단 한곳에서만 아슬아슬하게 실행된다면 무슨 일이 발생할 것인가?
우리가 겪었던 정답은, 개발 및 개선 발전 복리 속도가 보이지 않는 곳에서 계속 거대하게 둔화된다는 점이었습니다. 사소한 기능 변경도 극도로 조심스러워지고, 고객 환경 신규 배포는 늘 깨지기 일쑤며, 신장 개발자의 온보딩은 마치 역사 유적을 발굴하는 가혹한 고고학 탐사 업무로 돌변합니다. 그리고 단지 개발 당시의 편의를 위해 마구 타협했던 임베디드 아키텍처 부채들은 조용히 단단하게 굳어 향후 플랫폼 전반을 옭아매는 질긴 족쇄가 됩니다.
이번 Indexing 3.0 설계 혁신이 증명해 낸 가장 가치 있는 이정표는, 특정 한두 개의 개별 고속화 기능 달성이 아닙니다; 미래 시스템 구조 전반이 가능하게 만드는 패러다임의 확실한 해방에 있습니다:
더 많은 새 엔지니어가 커뮤니케이션 및 코드 충돌 병목 없이 자신 있게 비즈니스 빌딩에 참여할 수 있게 됨
하나의 통합 코어 플랫폼 그대로 퍼블릭 클라우드, 온프레미스 프라이빗 망, 저사양 제한 하드웨어 기기 수준까지 완전히 동일하게 지배 운영함
더 이상 배포 환경 구동 성격이 최상위 소프트웨어 아키텍처의 설계 복잡성을 지배 역행하지 않음
구조 자체가 우아하고 투명하고 심플해졌기에, 비로소 세밀한 유닛 단위 인프라 비용 및 효율 최적화가 완연히 통제 범위 안으로 들어옴
이 값진 교훈은 비단 비디오 인덱싱 파이프라인 개발 조직뿐만 아니라, 모든 방면의 범용 플랫폼 엔지니어링 패권에도 분명히 투영될 것입니다.
현대 ML 인프라 생태계에서, 최종 성능 확장 가속 능력을 극단적으로 가로막는 병목은 단순히 무거운 인공지능 모델이나 고성능 엔비디아 GPU 하드웨어 부족 때문만은 아닙니다. 추론하고 논의하기 난해하도록 엉겨 붙어 설계된 시스템 자체, 초기 가정과 완전히 다른 미지의 이종 환경 적용에 단 1도 저항력을 갖추지 못한 나약한 구조, 그리고 신규 인력이 두려움 없이 기여할 수 없게 막는 굳어버린 플랫폼 아키텍처가 결국 발목을 잡습니다.
그런 맥락에서 일구어 낸 참된 간결함(Simplicity)은 기술적 야심이 부족하다는 뜻이 전혀 아닙니다. 이는 지엽적이고 국지적인 똑똑함의 과시를 희생하는 대신, 글로벌 스케일의 전사적 레버리지 가치로 치환받아 소출을 보장받겠다는 영리하고 치밀한 의도적 설계 철학입니다.
Indexing 3.0은 이러한 거대한 성장의 기틀을 우리의 시스템 근간 최하단에 확실히 다져 박는 위대한 장정이었습니다. 이제 우리의 미래 인프라 여정은 꼬여버린 배포 올가미를 멍청히 푸는 무의미한 삽질을 멈추고, 동영상 이해 지평이 약속하는 더 위대한 미래 지적 가치들에 온전하고 풍요롭게 집중할 것입니다.
파트 1에서는 이전의 인덱싱 플랫폼이 "작동"했음에도 불구하고 왜 스케일링 한계에 부딪혔는지 보여주었습니다. 제한 요인은 원시 모델 처리량이 아니라, 애플리케이션에 인프라 가정이 내장된 마이크로서비스 중심 시스템의 운영 및 조직적 오버헤드였습니다. 팀과 제품 영역이 성장함에 따라 조정 비용, 서비스 간 디버깅, 배포 결합이 일상적인 엔지니어링 속도를 지배하기 시작했습니다. 핵심적인 재구성은 인덱싱을 일관되고 이식 가능한 시스템으로 취급하는 것이었습니다. 즉, 마이크로서비스 메시에서 애플리케이션 로직은 가독성을 유지하고, 실행 레이어는 분산을 처리하며, 인프라는 정의적인 존재가 아니라 교체 가능한 레이어가 되는 간소화된 레이어로 이동하는 것이었습니다. 이러한 레이어화된 관점은 컨트롤 플레인 상호 작용에서 동작을 다시 유도할 필요 없이, 비디오 → 재사용 가능한 표현 → 다운스트림 검색/생성에 이르는 엔드투엔드 경로를 보다 쉽게 논리적으로 파악할 수 있게 해줍니다.
파트 2에서는 이러한 재구성을 실현한 구체적인 설계 선택을 파헤쳐 보겠습니다. 통합이 확장성을 줄이는 대신 어떻게 확장성을 향상시켰는지, 패키징 제약 조건으로서 "단일 컨테이너"가 의미하는 바는 무엇인지, 통합 실행 레이어에 베팅할 때 얻는 것과 치르는 대가는 무엇인지, 그리고 플랫폼을 파편화하지 않고 여러 배포 환경을 지원하도록 설계한 방법에 대해 설명합니다.
1 - 이데올로기가 아닌 동력으로서의 통합

그림 1: 경계가 줄어들수록 더 빨라지는 추론
우리는 파트 1에서 Indexing 2.0의 실제 비용이 "컴퓨팅의 부족"이 아니라고 주장했습니다. 그것은 경계의 축적이었습니다. 모든 단계가 그 자체로 추론해야 할 서비스 계약, 배포 아티팩트, 실패 모드로 변했습니다. 각 단계가 별도의 서비스 경계가 되자, 시스템은 디버깅하기 더 어려워지고, 패키징하기 더 어려워졌으며, 발전시키기 더 용이하지 않게 되었습니다.
Indexing 3.0은 경계 표면적을 줄이기 위한 레버로 통합을 사용합니다. 이는 "그저 모놀리스를 지향하는 것"이 아닙니다. 핵심은 중요한 부분에서 시스템 유연성을 유지하되, 진정한 독립성을 보장하지 못하는 곳에서 조정 오버헤드를 지불하지 않는 것입니다.
더 적은 경계가 유연성을 제한하지 않고 오히려 향상시킨 이유
프로덕션 ML 시스템에서의 유연성은 가장 많은 박스를 갖는 데서 오지 않습니다. 플릿의 절반을 동기화하지 않고도 동작을 변경할 수 있는 능력에서 나옵니다.
통합은 다음과 같은 방식으로 도움이 되었습니다:
변경 시 안정적으로 유지되어야 하는 서비스 간 데이터 계약의 수를 줄입니다.
런타임, 트레이싱 시스템 및 배포 파이프라인 간의 변환만을 위해 존재하는 "글루 코드(glue code)"를 제거합니다.
엔드투엔드 인덱싱 경로를 하나의 일관된 흐름으로 더 쉽게 이해할 수 있도록 만듭니다.
개발자 경험의 배율기 역할을 하는 통합
우리는 파트 1에서 언어 및 런타임 경계(일부 배관에는 Go 개발, ML 워크플로우에는 Python 사용)가 인터페이스의 깔끔하지 못함으로 인해 마찰을 유발했음을 지적했습니다.
통합은 이러한 마찰을 은퇴시키는 방법입니다.
실무적으로 이는 다음을 개선합니다:
디버깅: 에러가 직렬화되고, 래핑되고, 재시도되면서 컨텍스트를 잃을 수 있는 지점이 줄어듭니다.
프로파일링: 서비스 전반에 걸쳐 로그를 짜 맞추지 않고도 여러 단계에 걸친 지연 시간과 리소스 리용률을 더 쉽게 추적할 수 있습니다.
온보딩: 엔지니어가 하나의 코드 경로를 따라가며 멘탈 모델을 더 빠르게 구축할 수 있습니다.
의도적으로 좁힌 영역 표면
통합은 시스템의 목적이 명확하게 제한되어 있을 때만 작동합니다. 인덱싱은 변환 레이어로서 비디오를 입력받아 재사용 가능한 표현으로 출력합니다. 이 범위를 명확히 유지하면 코드가 모든 것을 담는 잡동사니가 되지 않으면서도 수반되는 우발적인 복잡성을 낮출 수 있습니다.
2 - 패키징의 재고: "단일 컨테이너"가 실제로 의미하는 바

그림 2: 환경 전반에서 독립적인 단위로 실행
파트 1에서 주장한 바와 같이, 배포 유연성은 있으면 좋은 것이 아니라 최우선적인 제약 조건으로 드러났습니다. 어떤 환경은 "전체 플랫폼"처럼 보이고, 다른 환경은 "컨테이너 런타임과 몇 개의 노브"처럼 보입니다. Indexing 3.0은 이 전체 스펙트럼에서 실행되어야 했습니다.
"단일 컨테이너"는 이 제약 조건을 요약한 패키징 표현입니다.
"단일 컨테이너"는 압축이 아니라 디커플링에 관한 것입니다
목표는 모든 컴포넌트를 하나의 거대한 프레임워크 이미지에 쑤셔 넣는 것이 아닙니다. 목표는 인프라에 구애받는 컨트롤 플레인 프리미티브에 의존하지 않고 인덱싱 시스템을 실행 가능하게 만드는 것입니다.
실질적인 정의는 다음과 같습니다:
시스템이 독립적인 단위로 배포될 수 있습니다.
핵심 오케스트레이션을 수행하기 위해 Kubernetes API(또는 이와 유사한 것)를 별도로 요구하지 않습니다.
아키텍처의 포크(fork) 없이 최소한의 환경에서도 실행할 수 있습니다.
이것은 배포가 애플리케이션 로직으로 새어 나가는 제약 조건이 아니라 가장 아래 레이어의 속성이 되도록 하는 우리의 핵심 프레임과 일치합니다.
앱 레이어 내부로 오케스트레이션 이동
마이크로서비스 메시에서 오케스트레이션은 대개 애플리케이션 외부에 존재하며, 라우팅, 컨트롤러 및 플랫폼 동작 전반에 걸쳐 분산되어 있습니다.
파트 1의 레이어화된 모델에서는 오케스트레이션이 안쪽으로 이동합니다:
인덱싱 애플리케이션은 "무엇이 실행되어야 하는지" 정의합니다.
실행 레이어는 이를 실행하고 스케일링을 관리합니다.
인프라는 기저의 물리적인 기질 역할을 합니다.
이러한 도치가 이식성을 가능하게 만드는 원동력입니다. 시스템이 더 이상 단일 운영 환경에 종속되지 않기 때문입니다.
이것이 처음 생각했던 것보다 훨씬 더 중요했던 이유
패키징은 단지 어디서 실행할 수 있는지에만 영향을 미치는 것이 아니라 다음에도 영향을 미칩니다:
로컬 개발이 얼마나 단순한지.
여러 환경 전반에서 동작이 얼마나 일관적인지.
새로운 배포 방식이 얼마나 많은 운영 리소스를 그대로 상속받는지.
패키징이 더 단순해지면, 롤아웃, 디버깅, 지원, 온보딩에 이르는 다운스트림의 모든 과정 역시 단순해집니다.
3 - 단일화된 실행 레이어 선택: 약속 대 현실

그림 3: 라우팅, 스케일링, 안정성을 위한 단일 기질
파트 1에서는 Indexing 3.0을 마이크로서비스 메시에서 간소화된 레이어로의 전환으로 프레이밍했습니다. 여기서는 애플리케이션 로직이 일관되게 유지되고, 실행 레이어가 배포를 처리하며, 인프라 레이어는 교체 가능한 존재인 구조입니다.
이 섹션은 그 이야기의 다소 민감할 수 있는 현실적인 과정입니다: 즉, "우리의 인덱싱 로직"과 "고객이 제공한 컴퓨터 자원" 사이에 위치할 실행 레이어를 선택한다는 것이 실제로 무엇을 유의하는지 설명합니다. 우리는 그 단일 레이어로 Ray Serve(Ray Core 및 Ray Serve의 호스팅 프로바이더로 Anyscale 협력)를 선택했습니다. 이 결정은 확실한 레버리지를 제공했으나, 정면으로 마주해야 했던 몇 가지 대가 역시 치러야 했습니다.
단 하나의 추상화가 주는 약속
단일화된 실행 레이어의 핵심 약속은 매우 간단합니다: 늘어나는 서비스 군대 전반에 걸쳐 동시성, 스케일링, 결함 처리 메커니즘을 매번 재구축하는 대신, 단 한 곳에서 이를 쉽게 표현할 수 있도록 구조를 통일해 주는 것입니다.
Ray Serve의 서빙 모델은 이 약속을 구체화합니다:
요청은 HTTP(또는 gRPC) 프록시를 통해 유입되고 큐에 적재된 뒤 가용한 복제본(replica)으로 라우팅되어, 유저 코드를 실행하는 복제본 액터(Actor)에 의해 처리됩니다.
Serve는 단일 인그레스 포인트뿐만 아니라 스케일링 및 고가용성을 위해 다중 프록시를 지원합니다.
모델 구성을 위해 서비스가
DeploymentHandles를 통해 서로를 호출할 때도 동일한 요청 경로가 적용되므로, 내부 구성이 라우팅 및 배칭 동작을 공유할 수 있습니다.
인덱싱 플랫폼을 구축할 때 이 점은 상당한 매력으로 다가옵니다. 인덱싱은 단순한 하나의 모델 호출이 아니라 다단계 흐름이며, 세부적인 각 단계마다 동시성 제어와 실패 처리가 필요하기 때문입니다. 단일화된 실행 레이어는 "수많은 임시 스케줄러를 임시방편으로 엮어 만든 시스템"과 "표준화할 수 있는 강력한 단일 스케줄링 기질을 갖춘 시스템"의 차이를 만듭니다.
이것은 파트 1에서 다룬 패키징 및 배포 동인과도 긴밀하게 정렬됩니다. 오케스트레이션 로직이 Kubernetes 컨트롤러나 마이크로서비스 간 접착 코드에 흩어지지 않고 실행 레이어 안쪽에 위치한다면, 아키텍처를 새로 쓰지 않고도 서로 다른 환경에서 원활하게 작동하는 이식성 높은 시스템에 더욱 가깝게 확장할 수 있습니다.
인덱싱 워크로드의 현실
과소평가하기 쉬운 부분은 실행 레이어가 마냥 공짜가 아니라는 점입니다. 프레임워크 자체의 요청 경로, 컨트롤 플레인, 그리고 동작 성능 특징이 추가로 발생합니다. Ray Serve 공식 문서 역시 요청 경로에서의 높은 지연 시간과 낮은 처리량이 가장 흔히 발생하는 문제라고 언급하며, 면밀히 검토해야 할 라우터 및 처리 시간 성능 지표를 명시하고 있습니다.
비디오 인덱싱 환경에 있어 이 점은 매우 치명적인데, 워크로드의 형태가 종종 이 프레임워크 자체의 오버헤드를 배로 키우기 때문입니다.
현실 #1: 요청 라우팅 오버헤드는 실재하며, 때로는 뼈아픕니다
Ray Serve 아키텍처는 요청을 프록시를 통해 라우팅하고, 큐에 대기시킨 뒤 가용한 복제본을 선택해 실행합니다. 범용 서빙을 위해서는 타당한 기본 설계이지만, 이는 실제 작성한 코드가 실행되기도 전에 프레임워크에 의한 자체적인 연산 작업이 개입됨을 뜻합니다.
만약 애플리케이션의 단계 사이에 무수히 많은 짧은 전송 홉("small hops")이 존재한다면, 이러한 라우팅 오버헤드가 전체 엔드투엔드 지연 시간 중 무시할 수 없는 비중을 차지하게 됩니다. 추상화가 시스템을 조립하는 데는 유용하지만 동시에 조립 작업 자체에 필요한 비용도 예산에 반영해야 함을 상기시켜 줍니다.
이것은 단순한 가설이 아닙니다. Ray의 성능 튜닝 가이드에서도 요청 경로의 병목 진단을 상세히 논의하며, 라우터 처리량 및 큐 대기 지연 시간을 경고 신호로 지목합니다. 또한 Ray 생태계는 지연 요구량이 까다로운 서빙 제품군을 위해 맞춤형 custom 라우팅 공식 지원 기능을 추가하는 등 가용 경로 개선에 지속적인 투자를 이어가고 있습니다.
인덱싱 관점에서의 실질적인 교훈은 다음과 같습니다: 프레임워크의 오버헤드 또한 시스템의 한 부분이라는 점입니다. 특히 전체 수행 시간 중 오버헤드 비율이 치솟을 수밖에 없는 다수의 짧은 태스크들이 워크로드에 섞여 있을 때, 이를 명확히 측정하고 프로파일링하며 우회해서 설계해야 합니다. 실제로 이와 같은 "짧은 비디오 셋업 비용 페널티"는 파트 1에서 설명했던 한계 돌파 지점이기도 했습니다.
현실 #2: 비디오 디코딩은 핵심이며, 대개 CPU 병목을 유발합니다
비디오 인덱싱을 단지 "GPU 추론과 약간의 주변 연산" 정도로 가볍게 보기는 쉽습니다. 하지만 프로덕션 환경의 디코딩은 전체 파이프라인에서 가장 결과론적인 영향을 미치는 영역 중 하나이며, 코덱 종류, 포멧 구성, 하드웨어 디코딩 가용 여부에 따라 예외 없이 높은 CPU 자원을 소모합니다.
NVIDIA의 NVDEC 공식 문서 역시 디코딩을 NVDEC로 넘겼을 때 비로소 다른 태스크를 실행하기 위한 CPU 자원이 안전하게 확보된다는 점을 분명히 합니다. 즉, 하드웨어 오프로딩이 없는 기본 디코딩 경로는 많은 연산 비용을 요구한다는 의미입니다.
심지어 최신 PyTorch 생태계 진영에서도 CUDA 디코딩을 더 빠른 최적 가속 경로로 제안하지만, 치명적인 함정이 존재합니다: 코덱 규격이나 비디오 포맷이 탑재된 하드웨어 디코더에 공식 매칭되지 않는 경우, 조용히 기존의 가벼운 소프트웨어 CPU 디코딩 방식으로 강제 폴백(fallback)될 수 있습니다.
인덱싱 플랫폼 입장에서 CPU 가용성은 있으면 좋은 보조 리소스가 아닙니다. 겉보기에는 "GPU 모델 작동"이 핵심인 것처럼 보여도, 최선두에서 실시간 병목을 일으킬 수 있는 주요 요인이기 때문입니다. 심지어 CPU 디코딩 능력이 한계까지 포화되어 정작 비싼 GPU가 할 일 없이 대기하는 최악의 사용률 참사가 발생하기도 합니다. "이종 리소스 프로파일(heterogeneous resource profiles)"이 추상적인 논점에 머무르지 않고, 디코딩 연산 단 하나만으로도 CPU를 1등급 리소스 스케줄링 차원으로 엄격히 다루어야 하는 강력한 이유입니다.
현실 #3: 다양한 리소스 특성을 지닌 단계들은 명시적인 리소스 모델링을 요구합니다
인덱싱 워크로드는 본질적으로 서로 다른 성격의 하드웨어 리소스를 사용합니다:
다운로드 및 I/O 중심 구간
CPU 점유가 지배적인 디코딩 구간
GPU 점유가 지배적인 임베딩 추출 구간
CPU 및 메모리 부하가 심하게 스윙하는 후처리 구간
단일화된 실행 레이어는 우리가 이러한 필요 사양을 물리적으로 명시해 주어야 비로소 의미 있게 작동합니다. Ray Core는 태스크 및 액터에 필요한 CPU, GPU 등의 논리적 리소스 요구 사항 지정을 공식 지원하며, 오직 해당 조건이 안전하게 확보된 하이브리드 노드 환경에만 스케줄링되도록 조정합니다. 한 태스크가 다른 태스크의 리소스를 방해하거나 병목 단계 앞단에 동시 실행이 걸려 병목이 폭증하는 비극적인 실패 시나리오를 방지하려면 이 성능은 필수 불가결합니다.
이것이 바로 파트 1의 "간소화된 레이어" 재구성 설계가 운영 현장에서 살아 숨 쉬는 모습입니다. 단순히 코드만 조각내는 것이 아니라, 컴퓨팅 자원의 의미론(resource semantics)을 논리적으로 통일하는 작업입니다: 인덱싱 플랫폼은 파이프라인 흐름을 기술하고, 실행 레이어는 동시성과 물리적 배치를 제어하며, 인프라 레이어는 온전한 기하학적 리소스만을 묵묵히 공급합니다.
얻은 교훈: 추상화는 엔지니어링 리소스를 파괴하는 것이 아니라 재배치할 뿐입니다
훌륭한 실행 레이어를 도입하더라도 전체 엔지니어링 투여량이 마법처럼 제로가 되지는 않습니다. 대신 일하는 위치가 한 단계 격상됩니다. 자체 오케스트레이션 코드를 매번 밑바닥부터 짜는 수고를 덜어내는 대신, 요청 처리 경로의 온전한 파악, 원격 계측(instrumentation) 및 성능 고도화 튜닝, 파이프라인 로직과 프레임워크 스케줄러 간의 특성 매칭 고도화에 인적 자원을 더욱 가치 있게 활용할 수 있게 됩니다.
동시에 겪었던 아주 솔직하고 값진 경험이 하나 더 있습니다: 개발 주기 극초반에 허리가 될 단일 통합 실행 레이어를 결정했다면, 해당 기술을 뒤에서 전력으로 개발 및 공급하는 핵심 플랫폼 전담 엔지니어 팀 또한 우리 내부 팀의 실질적인 연장선이라 믿고 밀접히 관계를 이어가야 합니다.
Ray Serve와 Anyscale 서비스는 우리에게 막강한 동력을 주었지만, 예측 불가능하고 무거운 비디오 워크로드를 극한까지 소화하면서 현실 필드의 다채로운 엣지 케이스들을 꽤 마주하기도 했습니다. 우리는 Anyscale 내 Ray Serve 핵심 개발팀과 적극적으로 원격 협력을 유지하면서 원인 모를 병목 현상을 규명하고, 그대로 똑같이 재현 가능한 코드로 협업 사례를 피드백하였으며, 패치 릴리즈 과정을 빈틈없이 단축했습니다. 초기 세팅의 시행착오는 고됐으나, 이러한 전사적 파트너 파이프라인 협업 구조 전반이 최종 승부에서 이 베팅을 영리하게 증명해 낼 수 있었던 아키텍처의 강력한 일부였습니다. 급변하는 서빙 코어 스택에서 기술 파트너십은 부차가 아니라 설계의 실질적 본질입니다.
4 - 중단 없는 다중 배포 환경 지원

그림 4: 하나의 개념적 플랫폼, 다양한 실행 환경
우리는 파트 1에서 다음과 같은 과감한 주장을 했습니다: 배포 형태는 시스템의 정의적 특징이 아니라 하나의 변수여야 한다. 이 섹션은 이를 실제로 어떻게 조율하고 구체화했는지 다룹니다.
배포는 나중에 끼워 맞추는 과정이 아니라 주요 설계 방향성입니다
고객이 인덱싱 파이프라인 출력물에 본격적으로 의존하기 시작하면, 이미 구축된 배포 제약 조건을 뜯어고치는 작업은 막대한 비용을 요구하게 됩니다. 특정 환경의 단일 컨트롤 플레인에 시스템이 완전히 잠겨 버리는 순간, 새로운 온프레미스나 엣지 환경 대응 요구는 필연적으로 전체 재작성이나 파편 포크(fork)로 이어집니다.
Indexing 3.0은 개발 완료 후 도커 패키징 작업을 시작할 때가 아니라, 아키텍처 기초 설계 첫 줄을 그을 때부터 "이것이 향후 어디서 굴러갈 것인가"를 최우선 기능 요구 사양으로 상정했습니다.
파편화 없는 높은 소화력
여러 시스템 환경을 호환한다는 것은, 각 환경에 맞춰진 N개의 서로 다른 변종 플랫폼을 매번 눈물겹게 병렬 유지 보수한다는 소리가 아닙니다.
진정한 목적은 단 하나의 관념적 핵심 구조를 완전히 통일한 상태에서, 환경별 개별 성격들은 최대한 가장 바닥에 있는 물리 어댑터 레이어로 가볍게 밀어내는 것입니다. 파트 1에서 설명한 깔끔한 모듈식 레이어 아키텍처의 원리와 일맥상통합니다: 인프라가 어떻게 물리적으로 설계되어 있든, 최상위 애플리케이션 핵심 구동 로직은 요동 없이 고고하게 보존되어야 합니다.
실 구현 관점에서 이는 다음을 실천하는 것을 뜻합니다:
운영 환경이 어떻게 달라지든 인덱싱의 핵심 수행 동작은 완벽히 대칭되도록 일관성을 지키는 것.
특이 환경의 성격들은 가벼운 설정 파일 단위, 개별 실행 헬퍼 도구, 그리고 얇은 어댑터 단독 코드로 완벽히 매몰 격리시키는 것.
시간이 지나면서 결국 두터운 레거시 편차를 낳고 마는 "특정 고객 전용 예외 처리 분기 코드"를 극도로 경계하고 방지하는 것.
구동 인프라 환경의 다양성을 눈감았을 때 치르는 숨겨진 세금
눈앞의 배포 다양성을 외면하고 단순 편의를 좇는다면, 플랫폼은 결국 더 악성으로 파편화됩니다. 온갖 개별 환경 맞춤형 하드코딩 패치, 독점 임시 릴리즈, 특정 고객 환경 전용의 복잡한 운영 오케스트레이션 매뉴얼 등의 부채가 켜켜이 쌓이게 됩니다.
아키텍처 선행 단계에서 애초에 다중 구동 환경 유연성을 계산해 두는 설계 총합 비용이, 향후 이로 인해 무너지는 플랫폼 파편화 파멸 비용을 변제하는 것보다 압도적으로 저렴합니다. 이는 향후 비즈니스 가치가 달라지고 요구 인프라 정책이 크게 선회해도, 시스템 전체를 통째로 부수지 않고 지속 가능하게 진화 변형시켜 나가는 결정적 무기가 됩니다.
결론: 휴먼 리소스 제약을 푸는 인프라가 결국 모든 엔지니어링 한계를 풉니다
Indexing 3.0 프로젝트는 무조건 고비용의 극단적 성능 지표 도달을 목표로 시작되지 않았습니다. 수많은 고성장 ML 인프라 팀이 파국에 이르러 마주하는 가장 본질적인 질문에서 출발했습니다:
시스템은 어떻게든 돌아가고 있는데, 코드 전체 구조를 제대로 정확히 꿰뚫는 엔지니어는 단 몇 명뿐이고, 심지어 특정 클라우드 단 한곳에서만 아슬아슬하게 실행된다면 무슨 일이 발생할 것인가?
우리가 겪었던 정답은, 개발 및 개선 발전 복리 속도가 보이지 않는 곳에서 계속 거대하게 둔화된다는 점이었습니다. 사소한 기능 변경도 극도로 조심스러워지고, 고객 환경 신규 배포는 늘 깨지기 일쑤며, 신장 개발자의 온보딩은 마치 역사 유적을 발굴하는 가혹한 고고학 탐사 업무로 돌변합니다. 그리고 단지 개발 당시의 편의를 위해 마구 타협했던 임베디드 아키텍처 부채들은 조용히 단단하게 굳어 향후 플랫폼 전반을 옭아매는 질긴 족쇄가 됩니다.
이번 Indexing 3.0 설계 혁신이 증명해 낸 가장 가치 있는 이정표는, 특정 한두 개의 개별 고속화 기능 달성이 아닙니다; 미래 시스템 구조 전반이 가능하게 만드는 패러다임의 확실한 해방에 있습니다:
더 많은 새 엔지니어가 커뮤니케이션 및 코드 충돌 병목 없이 자신 있게 비즈니스 빌딩에 참여할 수 있게 됨
하나의 통합 코어 플랫폼 그대로 퍼블릭 클라우드, 온프레미스 프라이빗 망, 저사양 제한 하드웨어 기기 수준까지 완전히 동일하게 지배 운영함
더 이상 배포 환경 구동 성격이 최상위 소프트웨어 아키텍처의 설계 복잡성을 지배 역행하지 않음
구조 자체가 우아하고 투명하고 심플해졌기에, 비로소 세밀한 유닛 단위 인프라 비용 및 효율 최적화가 완연히 통제 범위 안으로 들어옴
이 값진 교훈은 비단 비디오 인덱싱 파이프라인 개발 조직뿐만 아니라, 모든 방면의 범용 플랫폼 엔지니어링 패권에도 분명히 투영될 것입니다.
현대 ML 인프라 생태계에서, 최종 성능 확장 가속 능력을 극단적으로 가로막는 병목은 단순히 무거운 인공지능 모델이나 고성능 엔비디아 GPU 하드웨어 부족 때문만은 아닙니다. 추론하고 논의하기 난해하도록 엉겨 붙어 설계된 시스템 자체, 초기 가정과 완전히 다른 미지의 이종 환경 적용에 단 1도 저항력을 갖추지 못한 나약한 구조, 그리고 신규 인력이 두려움 없이 기여할 수 없게 막는 굳어버린 플랫폼 아키텍처가 결국 발목을 잡습니다.
그런 맥락에서 일구어 낸 참된 간결함(Simplicity)은 기술적 야심이 부족하다는 뜻이 전혀 아닙니다. 이는 지엽적이고 국지적인 똑똑함의 과시를 희생하는 대신, 글로벌 스케일의 전사적 레버리지 가치로 치환받아 소출을 보장받겠다는 영리하고 치밀한 의도적 설계 철학입니다.
Indexing 3.0은 이러한 거대한 성장의 기틀을 우리의 시스템 근간 최하단에 확실히 다져 박는 위대한 장정이었습니다. 이제 우리의 미래 인프라 여정은 꼬여버린 배포 올가미를 멍청히 푸는 무의미한 삽질을 멈추고, 동영상 이해 지평이 약속하는 더 위대한 미래 지적 가치들에 온전하고 풍요롭게 집중할 것입니다.
파트 1에서는 이전의 인덱싱 플랫폼이 "작동"했음에도 불구하고 왜 스케일링 한계에 부딪혔는지 보여주었습니다. 제한 요인은 원시 모델 처리량이 아니라, 애플리케이션에 인프라 가정이 내장된 마이크로서비스 중심 시스템의 운영 및 조직적 오버헤드였습니다. 팀과 제품 영역이 성장함에 따라 조정 비용, 서비스 간 디버깅, 배포 결합이 일상적인 엔지니어링 속도를 지배하기 시작했습니다. 핵심적인 재구성은 인덱싱을 일관되고 이식 가능한 시스템으로 취급하는 것이었습니다. 즉, 마이크로서비스 메시에서 애플리케이션 로직은 가독성을 유지하고, 실행 레이어는 분산을 처리하며, 인프라는 정의적인 존재가 아니라 교체 가능한 레이어가 되는 간소화된 레이어로 이동하는 것이었습니다. 이러한 레이어화된 관점은 컨트롤 플레인 상호 작용에서 동작을 다시 유도할 필요 없이, 비디오 → 재사용 가능한 표현 → 다운스트림 검색/생성에 이르는 엔드투엔드 경로를 보다 쉽게 논리적으로 파악할 수 있게 해줍니다.
파트 2에서는 이러한 재구성을 실현한 구체적인 설계 선택을 파헤쳐 보겠습니다. 통합이 확장성을 줄이는 대신 어떻게 확장성을 향상시켰는지, 패키징 제약 조건으로서 "단일 컨테이너"가 의미하는 바는 무엇인지, 통합 실행 레이어에 베팅할 때 얻는 것과 치르는 대가는 무엇인지, 그리고 플랫폼을 파편화하지 않고 여러 배포 환경을 지원하도록 설계한 방법에 대해 설명합니다.
1 - 이데올로기가 아닌 동력으로서의 통합

그림 1: 경계가 줄어들수록 더 빨라지는 추론
우리는 파트 1에서 Indexing 2.0의 실제 비용이 "컴퓨팅의 부족"이 아니라고 주장했습니다. 그것은 경계의 축적이었습니다. 모든 단계가 그 자체로 추론해야 할 서비스 계약, 배포 아티팩트, 실패 모드로 변했습니다. 각 단계가 별도의 서비스 경계가 되자, 시스템은 디버깅하기 더 어려워지고, 패키징하기 더 어려워졌으며, 발전시키기 더 용이하지 않게 되었습니다.
Indexing 3.0은 경계 표면적을 줄이기 위한 레버로 통합을 사용합니다. 이는 "그저 모놀리스를 지향하는 것"이 아닙니다. 핵심은 중요한 부분에서 시스템 유연성을 유지하되, 진정한 독립성을 보장하지 못하는 곳에서 조정 오버헤드를 지불하지 않는 것입니다.
더 적은 경계가 유연성을 제한하지 않고 오히려 향상시킨 이유
프로덕션 ML 시스템에서의 유연성은 가장 많은 박스를 갖는 데서 오지 않습니다. 플릿의 절반을 동기화하지 않고도 동작을 변경할 수 있는 능력에서 나옵니다.
통합은 다음과 같은 방식으로 도움이 되었습니다:
변경 시 안정적으로 유지되어야 하는 서비스 간 데이터 계약의 수를 줄입니다.
런타임, 트레이싱 시스템 및 배포 파이프라인 간의 변환만을 위해 존재하는 "글루 코드(glue code)"를 제거합니다.
엔드투엔드 인덱싱 경로를 하나의 일관된 흐름으로 더 쉽게 이해할 수 있도록 만듭니다.
개발자 경험의 배율기 역할을 하는 통합
우리는 파트 1에서 언어 및 런타임 경계(일부 배관에는 Go 개발, ML 워크플로우에는 Python 사용)가 인터페이스의 깔끔하지 못함으로 인해 마찰을 유발했음을 지적했습니다.
통합은 이러한 마찰을 은퇴시키는 방법입니다.
실무적으로 이는 다음을 개선합니다:
디버깅: 에러가 직렬화되고, 래핑되고, 재시도되면서 컨텍스트를 잃을 수 있는 지점이 줄어듭니다.
프로파일링: 서비스 전반에 걸쳐 로그를 짜 맞추지 않고도 여러 단계에 걸친 지연 시간과 리소스 리용률을 더 쉽게 추적할 수 있습니다.
온보딩: 엔지니어가 하나의 코드 경로를 따라가며 멘탈 모델을 더 빠르게 구축할 수 있습니다.
의도적으로 좁힌 영역 표면
통합은 시스템의 목적이 명확하게 제한되어 있을 때만 작동합니다. 인덱싱은 변환 레이어로서 비디오를 입력받아 재사용 가능한 표현으로 출력합니다. 이 범위를 명확히 유지하면 코드가 모든 것을 담는 잡동사니가 되지 않으면서도 수반되는 우발적인 복잡성을 낮출 수 있습니다.
2 - 패키징의 재고: "단일 컨테이너"가 실제로 의미하는 바

그림 2: 환경 전반에서 독립적인 단위로 실행
파트 1에서 주장한 바와 같이, 배포 유연성은 있으면 좋은 것이 아니라 최우선적인 제약 조건으로 드러났습니다. 어떤 환경은 "전체 플랫폼"처럼 보이고, 다른 환경은 "컨테이너 런타임과 몇 개의 노브"처럼 보입니다. Indexing 3.0은 이 전체 스펙트럼에서 실행되어야 했습니다.
"단일 컨테이너"는 이 제약 조건을 요약한 패키징 표현입니다.
"단일 컨테이너"는 압축이 아니라 디커플링에 관한 것입니다
목표는 모든 컴포넌트를 하나의 거대한 프레임워크 이미지에 쑤셔 넣는 것이 아닙니다. 목표는 인프라에 구애받는 컨트롤 플레인 프리미티브에 의존하지 않고 인덱싱 시스템을 실행 가능하게 만드는 것입니다.
실질적인 정의는 다음과 같습니다:
시스템이 독립적인 단위로 배포될 수 있습니다.
핵심 오케스트레이션을 수행하기 위해 Kubernetes API(또는 이와 유사한 것)를 별도로 요구하지 않습니다.
아키텍처의 포크(fork) 없이 최소한의 환경에서도 실행할 수 있습니다.
이것은 배포가 애플리케이션 로직으로 새어 나가는 제약 조건이 아니라 가장 아래 레이어의 속성이 되도록 하는 우리의 핵심 프레임과 일치합니다.
앱 레이어 내부로 오케스트레이션 이동
마이크로서비스 메시에서 오케스트레이션은 대개 애플리케이션 외부에 존재하며, 라우팅, 컨트롤러 및 플랫폼 동작 전반에 걸쳐 분산되어 있습니다.
파트 1의 레이어화된 모델에서는 오케스트레이션이 안쪽으로 이동합니다:
인덱싱 애플리케이션은 "무엇이 실행되어야 하는지" 정의합니다.
실행 레이어는 이를 실행하고 스케일링을 관리합니다.
인프라는 기저의 물리적인 기질 역할을 합니다.
이러한 도치가 이식성을 가능하게 만드는 원동력입니다. 시스템이 더 이상 단일 운영 환경에 종속되지 않기 때문입니다.
이것이 처음 생각했던 것보다 훨씬 더 중요했던 이유
패키징은 단지 어디서 실행할 수 있는지에만 영향을 미치는 것이 아니라 다음에도 영향을 미칩니다:
로컬 개발이 얼마나 단순한지.
여러 환경 전반에서 동작이 얼마나 일관적인지.
새로운 배포 방식이 얼마나 많은 운영 리소스를 그대로 상속받는지.
패키징이 더 단순해지면, 롤아웃, 디버깅, 지원, 온보딩에 이르는 다운스트림의 모든 과정 역시 단순해집니다.
3 - 단일화된 실행 레이어 선택: 약속 대 현실

그림 3: 라우팅, 스케일링, 안정성을 위한 단일 기질
파트 1에서는 Indexing 3.0을 마이크로서비스 메시에서 간소화된 레이어로의 전환으로 프레이밍했습니다. 여기서는 애플리케이션 로직이 일관되게 유지되고, 실행 레이어가 배포를 처리하며, 인프라 레이어는 교체 가능한 존재인 구조입니다.
이 섹션은 그 이야기의 다소 민감할 수 있는 현실적인 과정입니다: 즉, "우리의 인덱싱 로직"과 "고객이 제공한 컴퓨터 자원" 사이에 위치할 실행 레이어를 선택한다는 것이 실제로 무엇을 유의하는지 설명합니다. 우리는 그 단일 레이어로 Ray Serve(Ray Core 및 Ray Serve의 호스팅 프로바이더로 Anyscale 협력)를 선택했습니다. 이 결정은 확실한 레버리지를 제공했으나, 정면으로 마주해야 했던 몇 가지 대가 역시 치러야 했습니다.
단 하나의 추상화가 주는 약속
단일화된 실행 레이어의 핵심 약속은 매우 간단합니다: 늘어나는 서비스 군대 전반에 걸쳐 동시성, 스케일링, 결함 처리 메커니즘을 매번 재구축하는 대신, 단 한 곳에서 이를 쉽게 표현할 수 있도록 구조를 통일해 주는 것입니다.
Ray Serve의 서빙 모델은 이 약속을 구체화합니다:
요청은 HTTP(또는 gRPC) 프록시를 통해 유입되고 큐에 적재된 뒤 가용한 복제본(replica)으로 라우팅되어, 유저 코드를 실행하는 복제본 액터(Actor)에 의해 처리됩니다.
Serve는 단일 인그레스 포인트뿐만 아니라 스케일링 및 고가용성을 위해 다중 프록시를 지원합니다.
모델 구성을 위해 서비스가
DeploymentHandles를 통해 서로를 호출할 때도 동일한 요청 경로가 적용되므로, 내부 구성이 라우팅 및 배칭 동작을 공유할 수 있습니다.
인덱싱 플랫폼을 구축할 때 이 점은 상당한 매력으로 다가옵니다. 인덱싱은 단순한 하나의 모델 호출이 아니라 다단계 흐름이며, 세부적인 각 단계마다 동시성 제어와 실패 처리가 필요하기 때문입니다. 단일화된 실행 레이어는 "수많은 임시 스케줄러를 임시방편으로 엮어 만든 시스템"과 "표준화할 수 있는 강력한 단일 스케줄링 기질을 갖춘 시스템"의 차이를 만듭니다.
이것은 파트 1에서 다룬 패키징 및 배포 동인과도 긴밀하게 정렬됩니다. 오케스트레이션 로직이 Kubernetes 컨트롤러나 마이크로서비스 간 접착 코드에 흩어지지 않고 실행 레이어 안쪽에 위치한다면, 아키텍처를 새로 쓰지 않고도 서로 다른 환경에서 원활하게 작동하는 이식성 높은 시스템에 더욱 가깝게 확장할 수 있습니다.
인덱싱 워크로드의 현실
과소평가하기 쉬운 부분은 실행 레이어가 마냥 공짜가 아니라는 점입니다. 프레임워크 자체의 요청 경로, 컨트롤 플레인, 그리고 동작 성능 특징이 추가로 발생합니다. Ray Serve 공식 문서 역시 요청 경로에서의 높은 지연 시간과 낮은 처리량이 가장 흔히 발생하는 문제라고 언급하며, 면밀히 검토해야 할 라우터 및 처리 시간 성능 지표를 명시하고 있습니다.
비디오 인덱싱 환경에 있어 이 점은 매우 치명적인데, 워크로드의 형태가 종종 이 프레임워크 자체의 오버헤드를 배로 키우기 때문입니다.
현실 #1: 요청 라우팅 오버헤드는 실재하며, 때로는 뼈아픕니다
Ray Serve 아키텍처는 요청을 프록시를 통해 라우팅하고, 큐에 대기시킨 뒤 가용한 복제본을 선택해 실행합니다. 범용 서빙을 위해서는 타당한 기본 설계이지만, 이는 실제 작성한 코드가 실행되기도 전에 프레임워크에 의한 자체적인 연산 작업이 개입됨을 뜻합니다.
만약 애플리케이션의 단계 사이에 무수히 많은 짧은 전송 홉("small hops")이 존재한다면, 이러한 라우팅 오버헤드가 전체 엔드투엔드 지연 시간 중 무시할 수 없는 비중을 차지하게 됩니다. 추상화가 시스템을 조립하는 데는 유용하지만 동시에 조립 작업 자체에 필요한 비용도 예산에 반영해야 함을 상기시켜 줍니다.
이것은 단순한 가설이 아닙니다. Ray의 성능 튜닝 가이드에서도 요청 경로의 병목 진단을 상세히 논의하며, 라우터 처리량 및 큐 대기 지연 시간을 경고 신호로 지목합니다. 또한 Ray 생태계는 지연 요구량이 까다로운 서빙 제품군을 위해 맞춤형 custom 라우팅 공식 지원 기능을 추가하는 등 가용 경로 개선에 지속적인 투자를 이어가고 있습니다.
인덱싱 관점에서의 실질적인 교훈은 다음과 같습니다: 프레임워크의 오버헤드 또한 시스템의 한 부분이라는 점입니다. 특히 전체 수행 시간 중 오버헤드 비율이 치솟을 수밖에 없는 다수의 짧은 태스크들이 워크로드에 섞여 있을 때, 이를 명확히 측정하고 프로파일링하며 우회해서 설계해야 합니다. 실제로 이와 같은 "짧은 비디오 셋업 비용 페널티"는 파트 1에서 설명했던 한계 돌파 지점이기도 했습니다.
현실 #2: 비디오 디코딩은 핵심이며, 대개 CPU 병목을 유발합니다
비디오 인덱싱을 단지 "GPU 추론과 약간의 주변 연산" 정도로 가볍게 보기는 쉽습니다. 하지만 프로덕션 환경의 디코딩은 전체 파이프라인에서 가장 결과론적인 영향을 미치는 영역 중 하나이며, 코덱 종류, 포멧 구성, 하드웨어 디코딩 가용 여부에 따라 예외 없이 높은 CPU 자원을 소모합니다.
NVIDIA의 NVDEC 공식 문서 역시 디코딩을 NVDEC로 넘겼을 때 비로소 다른 태스크를 실행하기 위한 CPU 자원이 안전하게 확보된다는 점을 분명히 합니다. 즉, 하드웨어 오프로딩이 없는 기본 디코딩 경로는 많은 연산 비용을 요구한다는 의미입니다.
심지어 최신 PyTorch 생태계 진영에서도 CUDA 디코딩을 더 빠른 최적 가속 경로로 제안하지만, 치명적인 함정이 존재합니다: 코덱 규격이나 비디오 포맷이 탑재된 하드웨어 디코더에 공식 매칭되지 않는 경우, 조용히 기존의 가벼운 소프트웨어 CPU 디코딩 방식으로 강제 폴백(fallback)될 수 있습니다.
인덱싱 플랫폼 입장에서 CPU 가용성은 있으면 좋은 보조 리소스가 아닙니다. 겉보기에는 "GPU 모델 작동"이 핵심인 것처럼 보여도, 최선두에서 실시간 병목을 일으킬 수 있는 주요 요인이기 때문입니다. 심지어 CPU 디코딩 능력이 한계까지 포화되어 정작 비싼 GPU가 할 일 없이 대기하는 최악의 사용률 참사가 발생하기도 합니다. "이종 리소스 프로파일(heterogeneous resource profiles)"이 추상적인 논점에 머무르지 않고, 디코딩 연산 단 하나만으로도 CPU를 1등급 리소스 스케줄링 차원으로 엄격히 다루어야 하는 강력한 이유입니다.
현실 #3: 다양한 리소스 특성을 지닌 단계들은 명시적인 리소스 모델링을 요구합니다
인덱싱 워크로드는 본질적으로 서로 다른 성격의 하드웨어 리소스를 사용합니다:
다운로드 및 I/O 중심 구간
CPU 점유가 지배적인 디코딩 구간
GPU 점유가 지배적인 임베딩 추출 구간
CPU 및 메모리 부하가 심하게 스윙하는 후처리 구간
단일화된 실행 레이어는 우리가 이러한 필요 사양을 물리적으로 명시해 주어야 비로소 의미 있게 작동합니다. Ray Core는 태스크 및 액터에 필요한 CPU, GPU 등의 논리적 리소스 요구 사항 지정을 공식 지원하며, 오직 해당 조건이 안전하게 확보된 하이브리드 노드 환경에만 스케줄링되도록 조정합니다. 한 태스크가 다른 태스크의 리소스를 방해하거나 병목 단계 앞단에 동시 실행이 걸려 병목이 폭증하는 비극적인 실패 시나리오를 방지하려면 이 성능은 필수 불가결합니다.
이것이 바로 파트 1의 "간소화된 레이어" 재구성 설계가 운영 현장에서 살아 숨 쉬는 모습입니다. 단순히 코드만 조각내는 것이 아니라, 컴퓨팅 자원의 의미론(resource semantics)을 논리적으로 통일하는 작업입니다: 인덱싱 플랫폼은 파이프라인 흐름을 기술하고, 실행 레이어는 동시성과 물리적 배치를 제어하며, 인프라 레이어는 온전한 기하학적 리소스만을 묵묵히 공급합니다.
얻은 교훈: 추상화는 엔지니어링 리소스를 파괴하는 것이 아니라 재배치할 뿐입니다
훌륭한 실행 레이어를 도입하더라도 전체 엔지니어링 투여량이 마법처럼 제로가 되지는 않습니다. 대신 일하는 위치가 한 단계 격상됩니다. 자체 오케스트레이션 코드를 매번 밑바닥부터 짜는 수고를 덜어내는 대신, 요청 처리 경로의 온전한 파악, 원격 계측(instrumentation) 및 성능 고도화 튜닝, 파이프라인 로직과 프레임워크 스케줄러 간의 특성 매칭 고도화에 인적 자원을 더욱 가치 있게 활용할 수 있게 됩니다.
동시에 겪었던 아주 솔직하고 값진 경험이 하나 더 있습니다: 개발 주기 극초반에 허리가 될 단일 통합 실행 레이어를 결정했다면, 해당 기술을 뒤에서 전력으로 개발 및 공급하는 핵심 플랫폼 전담 엔지니어 팀 또한 우리 내부 팀의 실질적인 연장선이라 믿고 밀접히 관계를 이어가야 합니다.
Ray Serve와 Anyscale 서비스는 우리에게 막강한 동력을 주었지만, 예측 불가능하고 무거운 비디오 워크로드를 극한까지 소화하면서 현실 필드의 다채로운 엣지 케이스들을 꽤 마주하기도 했습니다. 우리는 Anyscale 내 Ray Serve 핵심 개발팀과 적극적으로 원격 협력을 유지하면서 원인 모를 병목 현상을 규명하고, 그대로 똑같이 재현 가능한 코드로 협업 사례를 피드백하였으며, 패치 릴리즈 과정을 빈틈없이 단축했습니다. 초기 세팅의 시행착오는 고됐으나, 이러한 전사적 파트너 파이프라인 협업 구조 전반이 최종 승부에서 이 베팅을 영리하게 증명해 낼 수 있었던 아키텍처의 강력한 일부였습니다. 급변하는 서빙 코어 스택에서 기술 파트너십은 부차가 아니라 설계의 실질적 본질입니다.
4 - 중단 없는 다중 배포 환경 지원

그림 4: 하나의 개념적 플랫폼, 다양한 실행 환경
우리는 파트 1에서 다음과 같은 과감한 주장을 했습니다: 배포 형태는 시스템의 정의적 특징이 아니라 하나의 변수여야 한다. 이 섹션은 이를 실제로 어떻게 조율하고 구체화했는지 다룹니다.
배포는 나중에 끼워 맞추는 과정이 아니라 주요 설계 방향성입니다
고객이 인덱싱 파이프라인 출력물에 본격적으로 의존하기 시작하면, 이미 구축된 배포 제약 조건을 뜯어고치는 작업은 막대한 비용을 요구하게 됩니다. 특정 환경의 단일 컨트롤 플레인에 시스템이 완전히 잠겨 버리는 순간, 새로운 온프레미스나 엣지 환경 대응 요구는 필연적으로 전체 재작성이나 파편 포크(fork)로 이어집니다.
Indexing 3.0은 개발 완료 후 도커 패키징 작업을 시작할 때가 아니라, 아키텍처 기초 설계 첫 줄을 그을 때부터 "이것이 향후 어디서 굴러갈 것인가"를 최우선 기능 요구 사양으로 상정했습니다.
파편화 없는 높은 소화력
여러 시스템 환경을 호환한다는 것은, 각 환경에 맞춰진 N개의 서로 다른 변종 플랫폼을 매번 눈물겹게 병렬 유지 보수한다는 소리가 아닙니다.
진정한 목적은 단 하나의 관념적 핵심 구조를 완전히 통일한 상태에서, 환경별 개별 성격들은 최대한 가장 바닥에 있는 물리 어댑터 레이어로 가볍게 밀어내는 것입니다. 파트 1에서 설명한 깔끔한 모듈식 레이어 아키텍처의 원리와 일맥상통합니다: 인프라가 어떻게 물리적으로 설계되어 있든, 최상위 애플리케이션 핵심 구동 로직은 요동 없이 고고하게 보존되어야 합니다.
실 구현 관점에서 이는 다음을 실천하는 것을 뜻합니다:
운영 환경이 어떻게 달라지든 인덱싱의 핵심 수행 동작은 완벽히 대칭되도록 일관성을 지키는 것.
특이 환경의 성격들은 가벼운 설정 파일 단위, 개별 실행 헬퍼 도구, 그리고 얇은 어댑터 단독 코드로 완벽히 매몰 격리시키는 것.
시간이 지나면서 결국 두터운 레거시 편차를 낳고 마는 "특정 고객 전용 예외 처리 분기 코드"를 극도로 경계하고 방지하는 것.
구동 인프라 환경의 다양성을 눈감았을 때 치르는 숨겨진 세금
눈앞의 배포 다양성을 외면하고 단순 편의를 좇는다면, 플랫폼은 결국 더 악성으로 파편화됩니다. 온갖 개별 환경 맞춤형 하드코딩 패치, 독점 임시 릴리즈, 특정 고객 환경 전용의 복잡한 운영 오케스트레이션 매뉴얼 등의 부채가 켜켜이 쌓이게 됩니다.
아키텍처 선행 단계에서 애초에 다중 구동 환경 유연성을 계산해 두는 설계 총합 비용이, 향후 이로 인해 무너지는 플랫폼 파편화 파멸 비용을 변제하는 것보다 압도적으로 저렴합니다. 이는 향후 비즈니스 가치가 달라지고 요구 인프라 정책이 크게 선회해도, 시스템 전체를 통째로 부수지 않고 지속 가능하게 진화 변형시켜 나가는 결정적 무기가 됩니다.
결론: 휴먼 리소스 제약을 푸는 인프라가 결국 모든 엔지니어링 한계를 풉니다
Indexing 3.0 프로젝트는 무조건 고비용의 극단적 성능 지표 도달을 목표로 시작되지 않았습니다. 수많은 고성장 ML 인프라 팀이 파국에 이르러 마주하는 가장 본질적인 질문에서 출발했습니다:
시스템은 어떻게든 돌아가고 있는데, 코드 전체 구조를 제대로 정확히 꿰뚫는 엔지니어는 단 몇 명뿐이고, 심지어 특정 클라우드 단 한곳에서만 아슬아슬하게 실행된다면 무슨 일이 발생할 것인가?
우리가 겪었던 정답은, 개발 및 개선 발전 복리 속도가 보이지 않는 곳에서 계속 거대하게 둔화된다는 점이었습니다. 사소한 기능 변경도 극도로 조심스러워지고, 고객 환경 신규 배포는 늘 깨지기 일쑤며, 신장 개발자의 온보딩은 마치 역사 유적을 발굴하는 가혹한 고고학 탐사 업무로 돌변합니다. 그리고 단지 개발 당시의 편의를 위해 마구 타협했던 임베디드 아키텍처 부채들은 조용히 단단하게 굳어 향후 플랫폼 전반을 옭아매는 질긴 족쇄가 됩니다.
이번 Indexing 3.0 설계 혁신이 증명해 낸 가장 가치 있는 이정표는, 특정 한두 개의 개별 고속화 기능 달성이 아닙니다; 미래 시스템 구조 전반이 가능하게 만드는 패러다임의 확실한 해방에 있습니다:
더 많은 새 엔지니어가 커뮤니케이션 및 코드 충돌 병목 없이 자신 있게 비즈니스 빌딩에 참여할 수 있게 됨
하나의 통합 코어 플랫폼 그대로 퍼블릭 클라우드, 온프레미스 프라이빗 망, 저사양 제한 하드웨어 기기 수준까지 완전히 동일하게 지배 운영함
더 이상 배포 환경 구동 성격이 최상위 소프트웨어 아키텍처의 설계 복잡성을 지배 역행하지 않음
구조 자체가 우아하고 투명하고 심플해졌기에, 비로소 세밀한 유닛 단위 인프라 비용 및 효율 최적화가 완연히 통제 범위 안으로 들어옴
이 값진 교훈은 비단 비디오 인덱싱 파이프라인 개발 조직뿐만 아니라, 모든 방면의 범용 플랫폼 엔지니어링 패권에도 분명히 투영될 것입니다.
현대 ML 인프라 생태계에서, 최종 성능 확장 가속 능력을 극단적으로 가로막는 병목은 단순히 무거운 인공지능 모델이나 고성능 엔비디아 GPU 하드웨어 부족 때문만은 아닙니다. 추론하고 논의하기 난해하도록 엉겨 붙어 설계된 시스템 자체, 초기 가정과 완전히 다른 미지의 이종 환경 적용에 단 1도 저항력을 갖추지 못한 나약한 구조, 그리고 신규 인력이 두려움 없이 기여할 수 없게 막는 굳어버린 플랫폼 아키텍처가 결국 발목을 잡습니다.
그런 맥락에서 일구어 낸 참된 간결함(Simplicity)은 기술적 야심이 부족하다는 뜻이 전혀 아닙니다. 이는 지엽적이고 국지적인 똑똑함의 과시를 희생하는 대신, 글로벌 스케일의 전사적 레버리지 가치로 치환받아 소출을 보장받겠다는 영리하고 치밀한 의도적 설계 철학입니다.
Indexing 3.0은 이러한 거대한 성장의 기틀을 우리의 시스템 근간 최하단에 확실히 다져 박는 위대한 장정이었습니다. 이제 우리의 미래 인프라 여정은 꼬여버린 배포 올가미를 멍청히 푸는 무의미한 삽질을 멈추고, 동영상 이해 지평이 약속하는 더 위대한 미래 지적 가치들에 온전하고 풍요롭게 집중할 것입니다.




