NVIDIA Dynamo 架构梳理

数据中心级分布式 LLM 推理编排栈  ·  Rust 核心 + Python 扩展 + K8s 编排
目录
  1. 顶层目录布局
  2. lib/ —— Rust 核心库与 crate 依赖
  3. lib/llm —— LLM 请求 pipeline
  4. components/ —— Python 入口与引擎适配
  5. 数据面 vs 控制面(全景)
  6. 部署链路:CRD / Helm / Operator / Pod
  7. 术语速查

1. 顶层目录布局

定位口径:Rust 在 lib/ 提供运行时和 LLM pipeline,Python 在 components/ 做胶水 + 引擎适配,Go/Helm 在 deploy/ 做 K8s 编排

flowchart TD ROOT["dynamo/ 仓库根"] ROOT --> LIB["lib/
Rust 核心库(性能关键路径)"] ROOT --> COMP["components/
Python 组件入口 python -m dynamo.*"] ROOT --> DEP["deploy/
K8s Operator / Helm / Gateway"] ROOT --> REC["recipes/
各模型 K8s 部署模板"] ROOT --> EX["examples/ · benchmarks/ · docs/ · container/ · tests/"] classDef rust fill:#fff1e5,stroke:#bc4c00,color:#3d1d00; classDef py fill:#ddf4ff,stroke:#0969da,color:#03285e; classDef go fill:#dafbe1,stroke:#1a7f37,color:#03311a; classDef misc fill:#f0f3f6,stroke:#8b949e,color:#1f2328; class LIB rust; class COMP py; class DEP go; class REC,EX misc;

2. lib/ —— Rust 核心库与 crate 依赖

每个目录都带有自己的 Cargo.toml,因此都是一个独立 crate,由根 Cargo.toml 的 workspace 统一管理。依赖方向自底向上:

flowchart BT RUNTIME["dynamo-runtime
分布式运行时 · AsyncEngine · pipeline · 服务发现"] PROTO["dynamo-protocols
跨进程消息协议"] TOK["dynamo-tokenizers / tokens"] PARSERS["dynamo-parsers
tool-calling / reasoning"] MEM["dynamo-memory
NIXL / 共享内存"] KVR["dynamo-kv-router
KV-aware 路由(独立 crate)"] KVBM["kvbm-logical / physical / kernels / engine
KV Block Manager 多层缓存"] LLM["dynamo-llm
LLM pipeline(最大 crate)"] BIND["lib/bindings/python
PyO3 绑定 → Python 包"] PROTO --> LLM RUNTIME --> LLM TOK --> LLM PARSERS --> LLM MEM --> LLM KVR --> LLM KVBM --> LLM RUNTIME --> KVR LLM --> BIND RUNTIME --> BIND classDef base fill:#f0f3f6,stroke:#8b949e,color:#1f2328; classDef hot fill:#fff1e5,stroke:#bc4c00,color:#3d1d00; classDef py fill:#ddf4ff,stroke:#0969da,color:#03285e; class RUNTIME,PROTO,TOK,PARSERS,MEM,KVR,KVBM base; class LLM hot; class BIND py;
易混点:crate vs module
dynamo-kv-routerlib/kv-router)是独立 crate,可被任何项目单独依赖; 而 lib/llm/src/kv_routerdynamo-llm crate 内部的 module。前者被后者依赖。

3. lib/llm —— LLM 请求 pipeline

一次请求在 Rust 侧的流向:每一层都实现 AsyncEngine trait,被串成 pipeline;上游只认 Arc<dyn AsyncEngine>,不关心下游具体是哪个引擎。

flowchart LR CLIENT(["client"]) -->|OpenAI JSON| HTTP["http / grpc
OpenAI 兼容入口"] HTTP --> PRE["preprocessor
模板渲染 + 分词 + 多模态"] PRE --> ROUTER["kv_router
选 worker(KV 重叠 + 负载)"] ROUTER --> MIG["migration
失败自动重路由(容错)"] MIG --> BACKEND["backend engine
vLLM / SGLang / TRT-LLM worker"] BACKEND -->|KV blocks| KVBM["block_manager (KVBM)
GPU↔CPU↔SSD↔远端 多层缓存"] BACKEND -.响应流.-> DETOK["backend.rs
detokenize + 合并增量"] DETOK -.stream.-> CLIENT classDef hot fill:#fff1e5,stroke:#bc4c00,color:#3d1d00; classDef io fill:#ddf4ff,stroke:#0969da,color:#03285e; class HTTP,PRE,ROUTER,MIG,DETOK hot; class BACKEND,KVBM io;
模块职责关键文件
httpOpenAI JSON → 内部 Requestlib/llm/src/http/
preprocessorRequest → PreprocessedRequest(token_ids、多模态 tensor)preprocessor.rs
kv_router按 KV 缓存重叠 + 负载选中 workerkv_router/{indexer,scheduler,push_router}.rs
migration遇到可迁移错误自动换 worker 重试migration.rs
backend反向 detokenize、合并流式增量backend.rs
block_managerKVBM 多层 KV 缓存管理block_manager/ + lib/kvbm-*

4. components/ —— Python 入口与引擎适配

每个目录是一个 python -m dynamo.<name> 可执行模块。Frontend 只是壳,真正的 HTTP / preprocessor / router 都在 Rust 里,经 PyO3 绑定拉起。

flowchart TD CLIENT(["client"]) -->|HTTP| FE["python -m dynamo.frontend
HTTP + preprocessor + router"] FE <-->|etcd / K8s 服务发现| DISC{{"discovery"}} FE -->|TCP / NATS| W1["dynamo.vllm"] FE -->|TCP / NATS| W2["dynamo.sglang"] FE -->|TCP / NATS| W3["dynamo.trtllm"] W1 -.注册.-> DISC W2 -.注册.-> DISC W3 -.注册.-> DISC PLAN["dynamo.planner
SLA / load 自动扩缩容"] -->|调 K8s API 调整副本| W1 PROF["dynamo.profiler
离线性能 profiling"] -->|profile 数据| PLAN PLAN -.订阅 metrics.-> FE classDef py fill:#ddf4ff,stroke:#0969da,color:#03285e; classDef ctrl fill:#fff8c5,stroke:#9a6700,color:#3d2e00; class FE,W1,W2,W3 py; class PLAN,PROF ctrl;

三个 worker(vllm / sglang / trtllm)结构一致:main.py / args.py / publisher.py / handlers.py / engine.py / request_handlers/,都是把对应引擎包成实现 AsyncEngine 的 worker,再注册到 etcd 让 frontend 发现。

5. 数据面 vs 控制面(全景)

flowchart TB subgraph CTRL["控制面 control plane"] direction TB YAML["user.yaml
kind: DynamoGraphDeployment / DGDR"] OP["deploy/operator (Go)
监听 CRD → reconcile"] PLAN2["dynamo.planner + profiler
SLA 闭环扩缩容"] YAML --> OP OP -->|K8s API 拉起 Pod| PODS["frontend / worker / planner Pod"] PLAN2 -->|scale up/down| PODS end subgraph DATA["数据面 data plane"] direction LR C(["client"]) --> FE2["dynamo.frontend"] FE2 --> RT["kv_router"] RT --> MG["migration"] MG --> BE["dynamo.{vllm|sglang|trtllm}"] BE --> KB["KVBM 多层缓存"] BE -.detokenize/stream.-> FE2 end OP -.创建.-> FE2 PLAN2 -.订阅 metrics.-> FE2 classDef ctrl fill:#fff8c5,stroke:#9a6700,color:#3d2e00; classDef data fill:#ddf4ff,stroke:#0969da,color:#03285e; class YAML,OP,PLAN2,PODS ctrl; class C,FE2,RT,MG,BE,KB data;

6. 部署链路:CRD / Helm / Operator / Pod

flowchart LR DEV["Rust 代码 lib/"] -->|PyO3 + maturin| PYPKG["Python 包 dynamo.*"] HELM["helm install"] -->|打包安装| INSTALL["Operator + CRD 装入集群"] USERYAML["写 YAML
kind: DynamoGraphDeployment"] -->|类型由 CRD 定义| INSTALL INSTALL --> OP3["Operator 监听到资源"] OP3 -->|拉起=启动| POD["Pod:frontend / worker / planner
(容器里跑 python -m dynamo.*,底层是 PyO3 包的 Rust)"] classDef rust fill:#fff1e5,stroke:#bc4c00,color:#3d1d00; classDef py fill:#ddf4ff,stroke:#0969da,color:#03285e; classDef go fill:#dafbe1,stroke:#1a7f37,color:#03311a; class DEV rust; class PYPKG,POD py; class HELM,INSTALL,USERYAML,OP3 go;

7. 术语速查

术语含义在 Dynamo 的位置
crate Rust带 Cargo.toml 的 Rust 包 / 编译单元,类似 Python 的 pip 包lib/ 下每个目录
trait Rust类似接口:声明一组行为,impl Trait for Type 实现AsyncEngine(数据面核心)
PyO3 RustPy把 Rust 编译成 Python 能 import 的模块lib/bindings/python
CRD K8s给 K8s 注册一种自定义资源类型deploy/operator/api/(DynamoGraphDeployment)
Helm K8sK8s 的包管理器,把成套 YAML 打包成 chartdeploy/helm/charts/
Operator K8s监听 CRD 资源并落地为 Pod 的控制器deploy/operator/(Go)
Pod K8sK8s 最小运行单位,跑一个/一组容器frontend / worker / planner 运行实例