TRENDSHIFT · 2026-05-23 · 24위
NVIDIA Dynamo 딥다이브
— GPU 한 장이 아니라 데이터센터 전체로 LLM을 서빙하는 법
vLLM·SGLang·TensorRT-LLM 위에 얹는 오케스트레이션 레이어. Rust로 빌드된 분산 추론 프레임워크 ai-dynamo/dynamo (6.8k stars · Apache-2.0 · v1.1.1)를 한국어로 처음부터 풀어 봅니다.
1프로젝트 한줄 요약
"GPU 한 장만 있을 때는 필요 없고, 여러 노드를 묶기 시작하면 필요한 것"
한 줄 정의
Dynamo는 추론 엔진을 대체하는 것이 아니라, 추론 엔진 여러 개를 데이터센터 규모로 조율하는 오케스트레이션 레이어다.
vLLM·SGLang·TensorRT-LLM이 GPU 1장(혹은 1노드)에서 모델 1개를 잘 돌리는 데에 집중한다면, Dynamo는 그 위에 올라서서 여러 GPU·여러 노드·여러 모델을 한 시스템처럼 묶어 준다.
Rust로 만든 코어 위에 Python 확장성을 얹은 형태이며, NVIDIA가 직접 만들고 Apache-2.0으로 풀었다.
비유로 이해하기
오케스트라 vs 단독 연주자. vLLM 하나가 바이올린을 잘 켜는 한 명의 연주자라면, Dynamo는 지휘자 + 무대 매니저 + 음향 엔지니어를 합쳐 놓은 존재다.
"이 곡(요청)은 누구한테 맡기지?" → 지휘 (KV-Aware Routing)
"리허설 단계(prefill)랑 본 연주(decode)는 따로 풀자" → 무대 분리 (Disaggregated Serving)
"악보(KV cache)는 한 번 본 거 또 안 보게 캐싱" → 메모리 매니저 (KVBM)
"객석 만석 되면 연주자 더 부르기" → 자동 스케일링 (Planner)
레포 한 줄 설명은 이렇게 적혀 있다: "A Datacenter Scale Distributed Inference Serving Framework". NVIDIA가 만든 만큼 자사 GPU(B200·GB200·GB300·H100·H200) 최적화가 강하지만, 라이선스는 Apache-2.0이라 누구나 가져다 쓰고 수정할 수 있다.
2왜 지금 주목받는가
"추론 비용이 학습 비용을 넘어선 시대" — 그래서 추론 인프라가 다시 뜨겁다
2026년 LLM 인프라의 패러다임 전환
2024년까지만 해도 LLM의 화두는 "어떻게 잘 학습시키느냐"였다. 하지만 ChatGPT·Claude·Gemini가 일상이 되면서 추론 토큰 양이 학습 토큰 양을 압도하기 시작했다. 모델 하나를 잘 만드는 것보다, 그 모델을 수억 명에게 싸게 빨리 돌리는 것이 진짜 경쟁력이 된 것이다.
용어 풀이
Inference (추론)
학습이 끝난 모델로 실제 답변을 생성하는 단계. 사용자가 ChatGPT에 질문을 던지면 일어나는 일. 학습은 한 번이지만 추론은 사용자가 늘수록 끝없이 늘어남.
경쟁 제품과 무엇이 다른가
| 제품 | 역할 | Dynamo와의 관계 |
| vLLM | 단일 노드 추론 엔진 | Dynamo가 백엔드로 호출 |
| SGLang | 단일 노드 추론 엔진 | Dynamo가 백엔드로 호출 |
| TensorRT-LLM | NVIDIA 단일 노드 추론 엔진 | Dynamo가 백엔드로 호출 |
| Triton Inference Server | 구버전 NVIDIA 서빙 서버 | Dynamo가 사실상 후속작 |
| Ray Serve / KServe | 일반 ML 모델 서빙 | LLM 특화가 약함 → Dynamo가 강함 |
핵심은 Dynamo는 추론 엔진을 만들지 않는다는 점이다. 그래서 vLLM·SGLang·TensorRT-LLM과 경쟁하지 않고 그들의 매니저 역할을 자처한다. "최고의 추론 엔진은 매년 바뀌지만, 그것들을 묶는 방법은 점점 안정될 것"이라는 베팅이다.
벤치마크가 보여주는 충격
| 지표 | 수치 | 상황 |
| 처리량 (GPU당) | 7× 향상 | DeepSeek R1 / GB200 NVL72 / Dynamo 있을 때 vs B200 + Dynamo 없을 때 |
| 모델 시작 시간 | 7× 단축 | ModelExpress weight streaming (DeepSeek-V3 / H200) |
| TTFT (첫 토큰까지 시간) | 2× 단축 | KV-aware 라우팅, Qwen3-Coder 480B (Baseten 측정) |
| SLA 위반 건수 | 80% 감소 | Planner 자동 스케일링, TCO 5% 절감 (Alibaba APSARA 2025) |
| 처리량 신기록 | 750× | DeepSeek-R1 / GB300 NVL72 / InferenceXv2 벤치 |
용어 풀이
TTFT (Time To First Token)
사용자가 메시지를 보낸 직후 첫 글자가 화면에 뜨기까지 걸리는 시간. ChatGPT가 "..." 깜빡이다 글자 나오기 시작하는 그 순간까지의 지연. 보통 100~500ms 이내가 목표.
용어 풀이
SLA (Service Level Agreement)
"우리는 TTFT 200ms 이내, 토큰 간 지연 20ms 이내로 응답한다"처럼 고객에게 약속한 성능 수치. 이걸 못 지키면 환불·계약 해지 사유가 됨.
용어 풀이
TCO (Total Cost of Ownership)
단순 GPU 가격이 아니라 전기료 + 데이터센터 임대료 + 네트워크 비용 + 인력까지 다 합친 진짜 비용. NVIDIA가 자꾸 강조하는 이유 = 그래야 H100·H200·GB200 한 대당 비싼 가격이 정당화됨.
오픈소스 인프라 트렌드의 한 축
2025~2026년 LLM 추론 인프라 오픈소스는 크게 세 갈래로 갈라졌다:
- 엔진 단(單) 노드: vLLM, SGLang, TensorRT-LLM, llama.cpp, MLX
- 오케스트레이션: Dynamo, Ray Serve, KServe, NVIDIA NIM
- 응용 플랫폼: Ollama (로컬), Dify (앱), LiteLLM (라우터)
Dynamo는 가운데 칸의 NVIDIA표 정통 후보다. AWS·Google·Mistral·Moonshot AI(Kimi K2)·Baseten 같은 굵직한 사용처가 이미 붙어 있고, MLPerf 추론 벤치마크 신기록도 Dynamo로 세워졌다.
3기술 스택 전체 지도
Rust 54.5% / Python 30.5% / Go 12.8% — "성능은 Rust, 확장성은 Python, K8s는 Go"
3-1. 언어 구성과 그 이유
| 언어 | 비중 | 맡은 역할 |
| Rust | 54.5% | 코어 런타임, KV 라우터, KVBM(KV Block Manager), 토크나이저. 메모리 안전 + GC 없는 저지연 + Tokio 비동기가 필요한 hot path. |
| Python | 30.5% | Frontend(OpenAI 호환 HTTP 서버), Planner(자동 스케일러), 백엔드 래퍼, 사용자 확장. PyO3/maturin으로 Rust 코어와 결합. |
| Go | 12.8% | Kubernetes Operator(Grove), K8s 리소스 컨트롤러. controller-runtime / kubebuilder 생태계가 Go. |
| Shell·Dockerfile·CUDA | ~1.6% | 빌드 스크립트, 컨테이너 정의, CUDA 커널. |
왜 굳이 3개 언어?
레이어마다 요구사항이 다르기 때문이다. "마이크로초가 중요한 곳은 Rust, 사람이 매일 만지는 곳은 Python, 쿠버네티스가 사는 곳은 Go"라는 합리적 분업.
한 언어로 통일하면 깔끔하지만, KV 라우팅 같은 hot path에 Python을 쓰면 GIL과 GC 때문에 마이크로초 단위 지연이 무너진다. 반대로 Operator를 Rust로 쓰면 controller-runtime 같은 K8s 표준 도구를 못 쓴다.
3-2. 백엔드(추론 엔진) 매트릭스
| 기능 | SGLang | TensorRT-LLM | vLLM |
| Disaggregated Serving | ✅ | ✅ | ✅ |
| KV-Aware Routing | ✅ | ✅ | ✅ |
| SLA-Based Planner | ✅ | ✅ | ✅ |
| KVBM (KV Block Manager) | 🚧 작업 중 | ✅ | ✅ |
| Multimodal (이미지·비디오) | ✅ | ✅ | ✅ |
| Tool Calling (함수 호출) | ✅ | ✅ | ✅ |
세 엔진 모두 사실상 동등하게 지원한다. 사용자는 자기 모델·하드웨어·라이선스 사정에 맞게 고르면 된다. TensorRT-LLM은 NVIDIA GPU 전용이고 빠르지만 컴파일 시간이 길고, vLLM·SGLang은 더 쉽고 멀티 벤더(AMD MI300 등)를 좀 더 본다.
3-3. Rust 크레이트 의존성의 풍경
Cargo.toml의 workspace.dependencies를 보면 Dynamo가 어느 생태계 위에 서 있는지가 한눈에 드러난다.
# 비동기 런타임
tokio = "=1.48.0" # 사실상 Rust 비동기의 표준
async-stream / async-trait # 스트리밍 응답
hyper / axum / tower-http # HTTP 서버
# 메시징·서비스 디스커버리
async-nats = "0.45" # JetStream 메시지 큐
etcd-client = "0.17" # 분산 키-값 저장소
tmq = "0.5" # ZeroMQ 바인딩 (SGLang 통신)
# GPU
cudarc = "0.19.3" # CUDA Rust 바인딩
# 데이터 구조·해싱
blake3 = "1" # KV cache 해시 (충돌 거의 0)
xxhash-rust # 빠른 해시
dashmap / moka # 동시성 맵·캐시
# HF Hub
hf-hub = "0.4.2" # 모델 다운로드 (rustls-tls)
modelexpress-client = "0.3" # 모델 가중치 스트리밍
# 관측 가능성
prometheus / tracing
opentelemetry-otlp # OTel → Tempo/Jaeger 연동
용어 풀이
Tokio
Rust의 사실상 표준 비동기 런타임. Node.js의 이벤트 루프 + 스레드 풀 같은 것. Dynamo의 모든 네트워크 I/O는 Tokio 기반이라 마이크로초 단위 지연이 가능.
용어 풀이
cudarc
Rust에서 CUDA를 직접 호출할 수 있게 해주는 바인딩. "Rust에서 GPU 메모리 잡고 커널 띄우기"가 가능. Dynamo가 KVBM(GPU↔CPU 메모리 이전) 같은 걸 Rust로 짤 수 있는 이유.
3-4. Python 측 의존성
pyproject.toml의 [project.optional-dependencies]는 백엔드별로 분리되어 있다. uv pip install "ai-dynamo[sglang]" 식으로 필요한 것만 골라 깔 수 있다.
- [sglang] — SGLang 추론 엔진
- [vllm] — vLLM 추론 엔진
- [trtllm] — TensorRT-LLM (별도 NVIDIA PyPI 인덱스 필요)
- 코어: 빌드는
maturin(Rust↔Python 브릿지), 패키지 관리는 uv(astral.sh의 초고속 pip 대체)
3-5. 인프라·운영 스택
| 레이어 | 도구 | 역할 |
| 컨테이너 | Docker, NGC (nvcr.io) | SGLang/vLLM/TRT-LLM 런타임 미리 빌드된 이미지를 NGC에서 제공 |
| 오케스트레이션 | Kubernetes + 커스텀 Operator | DynamoGraphDeploymentRequest CRD 한 장으로 배포 |
| K8s 스케줄러 | Grove (자체 Operator) | NVL72 같은 NVLink 토폴로지를 인식해 gang scheduling |
| 서비스 디스커버리 | etcd (선택), K8s EndpointSlice | 워커 노드 등록·발견 |
| 메시징 | NATS JetStream (KV-Aware 라우팅 필수) | 접두사 캐시 이벤트 공유 |
| 관측 | Prometheus + OpenTelemetry (OTLP) | 외부 모니터링 시스템으로 송출 |
| 문서 | Fern + MDX | buildwithfern.com 호스팅 |
| CI | GitHub Actions, CodeRabbit | 자동 코드 리뷰 |
4아키텍처 심화 분석
"prefill과 decode를 따로 푼다" — 이 한 줄이 모든 성능 향상의 출발점
4-1. 큰 그림: 6개 핵심 컴포넌트
┌─────────────────────────────────────────────────────────────────────┐
│ 클라이언트 (OpenAI 호환 SDK) │
└──────────────────────────────┬──────────────────────────────────────┘
│ HTTP /v1/chat/completions
▼
┌─────────────────────────────────────────────────────────────────────┐
│ FRONTEND (Rust + axum) │
│ - OpenAI 호환 HTTP 서버 │
│ - 전처리/검증, 자동 디스커버리 │
└──────────────────────────────┬──────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ KV ROUTER (Rust, lib/kv-router) │
│ - 요청 토큰의 블레이크3 해시 → 어떤 워커가 KV cache 있는지 조회 │
│ - 적합도 점수 = 워커 부하 + 캐시 적중률 │
└──────┬──────────────────────────────────────────────────┬───────────┘
│ "이건 prefill용" "이건 decode용"
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ PREFILL WORKERS │ NIXL/NVLink로 KV │ DECODE WORKERS │
│ (GPU 풀 A) │ cache 전송 → │ (GPU 풀 B) │
│ - vLLM/SGLang/ │ ─────────────────────▶│ - vLLM/SGLang/ │
│ TRT-LLM 인스턴스 │ │ TRT-LLM 인스턴스 │
│ - 긴 입력 한 방에 처리│ │ - 토큰 한 개씩 빠르게 │
└──────┬───────────────┘ └──────┬───────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────────┐
│ KVBM (Rust, lib/kvbm-*) │
│ GPU HBM → CPU RAM → 로컬 SSD → 원격 S3/Azure 4단 계층 캐시 │
│ "한 번 본 KV는 가장 빠른 자리에 캐싱, 안 쓰는 건 천천히 내려보냄" │
└─────────────────────────────────────────────────────────────────────┘
▲
│ 메트릭/이벤트
│
┌─────────────────────────────────────────────────────────────────────┐
│ PLANNER (Python, components/src/dynamo/planner) │
│ - SLA(예: TTFT 200ms) 위반 위험 감지 → prefill/decode 풀 +/- 스케일 │
│ - AIConfigurator로 10K+ 토폴로지 시뮬레이션해 최적 비율 찾음 │
└─────────────────────────────────────────────────────────────────────┘
4-2. 핵심 설계 패턴 1 — Disaggregated Serving (분리 서빙)
전통적인 LLM 추론은 한 GPU가 prefill(입력 처리) → decode(토큰 생성)를 모두 한다. 문제는 두 단계가 GPU를 완전히 다르게 쓴다는 점이다.
| 단계 | 특성 | GPU 사용 패턴 |
| Prefill (입력 처리) | 5천 토큰 한 번에 — 행렬곱 큰 묶음 | 연산(컴퓨트) 바운드 — TFLOPS 다 씀 |
| Decode (토큰 생성) | 토큰 하나씩 — 작은 연산 반복 | 메모리 대역폭 바운드 — HBM 대역폭 다 씀 |
비유로 이해하기
"빵집의 반죽기와 오븐"을 상상해 보자. 반죽기(prefill)는 큰 배치를 한 번에 처리하고, 오븐(decode)은 작은 빵을 계속 구워낸다. 둘이 다른 기계인데도 한 사람이 두 역할을 다 하면 한쪽이 노는 시간이 생긴다.
Dynamo는 GPU를 두 풀로 나눠 "이쪽 GPU는 prefill 전용, 저쪽 GPU는 decode 전용"으로 운영한다. 그리고 prefill이 끝난 KV cache를 NVLink/NIXL로 decode GPU에 직접 전송. 결과 → 두 풀 모두 100%에 가깝게 활용.
4-3. 핵심 설계 패턴 2 — KV-Aware Routing
LLM은 같은 시스템 프롬프트로 시작하는 요청이 많다(예: "당신은 친절한 한국어 어시스턴트입니다..."). 이 부분의 KV cache는 한 번 계산해두면 그대로 재사용 가능한데, 아무 GPU나 골라 보내면 매번 새로 계산해야 한다.
Dynamo의 KV Router는 토큰 prefix를 BLAKE3로 해싱해서, 어느 워커가 그 prefix의 KV를 이미 가지고 있는지 NATS 메시지로 받아 본다. 가지고 있는 워커에게 보내면 prefill 시간이 거의 0이 된다. 그래서 TTFT 2배 단축.
용어 풀이
KV cache (Key-Value cache)
Transformer가 이미 본 토큰들의 attention 계산 결과를 메모리에 저장해둔 것. 매 토큰 생성마다 처음부터 다시 계산하지 않게 해줌. "앞 문장은 이미 외웠으니 새 문장에만 집중하기". 한 요청당 GPU 메모리 수 GB까지 차지.
4-4. 핵심 설계 패턴 3 — KVBM 4단 계층 캐싱
KV cache는 빠르지만 비싸다. GPU HBM은 비싸고 좁아서 긴 컨텍스트나 동시 요청이 많아지면 금방 꽉 찬다. KVBM은 "안 쓰는 KV는 더 싼 곳으로 내려보낸다"는 발상.
| 계층 | 위치 | 접근 시간 | 용량 |
| 1단 | GPU HBM (현재 워커) | ~ns | 수십 GB |
| 2단 | CPU RAM (같은 노드) | ~µs | 수백 GB |
| 3단 | 로컬 NVMe SSD | ~10µs | 수 TB |
| 4단 | 원격 S3/Azure Blob | ~ms | 수십 PB |
OS의 페이지 캐시·CPU 캐시 계층 구조와 똑같은 발상을 KV cache에 적용한 것이다. lib/kvbm-* 크레이트 시리즈가 이걸 구현한다: kvbm-engine(코어), kvbm-kernels(CUDA 커널), kvbm-logical(논리 계층), kvbm-physical(물리 계층), kvbm-consolidator(통합).
4-5. 핵심 설계 패턴 4 — SLA-Based Planner
워크로드는 시시각각 변한다. 점심 시간에 폭증, 새벽에 한산. Planner는 Prometheus 메트릭(현재 TTFT, ITL, queue depth)을 보고 "prefill 워커 1개 더 띄울까? decode 줄일까?"를 자동 판단한다.
핵심은 AIConfigurator가 미리 10,000개 이상의 토폴로지 조합을 시뮬레이션해 두는 것. 실제 GPU를 안 태워보고도 "이 워크로드에는 prefill 4 + decode 8이 최적"이라는 답을 미리 안다.
4-6. 핵심 설계 패턴 5 — ModelExpress + Grove
- ModelExpress: 새 워커를 띄울 때 모델 가중치를 HuggingFace에서 매번 다운받지 않고, 이미 가중치를 가진 GPU에서 NVLink/NIXL로 GPU↔GPU 직접 스트리밍. 7× 더 빠른 cold start.
- Grove: GB200 NVL72 같은 시스템에서는 GPU 72개가 NVLink 도메인으로 묶여 있다. K8s 기본 스케줄러는 그걸 모른다. Grove Operator는 "이 워크로드는 같은 NVLink 도메인에 묶어줘"라고 알려주는 토폴로지-aware gang scheduling을 한다.
용어 풀이
NIXL (NVIDIA Inference eXchange Library)
NVIDIA가 만든 GPU 간 데이터 전송 라이브러리. RDMA, NVLink, InfiniBand 등을 추상화. "여러 GPU 간 메모리 직접 복사"를 한 줄 API로 가능하게 함. Dynamo가 prefill→decode KV 전송, ModelExpress 가중치 스트리밍에 사용.
용어 풀이
NVL72
NVIDIA Blackwell 세대의 랙 단위 시스템. GPU 72개가 한 NVLink 도메인으로 묶여 있어 마치 거대한 단일 GPU처럼 동작. DeepSeek R1 같은 대형 모델 추론의 표준 단위로 자리잡는 중.
5디렉토리 구조 해부
"Rust 워크스페이스 + Python 컴포넌트 + Go 오퍼레이터"의 3축 구조
ai-dynamo/dynamo/
├── Cargo.toml # Rust 워크스페이스 루트 (26개 멤버)
├── pyproject.toml # Python 패키지 (ai-dynamo) + maturin 빌드
├── rust-toolchain.toml # Rust 2024 edition 핀
│
├── lib/ # ◀ Rust 코어 (54.5%)
│ ├── runtime/ # 런타임 (Tokio 기반 비동기 서비스)
│ ├── llm/ # LLM 추론 추상화 + OpenAI 호환 API 생성
│ ├── tokenizers/ # 토크나이저 (HF tokenizers + fastokens)
│ ├── tokens/ # 토큰 처리 유틸
│ ├── kv-hashing/ # BLAKE3 기반 KV cache 해시
│ ├── kv-router/ # KV-Aware 라우터 (핵심 hot path)
│ ├── kvbm-common/ # KVBM 공통 타입
│ ├── kvbm-config/ # KVBM 설정
│ ├── kvbm-engine/ # KVBM 코어 엔진
│ ├── kvbm-kernels/ # CUDA 커널 (Rust + CUDA 혼합)
│ ├── kvbm-logical/ # 논리 KV 블록 추상화
│ ├── kvbm-physical/ # 물리 메모리 매핑
│ ├── kvbm-consolidator/ # KVBM 통합 관리
│ ├── memory/ # 메모리 관리 (CPU/GPU 풀)
│ ├── mocker/ # 백엔드 mock (테스트용)
│ ├── protocols/ # gRPC/HTTP 프로토콜 정의
│ ├── parsers/ # 요청 파서
│ ├── bench/ # 벤치마크 도구
│ ├── data-gen/ # 합성 데이터 생성
│ ├── backend-common/ # 백엔드 공통 인터페이스
│ ├── gpu_memory_service/ # GPU 메모리 서비스 (별도 Python 패키지)
│ └── bindings/
│ ├── c/ # C ABI 바인딩
│ └── python/codegen/ # PyO3 Python 바인딩
│
├── components/ # ◀ Python 컴포넌트 (30.5%)
│ └── src/dynamo/
│ ├── frontend/ # OpenAI 호환 HTTP 서버
│ ├── planner/ # SLA 자동 스케일러
│ ├── vllm/ # vLLM 백엔드 래퍼
│ ├── sglang/ # SGLang 백엔드 래퍼
│ └── trtllm/ # TensorRT-LLM 백엔드 래퍼
│
├── deploy/ # ◀ Go (12.8%) — K8s 오퍼레이터
│ └── operator/ # DynamoGraphDeployment* CRD 컨트롤러
│
├── recipes/ # ◀ 모델별 배포 레시피 (YAML)
│ ├── deepseek-r1/ # DeepSeek R1 (SGLang/TRT-LLM 분리)
│ ├── deepseek-v4/ # Day-0 DeepSeek V4 (vLLM/SGLang)
│ ├── llama-3-70b/ # Llama 3 70B (vLLM aggregated)
│ └── qwen3-32b-fp8/ # Qwen3 32B FP8 (TRT-LLM)
│
├── examples/ # ◀ 실행 예제
│ ├── backends/ # 엔진별 launch/deploy 스크립트
│ └── deployments/EKS, GKE/ # 클라우드별 가이드
│
├── benchmarks/ # AIPerf 벤치마크 시나리오
├── container/ # Dockerfile (sglang/vllm/trtllm-runtime)
├── docs/ # Fern 마크다운 문서
├── fern/ # Fern CLI 설정
├── tests/ # 통합 테스트
│
├── .agents/skills/ # ◀ Claude Code Agent Skills
│ └── dynamo-docs/ # 문서 자동화 스킬
├── .claude/ # ◀ Claude Code 설정 (서브에이전트, 슬래시 커맨드)
├── .cargo/ # Cargo 설정
├── .devcontainer/ # VSCode/Cursor 개발 환경
├── .github/ # Actions, 이슈 템플릿
│
└── ATTRIBUTIONS-{Go,Python,Rust}.md # 의존성 라이선스 명시
학습 관점
"여기부터 읽으면 빠르다" 추천 순서
1) README.md + docs/getting-started/quickstart.mdx → 큰 그림
2) lib/kv-router/src/lib.rs → KV-Aware 라우팅 알고리즘
3) components/src/dynamo/frontend/ → HTTP API 진입점
4) recipes/deepseek-r1/sglang/ → 실전 분리 서빙 YAML
5) lib/kvbm-engine/src/lib.rs → 4단 계층 캐싱 코어
6기술별 학습 포인트
Dynamo는 "여러 모던 기술 스택의 집합소" — 하나만 봐도 본전
6-1. Rust로 인프라 짜기
Dynamo는 Rust로 짠 진지한 분산 시스템의 좋은 표본이다. 다음을 직접 읽을 수 있다:
- Tokio 비동기 패턴:
async/await, channels, select!, JoinHandle 관리
- axum HTTP 서버: 라우팅, 미들웨어, OpenAPI 자동 생성
- maturin + PyO3: Rust 구조체를 Python에서 그대로 받기
- workspace 분할: 22개 크레이트로 책임 분리, 컴파일 캐시 활용
- tracing + OpenTelemetry: 분산 트레이싱을 Rust 코드에 어떻게 박는가
실습 아이디어
lib/kv-router에서 BLAKE3 해시 → 워커 매칭 함수만 따로 떼서 작은 데모로 만들어 보기. cargo new로 빈 프로젝트 만들고 워커 노드 mock 3개를 띄워 같은 prompt 보냈을 때 어떻게 같은 워커로 라우팅되는지 확인.
6-2. LLM 추론 엔진 이해하기
vLLM·SGLang·TensorRT-LLM 셋 다 Dynamo 백엔드로 등장한다. 각각 한 번씩 직접 띄워보면:
- vLLM: PagedAttention, continuous batching의 원조
- SGLang: RadixAttention(prefix 트리 캐시), 빠른 JSON 디코딩
- TensorRT-LLM: NVIDIA 컴파일 최적화의 끝판왕, FP8/FP4 양자화
Dynamo 추상화 덕분에 같은 API로 백엔드만 바꿔가며 비교 가능. "세 엔진의 강점/약점을 표로 정리"는 면접에서도 강력한 카드.
6-3. KV cache 메커닉스
모든 LLM 추론 최적화는 KV cache로 통한다. Dynamo를 공부하면 자연스럽게 알게 되는 것들:
- 왜 GPU 메모리의 절반 이상을 KV가 먹는가
- PagedAttention의 페이지 단위 관리
- Prefix sharing이 왜 그렇게 큰 이득인가
- 오프로딩(GPU→CPU→SSD)의 트레이드오프
- FP8/INT4 KV 양자화로 메모리 절반 줄이기
6-4. Kubernetes Operator 패턴
deploy/operator/의 Go 코드는 K8s Operator를 처음 배우기에 좋은 예시다.
- CRD(Custom Resource Definition):
DynamoGraphDeploymentRequest 같은 자기만의 K8s 리소스 정의
- Reconciler 루프: "원하는 상태"와 "실제 상태"의 차이를 메우는 무한 루프
- controller-runtime: kubebuilder가 만들어내는 표준 골격
- Operator SDK 패턴: Finalizers, OwnerReferences, Status 서브리소스
6-5. 분산 시스템 기본기
- etcd: Raft 기반 분산 KV 저장소. 서비스 디스커버리에 사용
- NATS JetStream: 가벼운 메시지 큐, KV 이벤트 broadcasting
- Service Mesh 없이도 되는 이유: 인프라가 GPU 노드 한정이라 단순 TCP면 충분
- Health Check + Request Migration: 워커 죽어도 사용자 요청은 안 죽게 하는 트릭
6-6. 관측 가능성 (Observability)
Prometheus + OpenTelemetry 조합은 모던 SRE의 표준. Dynamo는 둘 다 쓴다.
- tracing crate: Rust 안에서 span 만들기 → OpenTelemetry로 export
- Grafana 대시보드: TTFT P50/P95/P99, queue depth, GPU 활용률
- NVTX: NVIDIA Nsight 프로파일러에 마커 박기 (cargo profile 옵션)
7하드웨어·시스템 요구사항
"GPU가 있어야 의미가 있는 프로젝트" — 그래도 작게는 RTX 3090 한 장으로도 따라가 볼 수 있다
최소 ~ 권장 사양
| 시나리오 | GPU | RAM | 실행 가능 여부 |
| 로컬 학습 (Qwen3-0.6B) | RTX 3090/4090 (24GB) | 32GB+ | ✅ 단일 노드 quick start |
| 중급 모델 (Llama 8B FP8) | H100 (80GB) × 1 | 128GB+ | ✅ 단일 노드, aggregated |
| 대형 모델 (Llama 70B) | H100 × 2~4 (NVLink) | 256GB+ | ✅ 텐서 병렬 |
| 플래그십 (DeepSeek R1/V4) | GB200 NVL72 | TB급 | ✅ Disaggregated, 진짜 사용처 |
| 맥/CPU만 있는 경우 | — | — | ❌ Dynamo는 CUDA 필수 — 학습용으로 mocker 백엔드 사용 가능 |
OS/소프트웨어
- OS: Ubuntu 24.04 (공식 빌드 가이드 기준), Ubuntu 22.04도 가능
- Rust: 2024 edition, toolchain 자동 핀
- Python: 3.10~3.13
- CUDA: 12.x 권장 (백엔드별로 상이)
- 시스템 패키지:
build-essential libhwloc-dev libudev-dev pkg-config libclang-dev protobuf-compiler python3-dev cmake
- 패키지 매니저:
uv (필수에 가까움)
주의
"내 노트북에서 그냥 돌려보자"는 어렵다
Dynamo는 오케스트레이션 계층이라 단일 GPU 단일 모델만 돌리려면 사실 vLLM 단독으로 충분하다. Dynamo의 진짜 맛은 여러 GPU·노드를 묶을 때 나온다. 학습 목적이라면 mocker 백엔드(lib/mocker)나 Kubernetes Kind 클러스터 + 적은 GPU로 시뮬레이션하는 게 현실적.
8직접 해볼 수 있는 실습 과제
"읽기만 하지 말고 손에 묻혀라" — 난이도별 5단계
난이도 ★ — 동작 확인 (1~2시간)
실습 1 · "Hello Dynamo"
목표: 도커로 SGLang 런타임 컨테이너 띄우고 Qwen3-0.6B를 OpenAI API로 부르기
docker run --gpus all --network host --rm -it \
nvcr.io/nvidia/ai-dynamo/sglang-runtime:1.1.1
# 컨테이너 안에서
python3 -m dynamo.frontend --http-port 8000 --discovery-backend file &
python3 -m dynamo.sglang --model-path Qwen/Qwen3-0.6B --discovery-backend file &
# 호스트에서
curl localhost:8000/v1/chat/completions -d '{
"model": "Qwen/Qwen3-0.6B",
"messages": [{"role":"user","content":"안녕"}]
}'
배움: Frontend ↔ Worker 분리 구조 체감, etcd 없이도 file discovery로 동작한다는 것.
난이도 ★★ — 라우팅 관찰 (반나절)
실습 2 · "KV-Aware Routing 실측"
목표: 같은 시스템 프롬프트로 시작하는 요청을 100개 보내고, KV-Aware ON/OFF 비교
1) NATS 서버 띄우기 (nats-server -js)
2) Worker 2개를 KV cache 이벤트 활성화로 실행
3) locust나 vegeta로 같은 prefix 요청 폭격
4) Grafana로 TTFT P95 비교
배움: 왜 NATS가 KV-Aware의 필수 조건인지, 캐시 적중률이 TTFT에 미치는 직접 영향.
난이도 ★★★ — 분리 서빙 직접 구성 (1~2일)
실습 3 · "Llama-3-8B를 prefill/decode 분리로"
목표: H100 2장 또는 RTX 4090 4장으로 Llama 3 8B 분리 서빙
recipes/llama-3-70b/vllm의 YAML을 8B로 축소 → prefill 1대 + decode 2대 구성 → 같은 메시지를 aggregated vs disaggregated로 비교. 토큰당 처리량과 GPU 활용률 그래프 그리기.
배움: 왜 prefill GPU가 burst로 100% 찍고 decode는 평탄하게 60~80%인지 직접 본다.
난이도 ★★★★ — K8s 배포 (3~5일)
실습 4 · "EKS/GKE에 Dynamo Platform 올리기"
목표: 클라우드 K8s 클러스터에 Dynamo Operator 설치 → DGDR YAML 한 장으로 모델 배포 → Auto-scale 동작 확인
examples/deployments/EKS 가이드 따라가기. Helm chart 설치, GPU 노드 풀 생성, Prometheus 메트릭 수집, Grafana 대시보드 임포트, Locust 부하 → Planner가 워커 추가하는 것 관찰.
배움: 실전 LLM 인프라를 한 번 처음부터 끝까지 만져본 경험. 면접 카드.
난이도 ★★★★★ — 코드 기여 (장기)
실습 5 · "good first issue 하나 골라서 PR"
목표: github.com/ai-dynamo/dynamo/issues에서 good first issue 라벨 필터 → 하나 골라 PR
커뮤니티가 70명+로 활발하고, DCO 사인만 하면 받아준다. Office Hours가 격주로 있고 Discord도 운영 중이라 막히면 물어볼 사람이 있다. Rust + Python + Go 중 자신 있는 것부터 시작.
배움: NVIDIA 공식 레포 컨트리뷰터. 이력서 한 줄.
9관련 기술 심화 학습 로드맵
"Dynamo만 보지 말고, Dynamo를 둘러싼 생태계까지" — 8주 학습 플랜
1주차 — LLM 추론 기초
- Transformer attention의 KV cache 동작 원리 (3blue1brown 시리즈 + Andrej Karpathy nanoGPT)
- vLLM PagedAttention 논문 읽기
- HuggingFace transformers로 작은 모델 직접 추론 → KV cache 메모리 측정
2주차 — 추론 엔진 비교
- vLLM, SGLang, TensorRT-LLM 각각 단일 GPU에서 동일 모델(Llama-3-8B-Instruct) 추론
- 벤치마크: TTFT, ITL, throughput 비교
- 각 엔진의 라이선스·생태계·강점 정리
3주차 — Rust 비동기 시스템 프로그래밍
- Tokio 공식 튜토리얼 끝까지
- axum으로 OpenAI 호환 mock 서버 만들기
tracing + opentelemetry 연동해 분산 트레이싱 콘솔 출력
4주차 — Dynamo Quick Start
- 섹션 8 실습 1~2 완료
- Dynamo 공식 문서
docs.nvidia.com/dynamo/ Getting Started 전체 정독
- Disaggregated Serving 디자인 문서 읽기
5주차 — KV 라우팅과 캐싱
- NATS JetStream 직접 띄우고 publish/subscribe 코드 짜기
lib/kv-router 코드 읽으며 prefix 매칭 알고리즘 따라가기
- BLAKE3 vs xxhash vs SHA-256 벤치마크 비교
6주차 — Kubernetes Operator
- kubebuilder 튜토리얼로 mini Operator 만들기
- Dynamo Operator 코드 읽기 (Go,
deploy/operator/)
- DGDR CRD 스펙 분석 + 자기 모델용 YAML 작성
7주차 — 실전 배포
- 섹션 8 실습 3 (분리 서빙) 또는 실습 4 (EKS/GKE)
- Prometheus + Grafana로 SLA 대시보드 직접 구성
- Planner 메트릭으로 auto-scale 시연
8주차 — 기여·확장
- 섹션 8 실습 5 (PR 도전)
- 또는 자기 백엔드 어댑터(예: MLX, AMD ROCm vLLM) 만들기 시도
- 블로그 글로 8주간의 학습 기록 정리 → 커리어 포트폴리오
병행 추천
"Dynamo 외 같이 보면 좋은 레포"
· vLLM — 가장 활성화된 추론 엔진, Dynamo 백엔드 1순위
· SGLang — RadixAttention 등 흥미로운 알고리즘
· llama.cpp — CPU/Apple Silicon에서도 돌리고 싶을 때
· Ray — Dynamo와 다른 접근의 일반 분산 컴퓨팅
· KServe — K8s 위 ML 서빙의 다른 표준
10핵심 키워드 사전
"이 단어들이 한 페이지에 다 모이는 건 흔치 않다" — 자주 쓰는 LLM 인프라 용어
키워드
Disaggregated Serving
Prefill(입력 처리)과 Decode(토큰 생성)를 별도 GPU 풀에서 돌리는 방식. 두 단계의 GPU 사용 특성이 달라서 분리하면 각자 100%에 가깝게 활용 가능. Dynamo의 가장 큰 차별점.
키워드
Prefill / Decode
Prefill은 사용자 입력 토큰 전체를 한 번에 attention 계산(컴퓨트 바운드). Decode는 출력 토큰을 하나씩 생성(메모리 대역폭 바운드).
키워드
TTFT / ITL
Time To First Token(첫 토큰까지) + Inter-Token Latency(토큰 간 지연). 사용자 체감 속도를 결정하는 두 수치. SLA 정의의 표준.
키워드
KV Cache
Transformer가 이미 처리한 토큰의 attention K, V 값을 GPU 메모리에 보관. 긴 컨텍스트일수록 GB 단위 메모리를 먹는다. LLM 추론 최적화의 핵심 자원.
키워드
KV-Aware Routing
요청 토큰의 prefix가 이미 어느 워커의 KV cache에 있는지 알고 라우팅하는 기법. 시스템 프롬프트가 공통일 때 prefill을 거의 0으로 만든다.
키워드
KVBM (KV Block Manager)
Dynamo의 4단 KV 계층 캐시: GPU HBM → CPU RAM → NVMe SSD → 원격 S3. OS 페이지 캐시의 LLM 버전.
키워드
NIXL
NVIDIA Inference eXchange Library. GPU 간 데이터 전송(RDMA, NVLink, InfiniBand) 추상화. KV 전송과 ModelExpress 가중치 스트리밍에 사용.
키워드
NVL72
NVIDIA Blackwell 세대 GB200 NVL72 랙. 72개 GPU가 단일 NVLink 도메인. 거대 모델 분산 추론의 표준 단위.
키워드
SLA (Service Level Agreement)
"TTFT 200ms 이하, ITL 20ms 이하" 같은 약속. Dynamo Planner는 이 SLA를 지키기 위해 자동 스케일링한다.
키워드
TCO (Total Cost of Ownership)
GPU 가격 + 전기료 + 데이터센터 + 인력. NVIDIA가 강조하는 진짜 비용 단위. Planner는 SLA 충족하면서 TCO 최소화를 목표로.
키워드
PagedAttention
vLLM이 도입한 KV cache 페이지 관리 기법. OS 가상 메모리처럼 4KB 페이지 단위로 KV 할당 → 단편화 감소, 동적 batching 가능.
키워드
Continuous Batching
요청을 받는 즉시 진행 중 batch에 합류시키는 방식. 전통적 batch처럼 묶일 때까지 기다리지 않음. vLLM/SGLang/TRT-LLM 모두 채택.
키워드
CRD / Operator
Kubernetes Custom Resource Definition + 그 리소스를 reconcile하는 컨트롤러. Dynamo는 DynamoGraphDeploymentRequest CRD + Go Operator로 배포 자동화.
키워드
DGDR (Dynamo Graph Deployment Request)
모델·하드웨어·SLA를 한 YAML에 적으면 AIConfigurator가 토폴로지를 풀고 Planner가 워커를 띄우는 zero-config 배포 메커니즘 (1.0 beta).
키워드
BLAKE3
2020년 발표된 초고속 암호 해시. SHA-256보다 ~10배 빠르고 SIMD/병렬 최적화. Dynamo가 KV prefix 해싱에 사용.
키워드
maturin / PyO3
Rust 크레이트를 Python 모듈로 빌드하는 도구(maturin) + 브릿지 라이브러리(PyO3). Dynamo가 Rust 코어와 Python 컴포넌트를 잇는 방법.
키워드
uv
astral.sh가 만든 Rust 기반 Python 패키지 매니저. pip보다 10~100배 빠름. Dynamo 공식 설치 도구.
11참고 링크
"직접 가서 확인해 보고 싶을 때"
공식
커뮤니티
벤치마크·블로그
주변 생태계