diff --git a/docs/KVCACHE_CENTRIC_PROGRESS_ZH.md b/docs/KVCACHE_CENTRIC_PROGRESS_ZH.md new file mode 100644 index 0000000..1215ce0 --- /dev/null +++ b/docs/KVCACHE_CENTRIC_PROGRESS_ZH.md @@ -0,0 +1,221 @@ +# KV-cache centric P/D routing 当前进展 + +本文记录当前原型在 SGLang xPyD 上围绕 session-aware / KV-cache-aware P/D routing 的实现、实验结果和阶段性结论。实验日期为 2026-04-24 至 2026-04-25。 + +## 目标和核心假设 + +目标是在单机 8 GPU xPyD 环境中验证:针对 agentic coding workload,session-aware / KV-cache-aware P/D routing 是否能提升端到端延迟。 + +当前重点假设: + +1. 在 PD-disaggregation 下,P 节点和 D 节点可能同时保留同一个 session 的 prefix KV,形成 P/D duplicate。 +2. 如果预测某个 session 后续会 direct-to-D,那么 P 侧在 radix/prefix cache eviction 时可以优先淘汰这部分 prefix cache。 +3. 这样可以给 P 节点释放 cache 空间,提高 P 侧 prefix cache reuse。 +4. 如果 P 侧 reuse 提升后 D 侧开始成为瓶颈,可以通过增加 xPyD 中 D 的配比,也就是增加 y,缓解 decode 侧压力。 + +实验结果表明:第 2、3 点在 P cache 高压 workload 下成立;第 4 点只部分成立,因为瓶颈会从 decode prealloc 转移到 P->D transfer/bootstrap pipeline。 + +## 已实现机制 + +### 1. Trace profile 和 paired comparison + +新增 `agentic_pd_hybrid profile` 子命令和 `src/agentic_pd_hybrid/profile.py`。 + +能力: + +- 统计 trace 的 session 数、turn2+ 数、append tokens、overlap ratio、direct-to-D eligible turn。 +- 对比 baseline/candidate metrics,输出 paired E2E latency delta。 +- 用于解释 micro-benchmark 与 Ali filtered workload 的差异。 + +### 2. P 侧 priority eviction 支持 + +修改 SGLang server args,允许: + +```bash +--radix-eviction-policy priority +``` + +router/replay 支持内部字段: + +- `smg_prefill_priority` +- `smg_decode_priority` + +router 会将内部字段剥离,只把标准 `priority` 分别传给 P/D backend。这样可以让 direct-to-D predicted session 在 P 侧使用更低优先级,例如 `-100`,普通请求使用 `100`。 + +### 3. Kvcache seed/direct admission 控制 + +新增多种 seed/reseed 过滤: + +- `kvcache_seed_max_resident_tokens` +- `kvcache_seed_max_output_tokens` +- `kvcache_seed_min_turn_id` +- `kvcache_seed_only_multiturn_sessions` +- `kvcache_seed_max_inflight_decode` + +新增 P streaming session backup 策略: + +- `release-after-transfer`:P->D transfer 后释放 P 侧 session backup。 +- `capacity-backup`:容量允许时保留 P 侧 backup。 + +当前主实验使用 `release-after-transfer`。 + +### 4. 稳定性修复 + +之前 worker-admission 实验会在 replay 尾部卡住,不写出 metrics。原因是 benchmark 的长 `timeout_s=3600` 同时用于: + +- SGLang stack 启动等待 +- replay client 单请求 +- router 到 P/D backend 的单请求 + +修复后新增: + +- `BenchmarkConfig.request_timeout_s` +- CLI `benchmark-live --request-timeout-s` +- launch plan `router_request_timeout_s` + +当前做法: + +- `timeout_s=3600` 继续用于 SGLang 启动和整体 stack 等待。 +- `request_timeout_s=180` 用于 replay client 和 router 到 P/D backend 的单请求。 +- control-plane probe/open/close session 使用 2s timeout,fail closed。 + +修复效果:worker-admission 从“尾部卡死不落盘”变为“卡住请求记录为 ReadTimeout,整轮实验完成并写 metrics”。 + +## 关键实验结果 + +### P cache pressure 下 priority eviction 是否提升 P 侧 reuse + +配置:2P2D,P `--max-total-tokens 90000`,micro workload 316 requests / 58 sessions。 + +| 配置 | ok/total | mean E2E | p99 | request cached tokens | P log cached tokens | P new-token total | +|---|---:|---:|---:|---:|---:|---:| +| LRU | 314/316 | 28.171s | 43.409s | 8.204M | 7.783M | 2.236M | +| Priority | 314/316 | 28.165s | 41.935s | 8.401M | 7.981M | 2.039M | + +结论: + +- 在 P cache eviction 高频触发时,priority eviction 确实提高 P 侧 prefix reuse。 +- cached tokens 增加约 197k,new prefill tokens 减少约 197k。 +- 但 mean E2E 基本不变,说明性能瓶颈转移到 D decode/transfer。 + +### 增加 D 配比前的 D 侧瓶颈证据 + +2P2D priority pressure 下: + +- decode `#queue-req`:max/mean/p90 = 0/0/0 +- decode token usage:max 0.98,mean 0.842,p90 0.96 +- decode `#transfer-req`:max 7,mean 4.61,p90 7 +- decode `#prealloc-req`:max 21,mean 11.6,p90 21 + +解释: + +- D 侧不是普通 waiting queue 堆积。 +- 真正压力在 token usage、transfer queue 和 prealloc queue。 + +### D scaling:router admission 旧结果 + +| 配置 | ok/total | mean | p50 | p90 | p99 | error | +|---|---:|---:|---:|---:|---:|---:| +| 2P2D | 314/316 | 28.165s | 30.576s | 38.267s | 41.935s | 2 | +| 2P3D | 290/316 | 29.915s | 31.428s | 40.856s | 45.964s | 26 | +| 2P4D | 285/316 | 30.566s | 32.823s | 40.566s | 44.838s | 31 | + +结论: + +- 直接增加 D 不稳定。 +- 2P3D/2P4D 的错误主要来自 `kvcache-centric` seed/direct 路径。 +- 日志显示 decode 侧出现 `WaitingForInput` timeout 和 `KVTransferError`。 + +### D scaling:worker admission + request timeout 修复后 + +配置:P `--max-total-tokens 90000`,priority eviction,worker admission,`request_timeout_s=180`。 + +| 配置 | ok/total | mean | p50 | p90 | p99 | error | +|---|---:|---:|---:|---:|---:|---:| +| 2P2D | 313/316 | 29.838s | 30.742s | 39.641s | 52.506s | 3 | +| 2P3D | 299/316 | 29.349s | 30.569s | 42.161s | 46.113s | 17 | +| 2P4D | 312/316 | 26.442s | 27.759s | 38.197s | 47.970s | 4 | + +对应 decode log 摘要: + +| 配置 | decode usage mean | decode transfer mean | decode prealloc mean | +|---|---:|---:|---:| +| 2P2D | 0.859 | 4.86 | 11.3 | +| 2P3D | 0.877 | 5.70 | 6.92 | +| 2P4D | 0.809 | 5.31 | 3.46 | + +结论: + +- 2P4D + worker admission + request timeout 是当前最好的 D scaling 配置。 +- 相比旧 2P4D,成功率从 285/316 提升到 312/316,mean 从 30.566s 降到 26.442s。 +- 但 p99 仍未稳定改善,tail 仍由 P->D transfer/bootstrap timeout 主导。 +- 2P3D 不稳定,错误 17 个,不适合作为当前推荐配置。 + +## Ali filtered 当前状态 + +Ali filtered small-append trace: + +- 81 requests +- 28 sessions +- 53 turn2+ +- max input 18901 +- max output 1925 +- span 5414s + +PD baseline: + +- ok 81/81 +- mean 9.072s +- p50 7.086s +- p90 21.761s +- p99 26.813s + +Kvcache-centric 在 Ali filtered 上曾出现 58-67 个 router 200 后挂住、无 metrics 的问题。当前 request timeout 和 control-plane timeout 修复后,应重新跑 Ali filtered;在未重跑前,不把 Ali filtered 纳入最终性能结论。 + +## 当前结论 + +1. kvcache centric 可以提高 KV reuse,但需要满足 workload 条件: + - session 有多 turn; + - turn2+ append 较小; + - prefix overlap 高; + - P 侧 cache 有 eviction pressure; + - D 侧 seed/direct admission 不把 transfer pipeline 打爆。 + +2. 不适合的 workload: + - 单 turn 或 session 间隔过长; + - turn2+ append 很大,direct-to-D 不能省掉多少 prefill; + - prefix overlap 低; + - P cache 没有 eviction pressure; + - D transfer/prealloc 已经高压。 + +3. 用户关于 P/D duplicate 的假设部分成立: + - 如果 D session 已经 resident,P 侧对应 streaming session backup 可以视为 duplicate。 + - `release-after-transfer` 可以避免长期保留 P/D 两份 session KV。 + - priority eviction 进一步让 P 在必须 eviction 时优先淘汰 direct-to-D predicted session prefix。 + +4. 但当前机制还没有完全解决性能问题: + - P 侧 reuse 提升后,E2E 不一定改善。 + - 主要原因是 D 侧 transfer/bootstrap pipeline 成为瓶颈。 + - 增加 D 可以降低 prealloc,但不能自动降低 transfer backlog。 + +## 下一步优化方向 + +1. transfer-aware admission: + - seed/direct 不只看 D token capacity,也要看 `decode_transfer_queue_reqs`、`decode_prealloc_queue_reqs`、`decode_retracted_queue_reqs`。 + - 当 transfer queue 高时,应该主动走 PD fallback。 + +2. per-D transfer budget: + - 对每个 D 设置 seed/reseed 并发上限。 + - 不能只按 session residency 或 token headroom 判断。 + +3. P/D ratio 联合调度: + - 2P4D 当前最好,但 P queue 也随 D 增加而上升。 + - 后续需要测试 3P3D、3P4D、4P4D 等组合,确认 P transfer source 是否成为瓶颈。 + +4. Ali filtered 重跑: + - 使用 request timeout 修复后的版本重新跑 Ali filtered。 + - 如果仍然没有收益,需要按 session gap、append size、overlap ratio 分桶分析。 + +5. 更严格的成功率指标: + - 当前不能只看成功请求的 mean/p90。 + - 必须同时报告 ok/total、timeout/error 类型和 tail latency。