llm-wiki wiki · analysis 2026-10-11

本页追踪 Dynamo Frontend 收到 OpenAI-compatible 请求后,如何通过 Distributed Runtime、KV-aware routing 与 backend workers 进入 vLLM 或 SGLang,并区分 aggregated 与 Prefill/Decode 分离路径。它还将 request、event、discovery 三个 plane 分开,避免把 KV event 当作 KV tensor transfer。

Dynamo 的统一层在 engine 之上:Frontend/preprocessor、router、runtime endpoint 和 worker handler 负责跨进程/跨节点协调;进入 vLLM AsyncLLM 或 SGLang TokenizerManager/Scheduler 后,batch、KV allocation 与 GPU kernels 仍由 engine 负责。

当前源码快照与结论范围

核验日期:2026-10-11。

Frontend 与 Runtime 所有权

[Client]
   │ OpenAI-compatible HTTP/SSE
   ▼
[Dynamo Frontend]
   validate · chat template · tokenize · request extensions · postprocess
   │ preprocessed request / token sequence / routing hints
   ▼
[Router / PrefillRouter]
   KV overlap · active prefill/decode load · policy/admission
   │ runtime endpoint request
   ▼
[Distributed Runtime]
   Namespace → Component → Endpoint → endpoint instance
   │ request plane: direct TCP or NATS
   ├─────────────────────────────────────────┐
   ▼                                         ▼
[Aggregated worker]                 [Prefill + Decode workers]
   │ engine handler                           │ NIXL/engine handoff
   ▼                                          ▼
vLLM or SGLang → GPU                vLLM or SGLang → GPU
   │                                          │
   └────────────────── token stream ──────────┘
                         │ Frontend postprocess/detokenize
                         ▼
                       Client

Runtime 的四级对象

对象 所有权 请求路径作用
DistributedRuntime 进程级连接、background tasks、cancellation 承载 discovery/request/event clients
Namespace 一个 deployment/model group 的逻辑隔离 防止 endpoint 名称跨部署碰撞
Component 同角色 workers,如 frontend/prefill/decode 建立 membership 与 endpoint group
Endpoint generate、clear_kv_blocks、metrics 等服务 typed/streaming RPC 目标

Runtime 解决 endpoint 发现和消息 transport,不替代 engine scheduler。一个 Runtime request 可以流式返回很多 token chunks,但 GPU iteration 仍由 backend engine 决定。

支持矩阵

Engine Serving 形态 状态 固定 commit 证据
vLLM Aggregated documented vLLM backend overview 与 examples/backends/vllm/launch/agg.sh
vLLM P/D documented disaggregated architecture、vLLM Prefill/Decode handlers、NIXL connector tests/recipes
SGLang Aggregated documented SGLang backend overview 与 examples/backends/sglang/launch/agg.sh
SGLang P/D documented SGLang disaggregation guide、Prefill/Decode handlers 与 launch/disagg.sh

“documented”只表示基础组合有官方路径;feature pair 的成熟度仍不同。例如固定 commit 的 SGLang 文档把 disaggregated remote-prefill cancellation、LoRA+P/D 等部分组合标成 limited/未做完整端到端验证。

vLLM × Aggregated

Aggregated worker 本地完成 prefill 与 decode。Frontend 可用 KV-aware router 在多个 aggregated workers 中选一个;被选 worker 的 Dynamo handler 将请求适配给 vLLM native generate API,并把 engine output 转成 Dynamo/OpenAI stream。

Client
  ──► Frontend preprocess/tokenize
  ──► KV router or load-balancer selects aggregated vLLM endpoint
  ──► Runtime request plane → vLLM DecodeWorkerHandler(aggregated mode)
         ├── request → vLLM GenerateRequest/SamplingParams
         ├── engine_client.generate / AsyncLLM.generate
         ├── EngineCore → Scheduler → GPUModelRunner
         ├── prefill and decode share local worker/KV
         └── async ModelRunner outputs
  ◄── Runtime response stream
  ◄── Frontend postprocess/detokenize/SSE

固定 commit 的 dynamo.vllm.handlers.DecodeWorkerHandler.generate 同时承载 aggregated 与 decode-side path;是否要求 remote prefill 由 worker mode/request annotations 决定。进入 vLLM 后见 vllm-gpu-execution-path。

vLLM × P/D

vLLM P/D 是同步 prefill-first 契约:Prefill 完成后返回 kv_transfer_params(block IDs、remote worker/connector 信息等 backend metadata),router 将其注入 Decode request。

Client       Frontend/PrefillRouter      Prefill vLLM handler       Decode vLLM handler
  │ request            │                          │                         │
  ├───────────────────►│ preprocess/tokenize      │                         │
  │                    ├─KV/load select prefill──►│                         │
  │                    │                          ├─AsyncLLM prefill        │
  │                    │                          ├─write/export KV         │
  │                    │◄─disaggregated_params────┤                         │
  │                    ├─select decode + inject kv_transfer_params─────────►│
  │                    │                          │◄══ NIXL KV transfer ═══►│
  │                    │                          │                         ├─load/wait
  │                    │                          │                         ├─decode GPU
  │                    │◄──────────────────────── token stream ─────────────┤
  │◄─Frontend SSE──────┤

Dynamo dynamo.vllm.handlers.PrefillWorkerHandler.generate 负责 prefill worker endpoint;DecodeWorkerHandler.generate 负责 decode/aggregated endpoint。Worker handler 包装 vLLM,但 block allocation、connector pre/finish hooks 和 invalid-block recovery属于 vLLM engine connector。

SGLang × Aggregated

SGLang aggregated worker 使用原生 tokenizer manager/async generation,Dynamo handler 做 request translation、runtime streaming 与错误/cancellation 适配。

Client
  ──► Dynamo Frontend
       ├── SGLang-compatible preprocessing/chat template
       └── route to aggregated SGLang generate endpoint
  ──► dynamo.sglang.request_handlers.llm.DecodeWorkerHandler.generate
       ├── build native GenerateReqInput/payload
       ├── TokenizerManager.generate_request or engine.async_generate
       ├── Scheduler + RadixCache + ModelRunner
       ├── local extend/prefill + decode
       └── token/text chunks
  ◄── Runtime stream ──► Frontend postprocess ──► Client

固定 commit 的 components/src/dynamo/sglang/engine_generate.py 封装 native request construction/stream;engine 内部完整链见 sglang-gpu-execution-path。

SGLang × P/D

SGLang 路径与通用“先 Prefill 后 Decode”图不同:官方 backend guide 明确说明 Dynamo 先路由 Decode worker,再选择 Prefill worker并向两端发送请求,用 SGLang bootstrap server 配合 NIXL/Mooncake 进行 transfer。

Client       Frontend/Router       Decode SGLang handler       Prefill SGLang handler
  │ request       │                         │                            │
  ├──────────────►│ preprocess              │                            │
  │               ├─select decode──────────►│ create/bootstrap context   │
  │               ├─KV-aware select prefill────────────────────────────►│
  │               │                         ├── bootstrap/request ──────►│
  │               │                         │ allocate KV receive pages  │
  │               │                         │◄─ room/transfer metadata ──┤
  │               │                         │                            ├─prefill GPU
  │               │                         │◄══ RDMA/NIXL KV write ═════┤
  │               │                         ├─poll/confirm readiness      │
  │               │                         ├─SGLang decode GPU           │
  │               │◄────── token stream ────┤                            │
  │◄─SSE──────────┤

dynamo.sglang.request_handlers.llm.PrefillWorkerHandler.generate 生成/返回 bootstrap info并运行 prefill;dynamo.sglang.request_handlers.llm.DecodeWorkerHandler.generate 支持 aggregated/disaggregated 两种模式,构造 native request、校验 bootstrap info并处理 token/text stream。SGLang 内部 bootstrap 与 KV mapping 见 SGLang engine P/D。

KV-aware Routing

Router 的目标不是“命中最多就选谁”,而是估算选择某 worker 后的增量成本。固定 commit 的 Rust lib/kv-router 将 KV index、active sequences/load、policy/admission 和 selection/reservation 分离。

preprocessed token sequence / block hashes
              │
              ├───────────────► KvIndexer
              │                  find match details per worker
              │                  cached blocks / overlap confidence
              │
              ├───────────────► Active load tracker
              │                  active prefill tokens
              │                  projected decode blocks / requests
              │
              ▼
SelectionCore.select / select_and_reserve
  ├── filter eligible/healthy/model-compatible workers
  ├── convert overlap to effective prefill discount
  ├── add projected load / policy penalties
  ├── admission or capacity decision
  └── choose endpoint + optional reservation
              │
              ▼
Runtime endpoint request

KvIndexer.find_match_details 查询路由视图;它不读取 worker 的 K/V tensors。Worker 通过 KV lifecycle events 更新 index,event 丢失或延迟会造成路由视图陈旧;engine 最终仍须验证 local/received KV。

反馈闭环

request routed ──► worker executes ──► KV block stored/removed events
      ▲                                      │
      │                                      ··► event plane
      │                                           │
      └──── next selection ◄·· KvIndexer update ──┘

active request reservation ──► projected load ──► completion/cancel releases

Prefix locality 与队列负载存在冲突:缓存丰富的 worker 可能已经很忙,空闲 worker 可能需要重新 prefill。Dynamo policy 把二者纳入同一 selection,而不是固定偏向其中一个。

Request / Event / Discovery Planes

DISCOVERY PLANE
worker register Endpoint instance
  ··► etcd leases OR Kubernetes DynamoWorkerMetadata/EndpointSlice
  ··► Frontend/Router watch membership

REQUEST PLANE
Frontend/Router ──► namespace.component.endpoint
  ──► direct pooled TCP (default) OR brokered NATS
  ──► msgpack/json codec advertised per endpoint
  ◄── streaming responses / errors / cancellation

EVENT PLANE
workers ··► KV lifecycle / telemetry events ··► router/index/planner consumers
  ZMQ (default) OR NATS subjects

KV DATA PLANE
Prefill GPU ══ NIXL/NVLink/PCIe/RDMA ══► Decode GPU
  separate from all three metadata/control planes above

Planes 可以选择不同 transport。Discovery stale 时 Runtime 可暂时 inhibit 一个刚失败的 local worker,等待权威 membership 收敛;这不是永久删除 endpoint,也不保证 in-flight request 自动恢复。

NIXL KV Transfer

[Prefill engine]
logical KV blocks/pages
   │ register/export memory regions + backend metadata
   ▼
disaggregated_params
   ──► Router/Decode: block IDs · addresses/handles · rank/layout identity

[Decode engine]
allocate/reserve destination KV slots
   │ build NIXL transfer descriptors
   ▼
[NIXL]
source GPU memory ══ chosen transport ══► destination GPU memory
   NVLink / PCIe / InfiniBand-UCX / backend-specific path
   │ completion/event
   ▼
Decode engine maps received blocks → request KV view → attention

NIXL 是 data movement layer,不决定 endpoint,也不执行 attention。Router只转发 metadata;engine connector 知道具体 KV layout、TP ranks、layer/block mapping与何时可安全读取。Transfer 可以 non-blocking,但 Decode attention 仍需等待相关 bytes 完成。

Token 返回

[Engine GPU]
logits → sample token ID
   │ engine async generator
   ▼
[Dynamo worker handler]
translate backend chunk / usage / finish / extension fields
   │ Runtime streaming response
   ▼
[Frontend]
postprocess / detokenize when frontend owns decoding
tool/reasoning formatting / OpenAI SSE encoding
   │
   ▼
[Client]

Detokenization 位置依 frontend/backend configuration 而变:Frontend 可 tokenize/postprocess,也存在 engine-native text/token stream。页面只要求 ownership 可追踪,不假设所有 backend 都返回同形态 chunk。

一次 aggregated request 的共同段

HTTP request
 ──► Frontend preprocess
 ──► KV/load selection
 ──► Runtime generate endpoint
 ──► backend DecodeWorkerHandler(aggregated)
 ──► vLLM AsyncLLM OR SGLang TokenizerManager/async_generate
 ──► engine scheduler/batch/KV
 ──► CUDA kernels
 ──► engine token chunks
 ──► Runtime stream
 ──► Frontend response

失败、取消与迁移

边界 当前行为重点 不能假设
Frontend validation 在 dispatch 前拒绝非法 protocol/model/params worker 一定看到 request
Runtime endpoint failure inhibit 本地失败 instance,discovery 决定后续 membership 已执行的请求必然无副作用
P/D Prefill 失败 没有可用 transfer metadata 时 Decode 不应消费 KV 任意 Decode 都能重新接管
KV transfer 失败 connector/engine 报错、recompute 或 fail 取决于 backend index 命中能证明 payload 正确
Client cancellation Runtime propagation + backend handler/engine abort 任意阶段都能立即释放 GPU/KV
SGLang remote prefill cancellation 固定 commit backend matrix标为有限;decode-side cancellation能力更完整 P/D 两腿都有完全相同语义
Worker graceful shutdown unregister、drain grace、停止接新请求 Pod 删除自动迁移 sampling state
Request migration 需要 Dynamo/backend 支持并恢复必要 state 单靠 retry 可保证 token 流一致
before first token
  worker fails ──► route retry/migration may be possible if request/KV/state recoverable

after token chunks
  worker fails ──► Frontend has already exposed irreversible stream prefix
                    │
                    ├── resume only with explicit migration contract
                    └── otherwise surface truncated/error stream

迁移必须处理 generated tokens、KV、sampling/RNG/grammar/tool state 和 client stream position。Dynamo 的 request migration capability不能推广为每个 backend/feature pairing的透明 exactly-once。

Planner / Operator 旁路

REQUEST HOT PATH
Client ──► Frontend ──► Router/Runtime ──► Workers ──► token stream
                 ▲                           │
                 │                           │ metrics/load/capacity
                 │                           ·
                 │                           ▼
CONTROL LOOP   Profiler / Planner / AIConfigurator
                 │ desired prefill/decode replicas / config
                 ▼
              DGD / DCD / Operator / Kubernetes
                 │ reconcile deployments/endpoints
                 └··► discovery membership ··► Router/Runtime

Planner 根据 workload、SLO、capacity signals 提议副本变化;Operator 实际 reconcile workers。扩缩会经过 model load、endpoint register 和 readiness delay,因此 admission/backpressure 仍需在热路径处理当前负载。

控制、请求与数据状态表

状态 典型 owner 更新路径 是否在每个 token 热路径
endpoint membership Discovery/Runtime lease/EndpointSlice/register 否,watch/cache 反馈
KV locality index KV router worker KV events 路由时读取;不传 payload
active projected load Router/reservation dispatch/completion/cancel 路由时读取
request queue/batch vLLM/SGLang scheduler 每 engine iteration 是
KV tensor bytes engine GPU memory attention write / NIXL transfer 是
replica desired state Planner/Operator metrics/reconcile 否

源码入口

组件 固定 commit symbol 阅读重点
Frontend 组装 frontend.async_main Runtime、router、pre/post processor 与 HTTP frontend 初始化
KV selection SelectionCore.select selection/admission/reservation 与 endpoint response
KV index lookup KvIndexer.find_match_details per-worker prefix match details
vLLM Decode/Aggregated dynamo.vllm.handlers.DecodeWorkerHandler.generate request translation、engine stream、decode connector/cancel
vLLM Prefill dynamo.vllm.handlers.PrefillWorkerHandler.generate prefill execution与 transfer metadata
SGLang Decode/Aggregated dynamo.sglang.request_handlers.llm.DecodeWorkerHandler.generate native/async generation、bootstrap、token/text stream
SGLang Prefill dynamo.sglang.request_handlers.llm.PrefillWorkerHandler.generate bootstrap info、prefill stream、cache-hit reporting
SGLang native bridge native_generate_stream 调用 SGLang TokenizerManager.generate_request

学习结论

  1. Dynamo 的共同主干是 Frontend → routing → Runtime endpoint → backend handler;engine 内部执行仍需分别学习 vLLM/SGLang。
  2. vLLM P/D 使用 prefill-first metadata injection;SGLang P/D 使用 decode-first bootstrap并发协调,不能用同一时序替代。
  3. Request/event/discovery planes 处理消息和状态,NIXL 单独移动 KV payload。
  4. KV-aware routing把 locality 当作成本折扣,同时纳入 projected load;KV index 不是 KV cache storage。
  5. Planner/Operator 改变未来 capacity,不参与每个 token iteration,也不能消除扩缩启动延迟。