vLLM 社区 RFC #43470 "Bottleneck-aware expansion for PD disaggregation"(2026-05-22, author: zsn6493)将 PD 运行时的压力明确分为三类:
| 瓶颈类 | 定义 | 扩展动作 |
|---|---|---|
| Prefill-bound | Prefill 侧 compute/memory 压力主导 | 加 prefill 容量 |
| Decode-bound | Decode 侧 token 吞吐/调度压力主导 | 加 decode 容量 |
| Decode-KV-bound | Decode 侧 KV holding capacity 主导,即使 compute 未饱和 | 加 decode 侧 KV capacity / tier |
关键原文:"decode-side KV capacity becomes the dominant bottleneck even when compute is still available; remote KV transfer backlog creates hidden stalls between the two pools"
协作方 robertgshaw2-redhat(llm-d)回应:该能力应放在编排层(llm-d flow-control / Dynamo 路由),vLLM 作为执行层暴露压力信号即可。
Google 搜索 sglang decode side memory pressure PD disaggregation long context 的 AI 摘要:
"In Prefill-Decode (PD) disaggregated serving, long-context requests place massive Key-Value (KV) cache burdens on the decode side. Managing this requires preventing Out-Of-Memory (OOM) lockups without sacrificing generation speed."
搜索 vllm decode worker HBM PD disaggregation capacity bottleneck 的 AI 摘要:
"the system often faces a decode worker bottleneck caused by HBM (High Bandwidth Memory) capacity and PD disaggregation bandwidth limitations"
DeepSeek-V4-Pro FP8 + H200 GPU(total_gpu_memory=138.17 GB),PD 分离 prefill 节点因 is_hybrid_swa=true 错误地把 token 容量钳制到 swa_max_total_num_tokens = 18,432,而实际硬件 KV pool 可支撑 186,368 tokens:
Memory profiling: available_gpu_memory=17.94 GB, total_gpu_memory=138.17 GB, mem_fraction_static=0.90, rest_memory=4.13 GB
DSv4 memory calculation: bytes_per_full_token=23749.84, available_bytes=4.13 GB, full_token=186368
DSv4 pool sizes: full=186368, swa=18432, c4=46592, c128=1456, c4_state=1152, c128_state=18432
错误信息:"Request ... exceeds the maximum number of tokens: 100804 > 18432"
根因:SWA allocator 在 prefill 时分配了全量 KV cache,但运行时仍用 SWA 上界卡 max_total_num_tokens。Commenter CloudRipple 反馈 swa=91904 同样 "severely unusable"。
维护者 weireweire 建议:应把 swa_max_total_num_tokens 与 估计峰值 SWA 需求(chunk size + sliding window margin)比较,而非与全量 prompt 比较。
GB300 节点(4 GPU/node, MNNVL fabric),Kimi-K2.5-NVFP4,mooncake transfer backend。per-DP-rank running requests > ~450 时,decode worker 在 4–8 分钟内卡死(6/6 复现):
| 场景 | CUDA graphs | Per-rank occupancy | 结果 |
|---|---|---|---|
| PD disagg serving (mooncake) | on | 450–790 | deadlock 6/6, 4–8 min |
| PD disagg serving | --disable-cuda-graph | 512 (slot cap) | stable 26 min |
| Single-node agg, fixed-bs | on | 512 | stable |
| Single-node agg, dynamic | on | 730–790 | stable 16 min |
关键配置:--mem-fraction-static 0.85 --context-length 9216 --max-running-requests 4096 --cuda-graph-max-bs 2048,decode TP8 跨 node0+node1。
故障需要 PD disaggregation + CUDA graphs + 高 per-rank batch size 三者同时成立。
Workaround:① 限制 decode admission 使 per-rank ≤ ~400(--max-running-requests 3200 for DP8)② --disable-cuda-graph(稳定但慢)。
怀疑方向:KV cache 从 mooncake custom mem pool 分配(cuMemCreate/fabric memory)与普通 allocator 行为不同;并发 mooncake NVLink writes into KV pool 与 captured graph replay 竞争。
#31252:HiCache 的 draft KV pool backup 在 PD disaggregation 下触发 cudaMemcpyBatchAsync invalid argument。显示 D 端多级 KV pool(HiCache 的 full/draft 分层)在 PD 模式下的内存管理仍不成熟。
#23022:ShmPointerMMData shared memory 在 multimodal + dp_size > 1 + PD disaggregation 组合下被过早 unlinked。显示 PD 模式下 host-memory 共享元数据层的生命周期管理缺陷。
论文 "Demystifying the Design Space and Best Practices for Heterogeneous LLM Inference and Serving"(arXiv 2606.29708, 2026-06-30)系统化了异构 PD 的设计空间,提出 4 个设计轴 + 3 个边界决策:
vLLM 官方博客 "Next-Level Inference: Why Your Single-Node vLLM Setup Needs Prefill-Decode Disaggregation"(22 min read)核心论点:
博客 "Serving Agentic Workloads at Scale with vLLM x Mooncake":
"PD disaggregation combined with the distributed KV cache pool via MultiConnector. Prefill: The prefill instance prepares KV blocks..."
通过 Mooncake Store 作为分布式 KV cache,跨 turn / 跨 instance 复用 shared prefix,解耦 KV capacity 与本地 HBM。
#46107 实测 DeepSeek-R1 8K-in/1K-out on MI300X(gfx942),512 concurrency:
| 配置 | Total throughput (tok/s) | Mean TTFT (ms) | Benchmark dur (s) |
|---|---|---|---|
| 2P_TP8 : 1D_TP8(同质 TP8) | 38,407 | 55,179 | 1,106 |
| 2P_DP8EP : 1D_DP8EP(同质 DP8EP) | 34,935 | 77,155 | 1,216 |
| 2P_TP8 : 1D_DP8EP(MIXED) | 42,349 | 46,052 | 1,003 |
混合并行(TP prefill + DP/EP decode)在最高并发下吞吐最高、TTFT 最低。核心机制:KV transfer connector 需支持跨不同 (dp_size, tp_size) 的 read routing,引入 per-(dp,tp) session keying + flexible prefill-TP read(round-robin 分散 read load 到多个 prefill TP ranks)。
SGLang "Memory-semantic PD-disaggregation paradigm"(Uni-PD):
这是对"D 端内存不够"的另一种解题思路:不是扩大 pool,而是让 KV 产生即落地到 D 端 HBM,消除 transfer backlog 造成的 hidden stall。
Google AI Overview 给出的单 sequence KV cache HBM 空间估算公式:
"The formula to estimate the HBM space (S) in gigabytes needed for a single sequence's KV cache is: ... You must balance how much HBM is dedicated to holding active tokens versus generating new ones. HBM is expensive and limited, so managing its size properly determines how many users an LLM can serve at once."
关键策略:
| Issue | 系统 | 主题 | 状态 |
|---|---|---|---|
| #43470 | vLLM | Bottleneck-aware expansion(定义 Decode-KV-bound) | open |
| #46107 | vLLM | MoRIIO 异构 TP/DP PD 并行 | open |
| #45749 | vLLM | MoRI/MoRIIO READ-mode hangs (AMD) | open |
| #44300 | vLLM | MooncakeConnector KV corruption under concurrent PD transfers | open |
| #45036 | vLLM | Mooncake Store Connector Roadmap | open |
| #44238 | vLLM | KV cache pruning feature | open |
| #47722 | vLLM | KV cache init shape mismatch EP+DP on MoE | open |
| #24523 | SGLang | PD input length hard-cap 18432 (SWA bug) | open |
| #30010 | SGLang | Decode deadlock high batch + CUDA graph | open |
| #31252 | SGLang | HiCache draft KV pool backup crash PD | open |
| #23022 | SGLang | ShmPointerMMData PD shared mem unlink | open |
| #30242 | SGLang | Deepseek V4 NVFP4 Disagg Decode node failure | closed |
| #23499 | SGLang | NIXL UCX segfault in disaggregated KV transfer | closed |