본문으로 건너뛰기

NVIDIA Dynamo의 LLM 추론 장애 복구를 초 단위로 단축

Shadow engine과 GMS로 LLM 추론 worker의 복구 시간을 283초에서 7.3초로 줄였습니다.

이 요약은 AI가 원문을 분석해 생성했습니다. 정확한 내용은 원문 기준으로 확인하세요.

TL;DR

NVIDIA Dynamo의 Shadow Engine Recovery는 LLM 추론 worker가 프로세스 장애를 겪을 때 같은 GPU에 미리 초기화한 standby engine을 활성화해 serving capacity를 복구하는 기능입니다. GPU Memory Service (GMS)가 HBM의 가중치를 엔진 프로세스와 분리해 관리하므로 active와 shadow가 가중치를 복제하지 않고 공유하며, CUDA context·communicator·CUDA graphs도 장애 전에 준비해 둡니다. GLM-5.2를 NVIDIA B200에서 실험한 결과 두 번째 worker의 serving 재개 시간은 cold restart의 283초에서 7.3초로 줄었고, 장애 후 TTFT p50은 23,815ms에서 1,311ms로 낮아졌습니다. 현재 preview는 프로세스 장애에 한정되고 KV cache 승계가 아직 지원되지 않으며, Kubernetes 1.34 이상과 DRA 환경이 필요합니다.

빠른 이해

새로운 점

GPU 메모리의 물리 페이지 수명과 엔진 프로세스의 수명을 분리해 shadow engine을 같은 GPU에 상주시킨 뒤, 프로세스 장애 복구를 수분 단위 cold restart에서 초 단위 failover로 바꾼 점입니다.

핵심 메커니즘

GMS가 HBM의 가중치를 엔진 프로세스와 독립적으로 보존하고 active·shadow engine의 CUDA context에 각각 매핑합니다. Shadow engine은 communicator와 CUDA graph를 미리 초기화한 채 KV cache 없이 대기하다가 active 프로세스의 POSIX flock이 해제되면 잠금을 획득하고, 가중치 재매핑과 KV cache materialization 후 router에 재등록합니다.

핵심 수치

  • 두 번째 worker serving 재개 시간: Cold restart 283 s vs Shadow Engine Recovery 7.3 s- 7.3초는 장애 감지 1.7초와 shadow 승격 5.6초로 구성됩니다.
  • 장애 후 TTFT p50: 23,815 ms vs 1,311 ms- GLM-5.2, 두 worker 중 한 worker SIGKILL 후 관측값입니다.
  • 장애 후 Decode rate p50: 12 tok/s/user vs 46 tok/s/user- Cold restart와 Shadow Engine Recovery 비교입니다.
  • 5초 초과 TTFT 요청: 201 of 399 vs 1 of 398- 장애 후 비교 window의 요청 수입니다.
  • 20 tok/s/user 미만 요청: 226 of 399 vs 0 of 398- 장애 후 사용자별 decode rate 기준입니다.
  • 장애 중 baseline inter-token latency: 84 ms for 283 s- 50 ms SLA ceiling을 초과한 cold restart baseline 값입니다.

섹션별 상세

01

Shadow Engine Recovery의 핵심 구조

NVIDIA Dynamo의 Shadow Engine Recovery는 LLM 추론 프로세스가 장애를 일으켰을 때 cold restart 대신 같은 GPU에 대기 중인 엔진을 즉시 활성화하는 구조입니다. 활성 엔진과 shadow engine은 모두 시작 단계에서 CUDA context, communicators, CUDA graphs, 가중치 매핑을 준비하지만, 실제 요청을 처리하는 활성 엔진만 KV cache를 물리적으로 보유합니다. GPU Memory Service (GMS)는 가중치를 엔진 프로세스와 분리된 GPU 메모리 영역으로 관리해 두 엔진이 HBM의 동일한 물리 가중치를 공유하게 합니다. 그 결과 장애 시 critical path에는 잠금 획득, 가중치 가상 주소 재매핑, KV cache materialization, 라우터 재등록만 남습니다. GLM-5.2와 NVIDIA B200을 사용한 실험에서 두 번째 worker가 다시 serving하기까지 걸린 시간은 cold restart의 283초에서 7.3초로 줄었습니다.
두 worker 중 하나가 장애 난 뒤 두 번째 worker가 serving을 재개하는 시간을 cold restart와 Shadow Engine Recovery로 비교한 막대그래프입니다.
ChartCold restart는 283초가 걸리지만 shadow engine recovery는 7.3초로 줄어들며 39배 빠른 복구를 기록합니다. cold restart에는 가중치 재로딩, KV cache 크기 조정, autotune, CUDA graph recapture가 포함되고, shadow engine은 GPU에 이미 상주한 초기화 상태를 활용합니다.
02

LLM 추론 복구가 느린 이유

일반적인 추론 엔진 복구가 오래 걸리는 이유는 가중치의 수명이 엔진 프로세스에 묶여 있고 일부 초기화 상태를 다른 프로세스로 넘길 수 없기 때문입니다. 프로세스가 종료되면 CUDA context가 사라지면서 driver가 HBM에 있던 가중치까지 해제하므로 새 엔진은 저장소에서 가중치를 다시 로드해야 합니다. NCCL과 torch.distributed communicator는 실행 중인 프로세스에 연결되고, CUDA graphs는 캡처 당시의 가상 주소에 고정되므로 재시작 때 다시 만들어야 합니다. cold restart는 가중치 로드, KV cache 크기 조정, autotune, CUDA graph recapture를 모두 serving capacity가 줄어든 상태에서 수행합니다. 따라서 두 worker 중 하나가 사라지면 남은 worker가 전체 요청을 처리하는 동안 TTFT와 사용자별 decode rate가 악화됩니다.
03

GMS가 가중치를 유지하는 방식

GMS는 각 GPU에 붙는 sidecar로서 엔진 대신 물리 GPU 메모리 영역을 소유하고, 엔진에는 해당 영역을 가리키는 handle을 전달합니다. 엔진은 각자의 CUDA context 안에서 handle을 import한 뒤 동일한 물리 페이지를 서로 다른 virtual address에 매핑하며, 이 매핑은 시작 시 한 번 수행됩니다. 이후 kernel은 일반 포인터를 통해 HBM의 가중치를 직접 읽으므로 GMS가 요청별 메모리 접근 경로에 끼어들지 않습니다. CUDA Virtual Memory Management API의 reference counting 덕분에 하나의 엔진이 종료돼도 다른 매핑이 남아 있으면 물리 페이지가 유지됩니다. vLLM, SGLang, NVIDIA TensorRT-LLM은 가중치 memory pool에 custom torch.cuda.CUDAPluggableAllocator를 연결해 GMS를 통합하며, 엔진 내부에서는 가중치를 일반 torch.Tensor로 계속 다룹니다.
GMS sidecar가 관리하는 하나의 HBM 가중치 복사본을 active engine과 shadow engine이 각자의 가상 주소로 매핑하는 구조도입니다.
DiagramGMS는 물리 페이지를 소유하고 handle을 전달하지만 엔진의 일반적인 메모리 읽기 경로에는 들어가지 않습니다. 두 엔진은 서로 다른 CUDA context에서 같은 물리 가중치를 참조하므로 shadow engine을 추가해도 가중치가 HBM에 중복되지 않습니다.
04

미리 초기화한 Shadow Engine

Shadow engine은 활성 엔진과 같은 GPU에 상주하면서 요청을 처리하지 않고 잠금 획득을 기다리는 완전 초기화 프로세스입니다. 시작 과정에서 GMS의 가중치 매핑을 가져오고 NCCL·NIXL communicator를 설정하며 CUDA graphs와 warm-up까지 끝내므로 장애 후 이 상태를 새로 만들 필요가 없습니다. 대기 상태에서는 materializable한 메모리를 반환하고 KV cache의 주소 범위만 예약하므로 별도 가중치 복사본이나 물리 KV cache를 보유하지 않습니다. 활성 엔진이 장애 나면 shadow가 잠금을 얻고 가중치 매핑을 깨운 뒤 KV cache를 materialize해 frontend router에 다시 등록합니다. 현재 preview는 KV cache를 GMS로 공유하지 않기 때문에 승격된 엔진이 빈 KV cache에서 시작하며, 향후 prefix-cache index와 cache memory를 승계하는 작업이 진행 중입니다.
python
await engine.initialize() # weight load, torch.compile, autotune, CUDA graph capture...
# put the engine to sleep while we wait on the lock
await engine.sleep()
lock = FlockFailoverLock(lock_path)
await lock.acquire(engine_id=engine.id) # wait on the lock to wake
await engine.wake()

각 엔진이 초기화한 뒤 공유 잠금을 기다리고, 활성 프로세스가 종료되면 대기 엔진이 잠금을 획득해 깨어나는 failover 흐름입니다.

05

Worker와 라우터의 장애 전환

각 worker는 두 개의 engine container, GMS sidecar, active 엔진을 선택하는 공유 잠금으로 구성되고 여러 worker는 하나의 frontend router 뒤에 배치됩니다. 정상 상태에서는 한 엔진만 잠금을 보유하고 KV cache를 유지하며 router에 등록되고, 다른 엔진은 초기화를 마친 채 dormant 상태로 대기합니다. 활성 프로세스가 crash, segfault, SIGKILL 또는 liveness probe에 따른 종료를 겪으면 운영체제가 프로세스의 file descriptor를 정리하면서 POSIX flock을 해제합니다. shadow engine은 이 해제를 감지해 잠금을 획득하고 깨어나며, worker가 잠시 unroutable 상태가 된 뒤 새 엔진이 router에 등록됩니다. 기존 엔진의 container는 orchestrator가 재시작하고 초기화를 마친 뒤 다시 shadow 역할로 들어가므로 worker는 두 엔진의 역할을 교대하며 steady state로 돌아갑니다.
하나의 Frontend Router 뒤에 세 worker가 배치되고 각 worker가 active engine, shadow engine, GMS sidecar, GPU로 구성된 구조도입니다.
Diagram두 엔진의 배치는 worker 내부에 캡슐화되며 router와 frontend는 active engine만 인식합니다. 이 구조 덕분에 개별 worker의 장애 전환을 상위 오케스트레이션 계층의 변경 없이 fleet 단위로 확장할 수 있습니다.
정상 상태, engine A 장애, engine B cutover, engine A 재시작 후 shadow 복귀까지 네 단계의 worker 상태 전환을 나타낸 도식입니다.
Diagram정상 상태에서는 engine A가 잠금을 보유하고 engine B가 대기하지만, A가 종료되면 B가 잠금을 획득해 active 역할을 맡습니다. 이후 재시작된 A는 다시 shadow로 들어가므로 worker는 두 엔진을 교대하며 steady state를 회복합니다.
06

메모리 구성과 장애 후 복구

두 엔진을 한 GPU에 함께 배치하려면 HBM을 가중치, KV cache, buffers와 graphs로 나눠 수명별로 관리해야 합니다. 가중치는 GMS가 한 번만 할당하고 worker 안의 모든 엔진이 read-only로 매핑하므로 중복되지 않으며, NCCL buffers와 CUDA context·captured graphs는 활성·대기 엔진 모두가 유지합니다. KV cache는 현재 활성 엔진에만 materialize하고 해당 엔진이 종료되면 영역을 회수해 shadow가 사용할 수 있게 합니다. 복구 단계에서 shadow는 잠금을 얻은 뒤 가중치를 재매핑하고 새 KV cache를 확보하므로 가중치 재로드 없이 serving을 재개합니다. 이 구조가 대기 엔진의 상주 비용을 buffers, graphs, context, mapping 수준으로 제한해 동일 GPU에서 빠른 failover를 가능하게 합니다.
초기화, serving, failure, cutover, restarted 단계에서 shared weights, engine별 buffers와 graphs, 활성 엔진의 KV cache가 어떻게 배치되는지 나타낸 메모리 도식입니다.
Diagramweights는 전 단계에서 공유되고, KV cache는 active engine에만 물리적으로 할당됐다가 장애 후 shadow engine B에 새로 materialize됩니다. shadow engine A는 재시작 후 buffers와 graphs를 유지하지만 KV cache 없이 대기하므로 두 엔진을 같은 GPU에 배치할 수 있습니다.
07

GLM-5.2 벤치마크 결과

실험은 NVIDIA B200 node 두 대에 GLM-5.2를 NVFP4로 양자화해 worker 하나씩 배치하고, TP=8, 200K max context, FP8 KV cache 설정으로 수행했습니다. 단일 frontend가 초당 0.7개의 요청을 round-robin으로 분배했으며 요청은 입력 32,000토큰과 출력 1,000토큰으로 구성됐습니다. steady state에 도달한 뒤 두 worker 중 하나에 SIGKILL을 보내고 600초 동안 cold restart와 Shadow Engine Recovery를 비교했습니다. 두 번째 worker가 serving을 재개하는 시간은 283초 대 7.3초였고, shadow 구성의 7.3초는 장애 감지 1.7초와 shadow 승격 5.6초로 나뉩니다. 장애 후 TTFT p50은 23,815ms에서 1,311ms로, 사용자별 decode rate p50은 12 tok/s/user에서 46 tok/s/user로 개선됐으며 5초 초과 TTFT 요청은 201건에서 1건으로 줄었습니다.
08

TTFT와 Inter-token Latency 변화

cold restart에서는 한 worker가 빠진 283초 동안 생존 worker가 모든 요청을 처리하면서 TTFT p50이 장애 구간 내내 상승하고 약 90초 뒤 5초 SLA 선을 넘었습니다. Shadow Engine Recovery에서는 승격 직후 작은 변동만 발생한 뒤 TTFT가 healthy fleet 수준에 가까운 상태를 유지했습니다. Inter-token latency에서도 baseline은 84ms로 올라 283초 동안 유지돼 50ms SLA ceiling을 웃돌았지만, shadow 구성은 장애 직후 소폭 상승한 뒤 회복했습니다. 수치상 장애 후 20 tok/s/user 미만 요청은 cold restart에서 226건, shadow 구성에서 0건이었습니다. 다만 이 결과는 하드웨어나 node 장애가 아니라 프로세스 장애를 주입한 두 worker 실험에 해당하므로 모든 장애 유형에 동일하게 적용되는 결과는 아닙니다.
장애 시점 전후 60초 rolling median 기준 TTFT를 cold restart baseline과 shadow engine recovery로 비교한 선그래프입니다.
Chartbaseline은 한 worker가 빠진 뒤 TTFT가 계속 상승해 장애 구간에서 20초를 넘고 5초 SLA ceiling도 초과합니다. shadow 구성은 승격 직후에도 약 1초대 수준을 유지해 surviving worker가 전체 요청을 떠안는 동안의 queue 증가를 크게 줄입니다.
장애 전후 60초 rolling median 기준 Inter-token Latency를 두 복구 방식으로 비교한 선그래프입니다.
Chartcold restart baseline은 장애 뒤 ITL이 84ms까지 올라 283초 동안 유지되며 50ms SLA ceiling을 넘습니다. shadow engine recovery는 잠시 상승한 뒤 약 20~30ms 범위로 돌아와 토큰 생성 속도 저하를 제한합니다.
09

현재 범위와 배포 조건

현재 preview는 recoverable engine process failure를 대상으로 하며 GPU, node, multi-node failure는 다루지 않고 기존 Kubernetes rescheduling에 맡깁니다. 배포에는 Kubernetes 1.34 이상, Dynamic Resource Allocation 활성화, NVIDIA GPU DRA driver 설치가 필요합니다. vLLM이 primary supported backend이고, Dynamo Snapshot을 함께 구성하면 shadow 초기화와 serving 간 메모리 경쟁을 줄일 수 있습니다. promoted shadow가 빈 KV cache로 시작하는 탓에 cutover 직후 TTFT가 약간 증가하며, prefix-cache index와 cache memory를 함께 넘기는 기능은 아직 개발 중입니다. 구현은 앞으로 안정화와 지원 workload 확대를 거쳐 단계적으로 배포될 예정이며, 사용자는 Kubernetes quickstart와 vLLM failover example을 통해 시험할 수 있습니다.

용어 해설

Shadow Engine Recovery
활성 LLM 추론 엔진과 같은 GPU에 미리 초기화한 대기 엔진을 유지해 프로세스 장애 때 즉시 트래픽을 넘기는 복구 방식입니다. 가중치와 CUDA 초기화 상태를 재사용해 cold restart의 장시간 재로딩을 피하는 것이 핵심입니다.
GPU 메모리 서비스(GPU Memory Service)
추론 엔진 프로세스와 별도로 GPU 물리 메모리 영역의 수명을 관리하는 NVIDIA Dynamo 구성 요소입니다. 여러 엔진이 동일한 HBM 가중치를 각자의 CUDA 가상 주소에 매핑하므로 프로세스가 종료돼도 가중치를 유지할 수 있습니다.
KV 캐시(KV cache)
LLM이 이전 토큰의 Key와 Value를 저장해 긴 문맥을 다시 계산하지 않도록 하는 메모리 영역입니다. 현재 Shadow Engine Recovery에서는 활성 엔진만 물리적으로 보유하며, 대기 엔진이 승격될 때 새로 materialize하므로 전환 직후 TTFT가 잠시 증가합니다.
CUDA 그래프(CUDA graphs)
GPU 연산 그래프를 미리 캡처해 반복 실행 시 커널 실행 오버헤드를 줄이는 CUDA 기능입니다. 캡처 시점의 가상 주소에 묶이므로 기존 프로세스에서 새 프로세스로 이전하기 어렵고, shadow engine이 시작할 때 미리 캡처해 둡니다.
Dynamic Resource Allocation
Kubernetes에서 GPU 같은 자원을 동적으로 할당하고 워크로드에 연결하는 기능입니다. NVIDIA Dynamo의 현재 Shadow Engine Recovery preview는 Kubernetes 1.34 이상, DRA 활성화, NVIDIA GPU DRA driver 설치를 배포 조건으로 요구합니다.
Cold restart
장애 난 추론 엔진을 처음부터 다시 시작하는 복구 절차입니다. 저장소에서 가중치를 HBM으로 로드하고 KV cache 크기를 정한 뒤 autotune과 CUDA graph 캡처를 반복하므로 대형 LLM에서는 serving capacity 회복까지 수분이 걸릴 수 있습니다.

기술

  • NVIDIA Dynamo
  • GPU Memory Service (GMS)
  • CUDA Virtual Memory Management API
  • vLLM
  • SGLang
  • NVIDIA TensorRT-LLM
  • NCCL
  • NIXL
  • CUDA graphs
  • Kubernetes
  • Dynamic Resource Allocation
  • NVIDIA GPU DRA driver
  • Dynamo Snapshot
  • GLM-5.2
  • NVFP4
  • FP8 KV cache

언급된 리소스

AI 분석 전체 내용 보기

AI 요약 · 북마크 · 개인 피드 설정 — 무료

출처 · 인용 안내

수집 2026. 08. 26.출처 타입 WEB

인용 시 "요약 출처: AI Trends (aitrends.kr)"를 표기하고, 사실 확인은 원문 보기 기준으로 진행해 주세요. 자세한 기준은 운영 정책을 참고해 주세요.