Files
agentic-kvc/microbench/fresh_setup/PD_DISAGG_INVESTIGATION.md
Gahow Wang b13ca10d19 PD_DISAGG_INVESTIGATION: snapshot Phase 0 done + sweep in flight
Phase 0 infrastructure (vendored proxy, dual-file vLLM patcher,
per-instance + cross-config plotters) is fully assembled and
smoke-validated. Sweep RUN_TAG=20260527_164040 (4 configs × 3 reps
on w600) is running on dash1.

Also realigned the figure list with what `aggregate_mb5.py`
actually produces (mb5_kv_timeline, mb5_peak_utilization,
mb5_latency_compare, mb5_summary.csv).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 00:51:28 +08:00

9.3 KiB
Raw Blame History

PD-disagg 在 agentic 下到底为什么不 work — 系统行为级论证

Living TODO 文档。记 H1/H2/H3/H4 四条假设的实验状态,以及每个实验需要的 instrumentation、figures、判定标准。所有 microbench 文件名前缀沿用 MB


当前状态2026-05-27

问题陈述:之前关于 "PD-disagg 在 agentic 失败" 的证据只有 colleague 一个数据点TTFT p50 62×、success 52%,在 dash0 patched 栈上。MB1+MB2 算正确账后 phase-isolation 反而 favor PD-disagg所以我们目前没有 paper-grade 实证证据。本文档跟踪需要的实验和 system-level 分析。

核心 gap:我们只看到 "PD-disagg 表面性能差 10×" 的 headline 数字,但没有 system-level breakdown 告诉 reviewer "为什么差,差在哪个组件"。需要的是 D-pool occupancy / scheduler queue depth / KV transfer queue / GPU SM utilization 等系统指标的时间序列,能直接指出 bottleneck。

Progress2026-05-27 16:50

Phase 0 doneMB5 pipeline 全部 standing up on dash1 fresh-venv:

  • mb5_launch.sh8C / 6P+2D / 4P+4D / 2P+6D 单一 launcherstop_all 包含 stale-port 守卫
  • mb5_pd_proxy.pyvendored copy of vLLM 官方 mooncake_connector_proxy.pypatch 了 min_tokens 在 prefill leg 上的兼容性 bug
  • instrument_kv_snapshot.pypatch V1 scheduler 暴露 schedule() 结束时的 per-request KV block 分配 + 修复 vLLM 0.18.1 MooncakeConnectorWorker.bootstrap_server 在 kv_consumer 模式下未初始化的 AttributeError
  • plot_kv_pool_timeline.pyper-instance KV pool 时间线stacked-area
  • aggregate_mb5.py:跨 config / 跨 rep 聚合,输出 4 张对比图 + 1 张 CSV

PD-disagg smoke (4P+4D × 20 reqs): 20/20 success, mean latency 3.9s, p99 17s, 8 PIDs 都写 snapshot601 total。 对比 8C × 20 reqs 同样数据点会在 sweep 完成后给出。

Phase 1 在跑

  • RUN_TAG=20260527_164040
  • CONFIGS=8C 6P+2D 4P+4D 2P+6D × REPS=3
  • TRACE=w600_r0.0015_st30.jsonl (~13 min/rep)
  • ETA ~3 h

Pendingsweep 结果 → 跑 aggregate_mb5.py → 写 Phase 2 system analysis。


4 条独立失败假设

假设 描述 当前证据 状态
H1 D 池容量天花板 p99 单请求 11.5 GiB / D-instance 38 GiB pool4P+4D 减半系统 decode 容量;长 context overflow → 排队 colleague 旧数据 + f4b 几何论证 need fresh-venv replication + system breakdown
H2 静态分池 mismatch 工作负载 P:D 比例随时间漂移;静态 ratio 无法适应 not started
H3 Cache reuse 退化 + P 池 hotspot round-robin P 丢 affinityAPC 跌sticky P 复现 §3.3 hot pin logical extension not started
H4 端到端 throughput 输 各 phase 看着 OK 但 wall-clock 输dispatch coupling 放大) not started

Phase 0 — Infrastructure必须先 done

TODO 0.1: 找 vLLM 标准 PD-disagg 部署方案 DONE

结论:用 vLLM 仓库 ship 的官方 example third_party/vllm/examples/online_serving/disaggregated_serving/mooncake_connector/

  • run_mooncake_connector.sh —— 参数化 P/D GPU 列表、ports、bootstrap直接支持任意 P:D 比例
  • mooncake_connector_proxy.py —— 官方 FastAPI proxyround-robin P + round-robin Dvendored 到 microbench/fresh_setup/mb5_pd_proxy.py,加 min_tokens=1 修复

部署形态P 实例用 kv_role:kv_producer(带 bootstrap_serverD 实例用 kv_role:kv_consumer。后者的 bootstrap_server AttributeError 通过 instrument_kv_snapshot.py patch 修复。

TODO 0.2: 包装官方 launcher DONE

microbench/fresh_setup/mb5_launch.sh 单一 launcher支持 8C / 6P+2D / 4P+4D / 2P+6D 配套 mb5_run.sh orchestratorCONFIG × REP 迭代,含 launch/replay/teardown

TODO 0.3: System-level instrumentation DONE (per-request KV)

选了比 /metrics 更深的层面:patch V1 scheduler 直接 dump 每个 schedule() 回合的 per-request KV block 分配10 Hz throttle

  • instrument_kv_snapshot.py 输出 schema: {t_unix, step, total_blocks, free_blocks, used_blocks, running:[{req_id, n_blocks, n_computed, n_prompt, n_tokens, status}], waiting:[...]}
  • 每个 EngineCore PID 一份 jsonl集中写入 MB5_LOG_DIR
  • 跟 prometheus /metrics 比:(a) 不需要轮询,(b) 拿到 per-request 而不只是 aggregate(c) 可以反推 D-pool 在某时刻被谁占着

如后续需要 prometheus /metricsadmission denial 事件之类),可以再加一个 sampler目前的 per-request 数据已经能撑住 Phase 1 + Phase 2 分析。

TODO 0.4: D 池 occupancy timeline 可视化 DONE

  • plot_kv_pool_timeline.py —— per-instance 视图stacked-area: 时间 × 块数 × per-request 色块;底下 waiting queue depth 子图)
  • aggregate_mb5.py —— 跨 config / 跨 rep 聚合视图cluster-wide KV 时间线、peak 占用率 bar、latency p50/p90/p99 bar、summary CSV

Phase 1 — MB5+3: PD ratio sweep + D-pool occupancy 实测

Question: 任何 static P:D ratio 能否打过 8C colo如果不能瓶颈在哪

矩阵

configs = [8C, 6P+2D, 4P+4D, 2P+6D]
trace = traces/w600_r0.0015_st30.jsonl (1.2k req, ~13 min if not stalled)
reps = 3

Primary metrics (per config, mean of 3 reps)

  • TTFT / TPOT / E2E (mean / p50 / p90 / p99)
  • Success rate
  • Wall-clock time to drain trace(→ dispatch coupling amplification
  • APC (effective prefix cache hit ratio)
  • System throughput (req/s steady state)

System breakdown (the kill-shot evidence)

  • D-pool occupancy timeline per D-instance
  • Scheduler queue depth timelinewaiting requests over time
  • TTFT per request scattercolored by which-instance— 看 D 池满了的时候 TTFT 是不是直接挂掉
  • Admission denial events(如果 vllm 暴露)

Output figures (aggregate_mb5.py will write all of these)

  • figs/mb5/mb5_kv_timeline.png — 4 panels (one per config), cluster-wide KV % 时间线faint per-rep line + bold median
  • figs/mb5/mb5_peak_utilization.png — bar chart peak vs steady KV per config含 ±std error bars
  • figs/mb5/mb5_latency_compare.png — bar chart p50/p90/p99 e2e latency per config
  • figs/mb5/mb5_summary.csv — flat per-(config, rep) 表latency, KV, prefix cache, success rate
  • manualfigs/mb5/mb5_per_instance_timeline.png — pick 1 rep per config, plot per-instance stacked-area via plot_kv_pool_timeline.py,给 paper §3.x system breakdown 用

判定标准H1 何时被 confirmed

H1 算 被证实 如果同时满足:

  1. PD-disagg 在所有非 8C config 上 TTFT p90 ≥ 2× 8C colo
  2. D-pool occupancy timeline 显示 D 池 ≥ 90% 持续超过 trace 时长的 30%
  3. Scheduler queue depth 在 PD-disagg 下显著高于 8C colo
  4. 至少一个 PD config 出现 success rate 下降

H1 算 被证伪 如果存在某 PD ratio 使所有指标和 8C colo 差不多 —— 那 §3.2 要重写。


Phase 2 — System analysis钉死 bottleneck

Phase 1 数据出来后,写 system-level analysis

  • 对 4P+4D 配置:哪条 D-instance 哪段时间到 90%?对应那时进来的请求是不是大 KV 的?
  • 比对 8C 和 4P+4D8C 同样时间窗内每个 instance 的 occupancy 是什么样?是不是因为有 prefill workload 帮忙 churn 走?
  • Wall-clock difference attribution用 system metrics 把 PD-disagg 比 8C 慢的 X 秒分解成 (queue_wait + decode + transfer + ...)
  • 看 vllm log 里有没有 "scheduler skipped due to no available KV blocks" 之类事件

预期写一段:

"在 4P+4D 配置下D 池在 trace 第 X 秒到第 Y 秒持续超过 90% 占用,这段时间 prefill 完成的请求(来自 P 池)平均排队 Z 秒才能进入 decode导致 TTFT p90 从 8C 的 18s 涨到 60s。在 8C 配置下相同时刻 KV 池只到 60%,因为 prefill 完成后 immediately decode 而不需要排队 admission。"


Phase 3 — MB4 cache-reuse × PD-routingsecondary

只在 H1 没被钉死的情况下才优先做;否则当 supporting 实验。

  • 4P+4D 固定,扫 P-routinground-robin / session-sticky / kv-aware
  • APC, P-pool per-worker hotspot, end-to-end TTFT
  • 预期round-robin 丢 ~23pp APCsticky P 池复现 §3.3 hot pin

Phase 4 — 可选 scale-out16 GPU on dash1+dash2

  • Phase 1 结论稳定后才动
  • 配置16C / 8P+8D / 4×(2P+2D)(节点内 disagg + 跨节点协调)
  • 用 cost model如有外推 80 GPU

时间表(粗估)

  • Phase 0infrastructure: 2-3 天 — 调研 vllm 标准部署 + 改 launcher + 加 metrics 采样
  • Phase 1MB5+3 sweep: 1 天跑 + 1 天分析 = 2 天
  • Phase 2system analysis 写 paper section: 1-2 天
  • Phase 3MB4: 2-3 天(可选)

总计:~1 周钉死 H1 + Phase 2 写作。


Notes / open questions

  • vLLM 0.18.1 kv_consumer mode 的 bootstrap_server AttributeError 这次必须正面处理 —— 因为 standard PD-disagg 部署典型用 producer/consumer 角色,不是 kv_both
  • D-pool occupancy timeline 是否要补到 MB3 的实验范围里?我倾向 yesPhase 1 自然就 cover
  • Cost modeltask #12是否还需要做取决于 Phase 1 结论是否需要 analytical 外推