그래프를 선언하면 부품들이 나눠 맡는다
한 줄 요약
Dynamo 는 추론 엔진(vLLM·SGLang·TensorRT-LLM) 위에 라우터·플래너·KV 캐시 전송을 얹은 서빙 프레임워크이고, 쿠버네티스에서는 「오퍼레이터와 CRD」 로 올라갑니다. 사용자는 DynamoGraphDeployment(DGD) 하나에 「프런트엔드 몇 개, 프리필 워커 몇 개, 디코드 워커 몇 개, 워커 하나는 노드 몇 대짜리」 를 적고, 여러 노드에 걸친 워커는 앞 모듈들에서 본 부품(Grove 와 KAI, 또는 LWS 와 Volcano)이 묶어 배치합니다. 이 모듈의 구조 설명은 Dynamo 1.6.0 문서 기준이고, GPU 없이 도는 Mocker 경로만 실험 VM 에서 직접 돌려 보았습니다.
왜 이게 필요했나
LLM 서빙을 크게 키우면 세 가지가 동시에 문제가 됩니다. 요청을 어느 워커로 보낼지(앞부분이 같은 요청은 KV 캐시가 남은 워커로), 프롬프트를 읽는 단계(프리필)와 토큰을 내는 단계(디코드)를 따로 늘릴지, 그리고 모델 하나가 노드 여러 대에 걸칠 때 그 묶음을 어떻게 배치할지입니다. 앞의 둘은 LLM 서빙 코스에서 원리를 계산해 보았습니다. 세 번째가 이 코스가 지금까지 다룬 영역입니다.
엔진만 Deployment 로 띄우면 이 셋을 사람이 맞춰야 합니다. 라우터 설정, 프리필과 디코드의 비율, 멀티 노드 워커의 갱 배치, 그리고 그 사이의 RDMA 네트워크까지. Dynamo 의 쿠버네티스 경로는 이것을 「그래프 하나」 로 선언하게 하고, 오퍼레이터가 아래 부품들에 나눠 맡깁니다.
어떻게 동작하나
설치되는 것과 사용자가 쓰는 것을 나눠 보면 이렇습니다(문서 기준).
Dynamo Platform 차트 NGC 의 dynamo-platform-<판>.tgz. 오퍼레이터·CRD·NATS 를 올린다
전제 NVIDIA 는 GPU Operator, Intel 은 DRA 드라이버(resource.k8s.io/v1 을 오퍼레이터가 스스로 알아챈다)
DGD components 목록. type 이 frontend · worker · prefill · decode
multinode.nodeCount 로 워커 하나가 노드 몇 대인지, roles 로 리더·워커 파드 틀(1.6.0 부터)
DGDR 모델과 SLA 를 적으면 프로파일러로 구성을 찾아 DGD 를 만들어 준다
Planner 지표를 보고 프리필·디코드 워커 수를 조정한다(Prometheus 필요)
멀티 노드 워커의 배치는 두 길입니다.
Grove + KAI-Scheduler 기본 권장. Grove 가 역할별 파드 묶음(PodClique)을 만들고 KAI 가 위상·갱 배치를 한다
LWS + Volcano 대안. LWS 가 리더·워커 그룹을 만들고 Volcano 가 갱 배치를 한다
오퍼레이터는 멀티 노드 배포에서 Grove 도 LWS 도 없으면 오류를 냅니다. 판 맞추기도 문서가 표로 요구합니다. Dynamo 1.6.x 는 KAI-Scheduler v0.17.0 이상, Grove v0.1.0-alpha.14 이상입니다. 이 코스의 KAI 실습은 v0.18.6 이라 조건을 만족합니다.
GPU 없이 구조를 시험하는 길도 있습니다. 「Mocker」 는 GPU 를 요청하지 않는 가짜 백엔드로, 워커를 등록하고 KV 이벤트를 내며 가짜 응답을 돌려줍니다. DGD 의 워커 명령을 python3 -m dynamo.mocker 로 바꾸면 프런트엔드·라우터·워커 수명 주기를 CPU 만으로 돌려 볼 수 있습니다. 성능 결론은 실제 GPU 에서 다시 확인하라고 문서가 못박습니다.
이 코스를 만들며 실험 VM(4 vCPU·4GiB, k3s v1.36.5)에서 그대로 해 보았습니다.
dynamo-platform 1.6.0 설치 26초. 기본값으로는 오퍼레이터 파드 하나뿐(NATS·etcd 는 install: false)
CRD DynamoGraphDeployment·DynamoComponentDeployment·DGDR·DynamoModel·DynamoWorkerMetadata 등
Mocker DGD(프런트엔드 + 디코드) 56초 만에 두 파드 Ready. 플래너 이미지(731MB)를 받는 데 35초
서비스 발견 쿠버네티스 API(DynamoWorkerMetadata CR)로 워커를 찾았다
요청 /v1/models 에 Qwen/Qwen3-0.6B, /v1/chat/completions 가 토큰 16개짜리 가짜 응답
메모리 프런트엔드 253Mi · 디코드 101Mi · 오퍼레이터 29Mi
설치 문서는 확인 단계에서 「dynamo-operator-* 와 nats-* 파드가 모두 Running」 을 기대하라고 적지만, 이 판의 차트 기본값은 NATS 를 설치하지 않습니다(요청·이벤트 경로가 기본으로 TCP·ZMQ 를 쓰기 때문이라고 차트 주석이 설명합니다). 문서와 기본값이 어긋난 자리라 기여 후보로 정리해 두었습니다.
현장에서 만나는 모습
- 「분리 서빙에는 RDMA 가 사실상 필수입니다.」 문서는 RDMA 없이 프리필과 디코드를 나누면 TCP 로 떨어지고, 첫 토큰까지 약 98초(RDMA 면 200~500ms)가 걸린다고 적습니다. 분리 서빙을 켜기 전에 네트워크 층을 먼저 봐야 합니다.
- 「모델 저장소를 먼저 정하세요.」 파드마다 수십 GB 가중치를 따로 받으면 시간도 Hugging Face 의 속도 제한도 감당하기 어렵습니다. 공유 스토리지는 오퍼레이터가 강제하지 않는 운영 판단입니다.
- 「판을 함께 올리세요.」 Grove 의 API 가 아직 바뀌는 중이라 Dynamo 와 Grove 를 같은 박자로 올리라는 경고가 있습니다. 판이 어긋나면 조용히 깨지는 종류의 문제입니다.
- 「문서의 예시 판이 늦게 따라올 때가 있습니다.」 1.6.0 의 설치 문서 예시는
RELEASE_VERSION=1.2.1로 남아 있었습니다. 판 번호는 릴리스 페이지에서 직접 고르세요.
English corner
A DynamoGraphDeployment describes the graph; Grove and KAI decide where each node of it runs.
disaggregated serving(분리 서빙), prefill·decode, planner 는 Dynamo 문서의 기본 어휘입니다.
다음 퀴즈에서 확인할 것
Dynamo 의 쿠버네티스 경로에서 무엇이 설치되고 무엇을 사용자가 적는지, 멀티 노드 워커가 어느 부품에 기대는지, 그리고 GPU 없이 무엇을 시험할 수 있는지를 확인합니다.