본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 27. 01:59

Cloud Run에서의 AI 콜드 스타트(Cold Start) 가이드

요약

Cloud Run 환경에서 AI 모델 배포 시 발생하는 콜드 스타트 문제를 분석하고 이를 최적화하는 가이드를 제공합니다. 인프라 프로비저닝부터 엔진 초기화까지의 단계를 설명하며 효율적인 AI 아키텍처 구축 방법을 다룹니다.

핵심 포인트

  • AI 콜드 스타트는 대용량 모델 가중치를 GPU로 이동시키는 과정이 핵심임
  • Cloud Run의 이미지 스트리밍을 활용해 컨테이너 부팅 속도 최적화 가능
  • GPU를 대체 가능한 컴퓨팅 자원으로 취급하는 아키텍처 설계 권장
  • 인프라, 이미지 스트리밍, 엔진 초기화 등 단계별 최적화 필요

저는 한 개발자가 Reddit에서 여러 리전에 걸쳐 AI를 위한 Cloud Run 콜드 스타트(Cold Start)를 관리할 "정상적인 방법"이 있는지 묻는 것을 보았습니다. (https://www.reddit.com/r/googlecloud/comments/1s8yzn1/is_there_a_sane_way_to_manage_cloud_run_cold/) 그들은 최대 20초에 달하는 시작 지연 시간(startup latencies)을 경험하고 있었는데, 이는 인프라가 가동되는 동안 사용자가 응답을 기다려야 하는 답답한 공백이었습니다.

그 토론에는 서버리스 GPU를 거의 포기한 개발자들이 가득했으며, 일부는 단지 지연 시간을 피하기 위해 GKE로 다시 마이그레이션하기도 했습니다. 저는 이제 AI 콜드 스타트의 메커니즘(Mechanics)을 깊이 파고들어 그 "정상적인 방법"을 찾을 수 있을지 확인해 볼 때라고 결정했습니다.

Cloud Run에서 Gemma 4와 같은 모델을 호스팅하는 방법에 대해 조사하는 동안, 저는 Oded Shahar(Cloud Run 시니어 엔지니어링 매니저) 및 초청 연사 Ajay Nair(Elastic의 플랫폼 글로벌 부사장)와 함께 Google Cloud Next '26에서 공동 발표하는 특권을 누렸습니다.

우리의 세션인 "Cloud Run에서 커스텀 모델로 AI 아키텍처 구축하기(Build AI architectures with custom models on Cloud Run)"에서, Ajay는 Elastic이 Cloud Run의 '스케일 투 제로(scale-to-zero)' 효율성을 유지하면서도 17개 이상의 모델 변형에 대해 수백만 건의 일일 요청을 처리할 수 있게 해주는, 프로덕션 환경에서 검증된 전략을 공유했습니다.

Cloud Run에서 커스텀 모델로 AI 아키텍처 구축하기

Ajay는 비밀이 단지 모델에 있는 것이 아니라, GPU를 관리해야 할 인프라가 아닌 대체 가능한 컴퓨팅 자원(fungible compute)으로 취급하는 데 있다는 것을 보여주었습니다.

저는 그때 콜드 스타트 지연 시간을 최소화하는 것이 단지 모델에 관한 것이 아니라, 빠르고 확장 가능하며 안전하게 유지하는 인프라 패턴과 아키텍처 결정에 관한 것이라는 점을 깨달았습니다.

AI 콜드 스타트의 구조

공식 Google Cloud GPU 베스트 프랙티스에서 설명하듯이, AI 콜드 스타트는 표준 웹 마이크로서비스(microservices)와는 다릅니다. 단순히 코드를 부팅하는 것이 아니라, 기가바이트 단위의 가중치(weights)를 특화된 물리적 가속기(physical accelerator)로 이동시키는 과정입니다.

이를 4단계의 경주라고 생각하십시오. 각 단계를 최적화하지 않으면 사용자를 놓치게 될 것입니다.

1단계: 인프라 프로비저닝 (Infrastructure Provisioning) (~5초)

Cloud Run은 물리적 GPU를 할당하고 사전 설치된 NVIDIA 드라이버를 주입합니다. Google이 드라이버를 대신 관리해주기 때문에, Dockerfile을 무겁게 만들 필요가 없습니다.

2단계: 블록 레벨 컨테이너 이미지 스트리밍 (Block-Level Container Image Streaming) (1-2초)

Cloud Run은 "이미지 스트리밍 (image streaming)"을 사용합니다. 이는 부팅에 필요한 블록만 가져온다는 의미입니다. 여러분의 15GB CUDA 이미지는 실제로 아주 작은 Node.js 앱만큼 빠르게 시작될 수 있습니다!

3단계: 엔진 초기화 (Engine Initialization) (5-15초)

이 단계는 추론 엔진 (inference engine, 예: vLLM, Ollama)이 예열되는 과정입니다. 이는 매우 많은 CPU를 소모하는 작업이며, 많은 사람들이 자신도 모르는 사이에 여기서 스로틀링 (throttling)을 겪게 됩니다.

4단계: 모델 로딩 및 VRAM 전송 (Model Loading & VRAM Transfer)

이것이 마지막 장애물입니다. 스토리지에서 GPU 메모리로 모델 가중치 (weights)를 이동시키는 과정입니다. CPU가 핵심인 일반적인 웹 앱과 달리, 여기서는 GPU 메모리가 주요 제약 사항입니다. 만약 모델의 가중치가 GPU 메모리 내에 완전히 들어가지 않는다면, 더 느린 시스템 RAM으로 스왑 (swap)되면서 성능이 현저히 저하됩니다.

AI 콜드 스타트 처리를 위한 모범 사례 (Best practices)

"정상적인" 운영 환경을 구축하기 위해, GPU를 이용한 AI 추론에 관한 Google Cloud 공식 문서를 바탕으로 활용할 수 있는 몇 가지 중요한 레버(levers)를 소개합니다.

4단계 최적화

적절한 배포 옵션 선택

4단계는 기가바이트 단위의 가중치를 스토리지에서 GPU 메모리로 이동시키는 "마지막 장애물"입니다. 여러분의 스토리지 선택에 따라 이 전송 속도가 결정됩니다:

  • Cloud Storage (병렬 다운로드, Concurrent Download) - 가장 빠름: Google Cloud CLI (gcloud storage cp)를 사용하면 모델 파일을 병렬로 다운로드할 수 있습니다. 이는 네트워크 처리량(throughput)을 극대화하고 전송 시간을 획기적으로 단축하기 때문에, 거대한 가중치(weights)를 다룰 때 권장되는 방법입니다.

  • Cloud Storage (FUSE) - 가장 쉬움: 버킷(bucket)을 로컬 파일 시스템으로 마운트하여

  • 4-bit 양자화 (Quantization): 이것은 궁극의 콜드 스타트 해킹 방법입니다. 가중치(weights)가 작아지면 스토리지에서 가져와야 할 기가바이트(GB) 수가 줄어들며, 이는 4단계의 다운로드 및 전송 부분을 직접적으로 가속화합니다.

  • 빠른 포맷 (Fast Formats): 시작 시간을 최소화하기 위해 GGUF와 같이 로드 시간이 빠른 모델 포맷을 선택하세요. 가장 빠른 성능을 위해서는 Python의 "pickle" 파일에서 벗어나 제로 카피(zero-copy) 로딩을 지원하는 Safetensors를 사용하세요.

  • VRAM 적합성 확보: 양자화된 모델을 사용하여 가중치가 GPU 메모리 내에 완전히 들어갈 수 있도록 하세요. 만약 모델이 VRAM을 초과하면, 시스템이 훨씬 느린 RAM으로 스왑(swap)되면서 4단계가 정체될 것입니다.

3단계 및 4단계 최적화: 인프라 및 네트워크 레버

이러한 인프라 설정은 시작 프로세스에서 가장 까다로운 부분들을 가속화하는 데 필요한 리소스를 제공합니다.

Startup CPU Boost (3단계 가속화)

이 기능은 시작 중에 CPU 성능을 일시적으로 두 배로 높여줍니다. 1 vCPU 인스턴스는 시작 시간과 서비스 제공 후 첫 10초 동안 2 vCPU로 부스트됩니다. 엔진 초기화는 엄청난 CPU 집약적 작업이므로 3단계에 필수적입니다.

Direct VPC Egress 및 PGA (4단계 가속화)

**Private Google Access (PGA)**와 함께 Direct VPC Egress를 활용하면 모델 가중치 트래픽이 Google의 내부 고속 백본(backbone)에 머물도록 보장할 수 있습니다. 이는 수 기가바이트의 가중치를 VRAM으로 이동하는 데 소요되는 시간을 단축하기 위해 네트워크 경로를 최적화합니다.

동시성 조정 (Concurrency Tuning, 콜드 스타트 방지):

Cloud Run에서 "동시성 (concurrency)"은 플랫폼이 새로운 인스턴스를 시작하기 위해 스케일 아웃(scale out)하기 전, 단일 인스턴스가 처리할 수 있는 최대 요청 수를 의미합니다. AI 워크로드의 경우, 이 설정을 모델 엔진의 내부 병렬화 플래그(예: vLLM의 --max-num-seqs 또는 Ollama의 OLLAMA_NUM_PARALLEL)와 함께 조정해야 합니다.

이상적인 Cloud Run 동시성을 찾으려면 공식 Google Cloud 공식 (formula)을 사용하세요:

(모델 인스턴스 수 * 모델당 병렬 쿼리 수) + (모델 인스턴스 수 * 이상적인 배치 크기 (ideal batch size))

예시: 만약 인스턴스가 GPU에 3개의 모델 인스턴스를 로드하고, 각 모델 인스턴스가 이상적인 배치 크기 4를 가진 상태에서 4개의 병렬 쿼리를 처리할 수 있다면, Cloud Run의 최대 동시 요청(maximum concurrent requests)을 24로 설정하면 됩니다: (3 × 4) + (3 × 4)

계산 원리: 목표는 사용자가 긴 대기열에 갇히지 않도록 보장하면서 GPU를 완전히 포화(saturated) 상태로 유지하는 것입니다. 이 예시에서 총 24개의 동시 요청은 두 개의 기능적 그룹으로 나뉩니다:

  1. 활성 처리 (Active Processing, 12개 요청): (3개 인스턴스 × 4개 쿼리)로 계산되며, 이는 GPU가 어느 시점에서든 활발하게 처리할 수 있는 총 요청 수를 나타냅니다.

  2. "다음 배치" 버퍼 (The "Next Batch" Buffer, 12개 요청): (3개 인스턴스 × 4개 배치 크기)로 계산되며, 이는 컨테이너 내부에서 "대기 중(on deck)"인 요청들입니다. GPU가 첫 번째 배치를 완료하자마자 이 대기 중인 요청들을 즉시 가져와 처리합니다.

VRAM이 허용하는 한 이 값을 최대한 높게(보통 10~20명의 사용자) 조정함으로써, 하나의 Warm Instance(활성화된 인스턴스)가 새로운 Scale-out(확장) 이벤트와 그에 따른 Cold Start(콜드 스타트)를 유발하지 않고도 많은 요청을 처리할 수 있습니다.

Scaling Controls (임계값 조정)

위의 공식이 최대 용량을 정의한다면, Cloud Run이 다음 인스턴스를 시작하기로 결정하는 시점 또한 조정할 수 있습니다. Cloud Run의 Autoscaler(오토스케일러)는 일반적으로 60%의 Utilization(사용률)을 목표로 하지만, 실행 시간이 긴 AI Cold Start(콜드 스타트)의 경우 Scaling Controls를 통해 이 임계값을 80% 또는 90%까지 높일 수 있습니다.

  • Concurrency Target (동시성 목표): 이 값을 높이면 Scale-out(확장)을 트리거하기 전에 단일 Warm Instance(활성화된 인스턴스)에 더 많은 요청을 "패킹(pack)"할 수 있습니다.

  • CPU Target (CPU 목표): CPU 목표를 높이면 초기화 또는 고강도 Inference(추론)로 인해 CPU 사용률이 급증했다는 이유만으로 플랫폼이 새로운 인스턴스를 시작하는 것을 방지할 수 있습니다.

Scaling & Reliability Strategies (확장 및 신뢰성 전략)

scaling and reliability strategies illustration

때로는 Cold Start(콜드 스타트)를 처리하는 가장 좋은 방법이 이를 완전히 피하거나 선제적으로 관리하는 것입니다.

Single-Region "Always-On" (단일 리전 "항시 가동") 트레이드오프

전 세계에 배포하는 경우, 모든 리전에서 Minimum Instances(최소 인스턴스)를 1로 설정하는 비용이 누적됩니다. 대신, 단 하나의 리전에만 'Always-on(항시 가동)' 서비스를 구축하는 것을 고려해 보세요. 100ms의 글로벌 네트워크 지연(Delay)이 20초의 로컬 Cold Start(콜드 스타트)보다 훨씬 더 나은 사용자 경험을 제공합니다.

15분의 유예 기간 (The 15-Minute Grace Period): 흔히 발생하는 질문은 '요청이 처리된 후 내 인스턴스가 얼마나 오랫동안 Warm(웜) 상태를 유지하는가?'입니다. Cloud Run은 일반적으로 인스턴스가 유휴 상태(Idle, 요청을 처리하지 않는 상태)가 된 후 15분 동안 인스턴스를 활성 상태로 유지합니다. 만약 트래픽이 예측 가능하고 10~12분마다 발생한다면, 'Always-on(항상 켜짐)' 서비스를 사용할 필요조차 없을 수도 있습니다. 플랫폼의 기본 종료 정책(Shutdown policy)이 다음 사용자를 위해 Warm 인스턴스를 준비된 상태로 유지해 줄 것이기 때문입니다.

참고: 표준 요청 기반(Request-based) 서비스의 경우 이 유휴 시간은 "무료"이지만, GPU 서비스는 인스턴스 기반 과금(Instance-based billing)이 적용된다는 점을 기억하세요. 따라서 요청 사이의 인스턴스가 Warm 상태로 유지되는 시간만큼 비용이 청구됩니다.

"웨이크업 콜 (Wake-Up Call)" 전략

때로는 Cold Start(콜드 스타트)를 처리하는 가장 좋은 방법이 이를 선제적으로 가리는 것입니다. 예를 들어, 사용자가 "새 채팅 (New Chat)"을 클릭하거나 텍스트 영역 위에 마우스를 올리는 등 UI에서 다가올 요청을 예측할 수 있다면, 즉시 서비스로 가벼운 헬스 체크 (Health check)를 보낼 수 있습니다. 사용자가 프롬프트 입력을 마칠 때쯤이면, Cold Start의 첫 두 단계인 인프라 프로비저닝 (Infrastructure Provisioning)과 컨테이너 이미지 스트리밍 (Container Image Streaming)이 이미 백그라운드에서 완료되어 있을 것입니다.

전문가 팁 (Pro-Tip): 이 "웨이크업 콜"을 최대한 빠르게 수행하려면, "hi"와 같은 더미 프롬프트 (Dummy prompt)를 보내는 대신 항상 **비추론 엔드포인트 (Non-Inference Endpoints)**를 사용하세요.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0