본문 바로가기

12. NVIDIA Dynamo와 llm-d — 서빙 층의 control/data path와 엔진 경계

이 장의 핵심 질문
  • "서빙 층(serving layer)"은 엔진 위에서 정확히 무엇을 더 하는가?
  • 서빙 층의 control path(제어 경로)data path(데이터 경로) 는 왜 나눠 봐야 하는가?
  • Dynamo·llm-d 같은 서빙 층과 엔진(11장)의 경계는 어디인가?

앞 장과의 연결 — 11장에서 엔진 층(단일 실행 단위)과 서빙 층(분산 조율)을 분리하고, 서빙 층은 engine-agnostic하다고 예고했다. 이 장은 그 서빙 층을 정면으로 다룬다. 앞 묶음의 PD 분리(07)·KV 계층(08)·세 제어 루프(09)가 서빙 층에서 하나의 소프트웨어로 구현됨을 확인한다.

먼저: 서빙 층이 뭔가요?

서빙 층(serving layer) 은 여러 엔진 인스턴스(11장) 위에 얹혀, 분산 추론을 조율하는 소프트웨어 계층이다. 엔진이 "한 실행 단위의 forward pass를 빠르게"라면, 서빙 층은 "여러 실행 단위를 어떻게 배치·연결·조율"을 담당한다.

운영체제 비유가 잘 통한다: 엔진은 "한 프로세스를 빠르게 돌리는 것"이고, 서빙 층은 "여러 프로세스에 자원을 스케줄링하고 메모리를 관리하고 데이터를 옮기는 OS"에 가깝다. 실제로 Dynamo 공식 문서도 스스로를 "스케줄링·메모리 관리·데이터 전송의 기반을 까는, OS 같은 접근"으로 설명한다.

서빙 층이 하는 일은 앞 묶음에서 이미 개념으로 다뤘다. 서빙 층은 그것들을 묶어 구현한다:

  • PD 분리 오케스트레이션(07장) — prefill·decode 워커를 나누고 조율
  • KV-aware 라우팅(08·09장) — KV 캐시 위치를 알고 요청을 보냄
  • 다중 tier KV 관리(08장) — GPU·CPU·SSD·오브젝트 스토리지에 KV 배치
  • 오토스케일링(09장) — 워커 개수 조절

control path와 data path — 서빙 층의 두 경로

서빙 층을 이해하는 핵심 기율은 제어(control)와 데이터(data)의 두 경로를 나누는 것이다. 이 둘은 흐르는 것도, 성능 관심사도 다르다.

  • control path(제어 경로) — "무엇을 어디로 보낼지 결정"이 흐르는 경로. 요청 접수, 워커 선택(라우팅), 스케줄링 결정, 스케일링 신호. 결정과 메타데이터가 오간다.
  • data path(데이터 경로) — 실제 무거운 데이터가 흐르는 경로. 대표적으로 KV 캐시 전송(P→D, 07·08장). 대역폭·지연이 성능을 좌우한다.

일상 비유: 택배 회사에서 "이 물건을 어느 지점에서 어느 지점으로"를 정하는 관제 시스템(control path)과, 실제 트럭이 물건을 나르는 도로(data path)는 다르다. 관제가 빨라도 도로가 막히면 배송이 느리고, 도로가 뚫려도 관제가 엉키면 엉뚱한 곳으로 간다.

flowchart TB
    REQ["요청 (OpenAI 호환 API)"] --> FE["Frontend / API 서버<br/>(control)"]
    FE --> ROUTER["Router<br/>워커 선택·KV-aware 라우팅<br/>(control)"]
    ROUTER -->|"제어: 어느 워커로"| P["Prefill 워커<br/>(엔진 인스턴스)"]
    ROUTER -->|"제어: 어느 워커로"| D["Decode 워커<br/>(엔진 인스턴스)"]
    P ==>|"데이터: KV 전송<br/>(data path)"| D
    D --> OUT["토큰 스트림"]

    KVMGR["KV Cache Manager<br/>다중 tier (GPU/CPU/SSD/오브젝트)<br/>(control + data)"] -.->|"배치·evict 결정"| P
    KVMGR -.-> D

    classDef req fill:#fff3c4,stroke:#d4a017,color:#000
    classDef ctrl fill:#c4f1f4,stroke:#0891b2,color:#000
    classDef eng fill:#cfe2ff,stroke:#2563eb,color:#000
    classDef data fill:#ffe0b2,stroke:#e07b00,color:#000
    class REQ,OUT req
    class FE,ROUTER ctrl
    class P,D eng
    class KVMGR data
📌 핵심 — 두 경로를 나눠 진단하라 — 성능 문제를 만나면 "control path 문제인가 data path 문제인가"를 먼저 물어라. 라우팅 결정이 나쁘면 control path(잘못된 워커 선택), KV 전송이 느리면 data path(대역폭 부족) 문제다. 둘의 해법이 다르다: control은 라우팅·스케줄링 개선, data는 인터커넥트·전송 라이브러리·KV tier 개선.
⚠️ 경계 혼동 주의 — "라우팅이 느리다"의 두 뜻 — "라우팅 때문에 느리다"는 (a) 라우팅 결정이 나빠 엉뚱한/과부하 워커로 보냈거나(control), (b) 결정은 맞지만 그 워커로의 데이터 전송이 느린(data) 것일 수 있다. 서로 다른 경로의 문제를 "라우팅"으로 뭉뚱그리면 오진한다.

두 서빙 층 — Dynamo와 llm-d

NVIDIA Dynamo — engine-agnostic 시스템 레이어

Dynamo는 여러 엔진 위에 얹히는 오픈소스 분산 추론 프레임워크로, 스스로를 "엔진 위의 시스템 레벨 최적화 계층"으로 규정한다. 핵심 성질:

  • engine-agnostic — vLLM·SGLang·TensorRT-LLM 위에서 동작하며, 엔진을 갈아 끼워도 서빙 인프라를 바꾸지 않는다(11장의 층 분리가 여기서 확인된다).
  • 세 핵심 기법의 조합 — 문서가 밝히는 정체성은 (1) Disaggregated Serving(PD 분리, 07장), (2) KV Cache-Aware Routing(KV 위치를 아는 라우팅, 불필요한 재계산 제거), (3) KV Cache Offloading(GPU·CPU·SSD·오브젝트 스토리지 등 다중 tier KV, 08장). 각각 단독으로도 이득이 있고 함께 쓰면 복합 이득이라고 설명한다.
  • NIXL(데이터 경로) — KV 캐시를 워커 사이로 옮기는 전용 데이터 전송 라이브러리. NVLink·InfiniBand 등 가용 전송을 골라 GPU-to-GPU 전송한다. 이것이 Dynamo의 data path 핵심이다.
  • 모듈러 채택 — 컴포넌트(예: KV-aware 라우터만)를 따로 도입할 수 있다.
  • Rust(성능)와 Python(확장성)으로 구현된 오픈소스이며, 범용 모델 서버(구세대 Triton)의 후속으로 자리매김한다고 설명된다.

llm-d — vLLM 기반 분산 추론 플랫폼

llm-d는 vLLM을 확장한 플랫폼으로, prefill과 decode를 노드별로 분리하는 분산 추론을 제공한다. 그 스케줄러는 KV 캐시 상태·SLA·시스템 부하를 보고 워크로드 배치를 결정한다(앞 묶음의 세 제어 루프·SLO가 스케줄러 입력으로 들어간 형태). 다만 vLLM 기반이라는 토대에서 오는 제약(예: 노드당 모델 관련 제약)이 있다고 일부 자료가 지적한다.

🔬 증거 읽기 — 서빙 층 근거표 (확인일 2026-07-20)
항목내용출처 등급 · 주장 유형canonical URL · 확인일
Dynamo가 엔진 위 시스템 레이어(disaggregated serving·KV-aware routing·KV offloading의 조합)아키텍처PRIMARY · vendor-reporteddocs.nvidia.com/dynamo (Introduction/Overview), 2026-07-20
Dynamo가 engine-agnostic(vLLM·SGLang·TensorRT-LLM 위에서 동작)아키텍처PRIMARY · vendor-reporteddocs.nvidia.com/dynamo, 2026-07-20
NIXL이 KV를 GPU-to-GPU로 옮기는 데이터 전송 라이브러리(NVLink·IB 등 선택)아키텍처PRIMARY · vendor-reporteddocs.nvidia.com/dynamo, github.com/ai-dynamo/nixl, 2026-07-20
Dynamo가 다중 tier(GPU·CPU·SSD·오브젝트 스토리지)에 KV 저장·evict아키텍처PRIMARY · vendor-reporteddocs.nvidia.com/dynamo (architecture), 2026-07-20
llm-d가 vLLM 확장 분산 추론 플랫폼, 스케줄러가 KV·SLA·부하 기반 배치아키텍처PRIMARY(llm-d) + SECONDARY(학술 정리) · vendor-reported/inferredllm-d 프로젝트 자료·학술 정리, 2026-07-20
conditions — 위는 아키텍처·기능의 존재에 대한 vendor-reported 진술이다. does-not-support — "Dynamo가 처리량을 2~3배/50배 높인다" 같은 2차·벤더 수치는 특정 하드웨어(예: 특정 랙 시스템)·모델·워크로드 조건의 산물이며 이 안내서는 그런 배수를 일반값으로 옮기지 않는다. 컴포넌트 명칭·버전은 빠르게 갱신되므로 canonical URL에서 재확인하라.
⚠️ 경계 혼동 주의 — 벤더 성능 배수 — 서빙 층 자료에는 "2~3배 처리량", "특정 랙에서 MoE 50배" 같은 수치가 등장한다. 이들은 특정 조건(하드웨어 세대·모델·워크로드·비교 대상)의 산물이다. 배수의 분모(무엇 대비) 와 조건을 확인하지 않으면 오해한다(15장). vendor-reported 배수는 owner 보고이지 독립 재현이 아니다(출처 등급 유의).

엔진 경계 — 서빙 층은 어디서 멈추는가

서빙 층과 엔진의 경계를 명확히 하자.

관심사엔진 층(11장)서빙 층(이 장)
단위하나의 (다중 device) 실행 단위여러 실행 단위의 fleet
대표 일KV 관리(Paged/Radix), 배칭, 커널PD 오케스트레이션, KV-aware 라우팅, 다중 tier KV, 오토스케일링
forward pass담당담당 안 함(엔진에 위임)
워커 간 조율담당 안 함담당
교체 가능성서빙 층이 engine-agnostic이면 갈아 끼움엔진을 워커로 배치

경계의 실무적 의미: KV 전송 자체는 서빙 층의 data path(NIXL 등)가 하지만, 한 워커 안에서 KV를 어떻게 페이지로 관리하는가는 엔진(PagedAttention)의 몫이다. 요청→워커 라우팅은 서빙 층이지만, 모델 안 토큰→전문가 라우팅(MoE) 은 엔진 안이다(05장). 같은 "KV"·"라우팅"이라는 단어가 두 층에서 다른 것을 가리킨다.

📌 핵심 — 같은 단어, 다른 층 — "KV 관리", "라우팅", "배치(placement)"는 엔진 층과 서빙 층 양쪽에 등장하지만 대상이 다르다. 문서를 읽을 때 "이 KV/라우팅은 한 워커 안의 것인가, 워커 사이의 것인가"를 먼저 확인하라. 이 층위 구분이 이 묶음의 반복 기율이다.

배포에 서빙 층을 얹다

배포 D6 — 서빙 층 도입 — 앞에서 엔진을 고른 배포의 팀은, 여러 엔진 워커를 조율할 서빙 층을 도입한다. 서빙 층은 control path(요청 접수·KV-aware 라우팅·스케줄링)와 data path(NIXL 등 KV 전송)를 나눠 관리하고, 다중 tier KV·오토스케일링으로 앞 묶음의 개념을 하나로 묶어 구현한다. 서빙 층이 engine-agnostic이면 엔진 선택과 독립적으로 조율 인프라를 유지할 수 있다. 이제 배포는 "엔진 + 서빙 층 + SLO 계약"을 갖춘 분산 서비스다.

이 장에서 배운 것

  • 서빙 층은 여러 엔진 인스턴스 위에서 분산 추론을 조율하는 계층이다(OS 비유). 앞 묶음의 PD 분리·KV 계층·라우팅·오토스케일링을 하나로 구현한다.
  • 서빙 층은 control path(결정·메타데이터)data path(KV 전송 등 무거운 데이터) 로 나눠 봐야 한다. 성능 문제는 먼저 어느 경로인지 진단한다.
  • Dynamo는 engine-agnostic 시스템 레이어로 disaggregated serving·KV-aware routing·KV offloading을 조합하고, NIXL이 data path(KV 전송)를 담당한다. llm-d는 vLLM 확장 플랫폼으로 KV·SLA·부하 기반 스케줄링을 한다.
  • 벤더의 성능 배수("2~3배" 등)는 특정 조건의 산물이며 분모·조건 없이 옮기지 않는다(vendor-reported ≠ 독립 재현).
  • 엔진 층과 서빙 층은 경계가 있다. 같은 단어(KV·라우팅)가 두 층에서 다른 것을 가리키므로, "한 워커 안인가 워커 사이인가"를 항상 확인한다.

🔎 이 장의 '지지하지 않는 결론' + 'unknown으로 남겨야 할 것'

  • 지지하지 않는 결론 — "서빙 층 X가 처리량을 N배 높인다"는 일반 명제로는 지지되지 않는다. 배수는 하드웨어·모델·워크로드·비교 대상 조건의 산물이며, vendor-reported는 독립 재현이 아니다.
  • unknown으로 남길 것 — 특정 배포에서의 서빙 층 실제 이득·컴포넌트 구성·최신 버전은 그 조건·측정 없이는 unknown. 벤더 배수의 원 조건이 불명이면 그대로 둔다.

✍️ 확인 문제

  1. 서빙 층의 control path와 data path를 각각 정의하고, "KV 전송이 느려 decode 워커가 논다"는 문제가 어느 경로의 문제인지, 그 해법 방향(라우팅 개선 vs 인터커넥트·전송 개선)이 왜 달라지는지 설명하라.
  1. (경계 혼동 유형) "우리 시스템의 KV 관리가 문제다"라는 문장에서, 이것이 엔진 층(PagedAttention 등 한 워커 안)의 문제인지 서빙 층(다중 tier KV·NIXL 전송 등 워커 사이)의 문제인지 어떻게 구분하는가? 두 경우의 해법이 어떻게 다른가?
  1. (증거 유형) 어떤 자료가 "Dynamo로 처리량 2~3배"라고 한다. 이 배수를 자기 배포에 기대하기 전에 반드시 확인해야 할 것(분모·하드웨어·모델·워크로드·비교 대상)을 들고, "vendor-reported이지 독립 재현이 아님"이 왜 중요한지 말하라.
다음 장에서는 실제 공개 배포 사례(DeepSeek·Kimi 등)를 읽는다. 보고서가 밝힌 것(explicit)밝히지 않은 것(unknown) 을 분리하고, owner-reported 경계를 보존하는 훈련이 초점이다.
다음13. DeepSeek·Kimi 공개 배포 사례 읽기 — explicit·inferred·unknown 분리