NVIDIA Dynamo 源码阅读(二):分布式运行时如何组织服务与请求

Dynamo 的推理组件能够跨进程、跨节点组合,核心依赖 lib/runtime。这一层不理解模型,也不关心 token 的语义;它提供的是一套分布式组件模型:服务如何命名、实例如何注册、客户端如何发现、请求如何流式传输。 本文基于 Dynamo 提交 27f09d5。 一、运行时的核心抽象 源码从 DistributedRuntime 开始。它持有运行时配置、服务发现实现、网络管理器和关闭信号,并向上提供 Namespace。 对象关系可以简化为: DistributedRuntime └── Namespace("dynamo") ├── Component("frontend") │ └── Endpoint("generate") ├── Component("router") │ └── Endpoint("generate") └── Component("worker") └── Endpoint("generate") × N instances 这四层各有不同职责: Runtime:进程级资源和生命周期; Namespace:隔离一组服务; Component:表示逻辑服务角色; Endpoint:表示可调用接口及其多个实例。 Endpoint 名字相同不代表只有一个服务器。每个 Worker 可注册自己的 instance,客户端通过 discovery 得到动态实例集合。 二、服务发现保存什么 lib/runtime/src/discovery 定义了发现层。一个 Endpoint 注册时,系统不仅记录地址,还附带实例、组件和元数据。客户端查询的关键维度是: (namespace, component, endpoint) -> [instance...] 在裸机模式中,注册与租约可由 etcd 支持;Kubernetes 模式使用 DynamoWorkerMetadata CRD 和 EndpointSlice。运行时把发现后端抽象掉,上层 Router 不需要分别实现 etcd watcher 与 Kubernetes watcher。 ...

2026年8月26日 · 2 分钟 · Hellokitty

NVIDIA Dynamo 源码阅读(三):KV-aware Router 如何选择 Worker

普通负载均衡只关心哪个 Worker 更空闲。LLM 推理还需要回答另一个问题:哪个 Worker 已经缓存了当前请求的最长前缀?如果忽略缓存局部性,相同 system prompt、文档或多轮会话会在不同 GPU 上反复 Prefill。 Dynamo 的 KV-aware Router 将缓存命中与运行负载放进同一次决策。本文基于提交 27f09d5,重点阅读 lib/kv-router 与 lib/llm/src/kv_router。 一、路由问题如何形式化 设请求 token 被按固定 block size 切成若干块: [t0 ... t15] [t16 ... t31] [t32 ... t47] [剩余 token] B0 B1 B2 每个完整块计算链式哈希。Router 维护如下关系: B0 -> {worker 1, worker 3} B1 -> {worker 1} B2 -> {worker 1} 如果新请求具有相同前三块,Worker 1 的重叠长度最大。但它可能已经非常繁忙,因此最终决策不是简单的最长前缀匹配,而是 locality 与 load 的权衡。 二、为什么使用链式 block hash compute_block_hash_for_seq 不会孤立地哈希每个 token 块,而是把前一个块的 hash 纳入下一个块。这使相同内容出现在不同前缀后时不会被错误视为同一缓存位置。 ...

2026年8月26日 · 2 分钟 · Hellokitty

NVIDIA Dynamo 源码阅读(四):Prefill/Decode 分离与 KV 传输

Prefill 与 Decode 使用同一个 Transformer,却具有不同资源特征。Prefill 面向长序列并行计算,关注首 token 延迟;Decode 每轮只处理少量 token,受显存带宽和迭代调度影响。把两者固定绑在同一副本上,资源比例只能随实例一起扩缩。 Dynamo 的 disaggregated serving 将两阶段放到不同 Worker 池,并用直接 KV 传输连接起来。本文基于提交 27f09d5。 一、为什么要做两次路由 解耦请求包含两个独立选择: Frontend | v 选择 Prefill Worker ----> 计算输入 KV | | |<---- transfer metadata--+ | v 选择 Decode Worker <==== 直接搬运 KV | v 逐 token 生成 -> Frontend -> Client Prefill Worker 的选择偏向输入前缀命中与 Prefill 排队;Decode Worker 的选择偏向持续生成负载、可用 KV 容量和传输拓扑。将二者合成一次普通负载均衡,会丢失阶段差异。 ...

2026年8月26日 · 2 分钟 · Hellokitty

NVIDIA Dynamo 源码阅读(一):数据中心级推理栈的整体架构

NVIDIA Dynamo 不是另一个 vLLM 或 TensorRT-LLM。它不负责重新实现 Attention、Continuous Batching 或模型执行,而是把多个推理引擎实例组织成一个可路由、可拆分、可扩缩的服务。 这一区分决定了阅读源码的入口:不要从 CUDA kernel 开始,而应先找到请求如何跨过 Frontend、Router、Prefill Worker 和 Decode Worker,以及服务发现、事件传播、KV 传输分别位于哪一层。 本文基于 Dynamo 提交 27f09d5,仓库版本为 1.5.0。 一、Dynamo 解决的不是单卡执行问题 单个推理引擎已经能完成一次生成:接收 token、执行 Prefill、循环 Decode、管理本机 KV Cache。规模扩大后,系统出现新的问题: 同一前缀可能被多个副本重复 Prefill。 Prefill 与 Decode 的算力和延迟特征不同,固定配比容易浪费 GPU。 Worker 上下线后,路由器必须快速获得最新拓扑。 KV Cache 不仅存在于显存,还可能分布在主存、SSD 或其他节点。 不同后端有不同请求格式与 KV 传输协议,但上层服务不应被绑定。 Dynamo 把这些问题放在推理引擎之上: 控制面 Discovery / Planner / Metrics | v Client -> Frontend -> Router -> Inference Worker | | | | +---- KV Events+ | +------ 流式响应 ----------> KV 数据面(按需) Prefill Worker ======> Decode Worker NIXL / backend connector 请求平面回答“请求发给谁”;KV 数据面回答“缓存如何移动”;控制面回答“哪些实例存在、负载怎样、是否扩缩容”。三者分开,是 Dynamo 架构最重要的设计。 ...

2026年8月26日 · 2 分钟 · Hellokitty