diff --git a/docs/V2_DEEP_ANALYSIS_ZH.md b/docs/V2_DEEP_ANALYSIS_ZH.md new file mode 100644 index 0000000..2a2e279 --- /dev/null +++ b/docs/V2_DEEP_ANALYSIS_ZH.md @@ -0,0 +1,549 @@ +# KVC v2 深度分析:相对 TEAM_REPORT 基线的改进、性能、新暴露的问题 + +**日期**:2026-05-11 +**对象**:项目团队同学 +**基线**:`docs/TEAM_REPORT_AGENTIC_PD_HYBRID_ZH.md`(v3-v6 ts=10 调优 sweep 的状态报告) +**新数据**: +- `docs/REFACTOR_PLAN_V1_ZH.md`(ts=1 4-run validation 结果) +- `docs/MIGRATION_V1_FINDINGS_ZH.md`(v1 thrashing 诊断) +- `docs/V2_RESULTS_ZH.md`(v2 reset-on-success + threshold tuning 结果) +- Critic agent 的对等性审查(本文 §4) + +**目的**:把"TEAM_REPORT 之后的实验产物"按改进 / 性能 / 新问题三段重新审视,明确哪些原结构性问题被消解、哪些被掩盖、哪些是新引入的。 + +--- + +## 0. TL;DR + +1. **TEAM_REPORT 头条结论"真实 agentic workload 上 KVC 无配置能赢 naive DP"在 ts=1 下被推翻**——KVC v2 在 7 项 headline 指标上击败 4DP CA。 +2. **但"赢"的归因高度混杂**——critic agent 审查后发现至少 3 处对等性破坏:TTFT p99 被刻意省略、error 统计口径不一致、KVC 的 fast-path 测量的工作量比 DP 少 6.9×。 +3. **TEAM_REPORT §1(session pin 饿死)已被 v2 修好**——direct-to-D 从 42.8% 涨到 91.6%,max D-changes 控制在 45(仅 1 个 session)。但 reset-on-success 这条修复路径是事后补的——v1 直接加 migration 制造了更严重的 thrashing 失效模式。 +4. **TEAM_REPORT §2/§3/§4/§5(LRU / backpressure / P-side imbalance / admission RPC 干扰)在 ts=1 下全部消失**——但是被 ts=1 的"低压自然 drain time"吸收,不是机制层面修好。一旦回到 ts=10 / 更长 trace / 更紧容量,会全部复现。 +5. **新暴露 3 个 ts=10 时代没看到的问题**: + - TTFT p99 反向恶化(KVC 1.285s vs DP 0.427s,**3.0×**)来自 8.3% 非 direct-to-D 路径的 mooncake reseed 代价 + - 对 4DP 比较存在拓扑不对等(KVC 的 1P + 3D 中 prefill GPU 在 91.7% 时间内闲置) + - 缺乏 naive 1P3D 对照(vanilla SGLang xPyD),无法区分"KVC 层贡献"vs"1P3D 拓扑贡献" +6. **结论**:v2 是项目第一次让 KVC 在 SWE workload 上证明价值,但当前对 DP 的胜利不能直接外推到 "KVC 机制本身优越"。需要 3 个补充对照才能站住。 + +--- + +## 1. 三组新实验与 TEAM_REPORT 的关系 + +### 1.1 时间线和因果链 + +``` +TEAM_REPORT (2026-05-06) + ├─ §1-§7 列出 ts=10 数据下的 7 类结构性问题 + ├─ 头条结论:KVC 全配置输 DP,需要重构 + └─ 提出 backpressure 作为最小代码修复点 + + ↓ 2 天 + +ts=1 validation (2026-05-07) + 4 个 run:KVC 1P3D N=3 + 4DP CA × 1,全部 ts=1 + ├─ 发现 1:ts=1 下 errors 从 372-912 跌到 5(DP 也 5 个,是 trace input-超限 artifact) + ├─ 发现 2:ts=1 下 KVC 在 categorical 层面完全确定(0/4449 records 跨 run 不同) + ├─ 发现 3:KVC 整体仍然慢 DP 9% / TTFT 慢 47% + └─ 结论:TEAM_REPORT §2/§3/§4/§5 是 ts=10 高压 artifact;§1 仍然是真问题(被 ts=1 衰减但不消失) + + ↓ 1 天 + +v1 migration (2026-05-08) + KVC 1P3D + rejection blacklist(policies.py 加 session_d_rejects Counter) + ├─ 修复 §1(session pin)——18/52 starved 降到 0 + ├─ 但引入新失效模式:6 个 session 跨 3 D 严重 thrash(max 116 次切换) + ├─ Lat mean 反退化到 1.758s,TTFT mean 涨到 0.419s + └─ 中期诊断:blacklist 永久累积 + degenerate fallback 形成 self-amplifying 死循环 + + ↓ 1 天 + +v2 migration (2026-05-09) + v1 + reset-on-success + --kvcache-direct-max-uncached-tokens 2048→8192 + ├─ Thrashing 消除(max D-changes 116→45,severe thrashing 0) + ├─ direct-to-D 53.3%→91.6%(threshold 拉高让大 append 也走快路径) + ├─ Lat / TTFT 全面赢 baseline,且 7/8 头部指标赢 4DP + └─ 但 N=1 + critic 发现的对等性问题(见 §4) + + ↓ 2 天 + +本文 (2026-05-11) + 把上述 5 天的数据放回 TEAM_REPORT 的结构性问题清单上做审计 +``` + +### 1.2 同 trace 全部数字总表(按时间) + +来源:`outputs/qwen3-30b-tp1-*` 系列各 summary.json。**4449 reqs / 52 sessions / Qwen3-30B-A3B (TP1) / 4×H100 80GB**。 + +| 阶段 | 时间尺度 | 配置 | Errors | Lat mean | Lat P50 | Lat P99 | TTFT mean | TTFT P50 | direct-to-D% | +|---|---|---|---:|---:|---:|---:|---:|---:|---:| +| **TEAM_REPORT baseline 区间(全部 ts=10)** | | | | | | | | | | +| v5 1P7D Option D | 10 | KVC | 9 | 5.18s | 1.59s | 26.09s | 0.207s | – | 45% | +| v5 2P6D Option D | 10 | KVC | 9 | 3.49s | 1.31s | 24.92s | 0.244s | – | 41% | +| v5 rerun1 (重测) | 10 | KVC | **372** | 3.50s | 1.11s | 19.49s | 0.147s | – | ~40% | +| v5 rerun2 | 10 | KVC | **912** | 3.00s | 0.94s | 20.37s | 0.071s | – | ~40% | +| v5 rerun3 | 10 | KVC | **396** | 3.42s | 1.22s | 18.97s | 0.183s | – | ~40% | +| 8-way DP CA | 10 | DP-colo | **0** | **1.43s** | **0.65s** | **8.37s** | **–** | **0.093s** | – | +| **ts=1 validation 区间** | | | | | | | | | | +| v0 baseline run1 | 1 | KVC 1P3D | 5 | 1.574s | 0.811s | 8.70s | 0.245s | 0.124s | **42.8%** | +| v0 baseline run2 | 1 | KVC 1P3D | 5 | 1.573s | 0.809s | 8.74s | 0.243s | 0.120s | 42.8% | +| v0 baseline run3 | 1 | KVC 1P3D | 5 | 1.574s | 0.812s | 8.76s | 0.243s | 0.123s | 42.8% | +| 4-way DP CA | 1 | DP-colo | 0 | 1.443s | 0.659s | 8.43s | 0.129s | **0.090s** | – | +| **Migration 区间** | | | | | | | | | | +| v1 migration | 1 | KVC 1P3D | 6 | 1.758s | 0.773s | 9.92s | 0.419s | 0.057s | 53.3% | +| **v2 migration (头条)** | 1 | KVC 1P3D | 5 | **1.432s** | **0.576s** | **8.69s** | **0.098s** | **0.042s** | **91.6%** | + +**两组关键对比**: + +1. **ts=10 → ts=1(同 KVC 配置)**:Lat mean 5.18s → 1.574s(**3.3× 改善**);errors 9-912 → 5(**~100× 改善**);direct-to-D 41% → 42.8%(持平,机制不变) +2. **v0 → v2(同 ts=1,机制改进)**:Lat mean 1.574s → 1.432s(**9% 改善**);TTFT mean 0.245s → 0.098s(**60% 改善**);direct-to-D 42.8% → 91.6%(**+48.8 pp**) + +**TEAM_REPORT 时代被认为"机制不可用"的 KVC,把 trace 时序还原到 ts=1 + 修两个旋钮后,赢了同 scale 下的 4DP。** + +--- + +## 2. TEAM_REPORT §1-§9 的逐项更新 + +按原始优先级排序,每条标注"是否仍是问题 / 被什么消解 / 残留风险"。 + +### 2.1 §1:KvAwarePolicy 不感知 D 容量 + Session 永久 pin — **被 v2 修好** + +| 维度 | TEAM_REPORT 状态 | v2 状态 | 修复机制 | +|---|---|---|---| +| 跨 run 一致饿死 session 数 | 13/52(25%) | 0 | `policies.py: session_d_rejects` + `replay.py: reset-on-success`:每次 direct-to-D 成功清零 reject 计数,连续失败累积到阈值 3 才迁移 | +| Avg distinct-D / session | 1.00 | <2(v2 实测 mean=0.6 D-changes/session) | 同上 | +| direct-to-D % | 41% | 91.6% | 同上 + threshold 2048→8192 | +| 饿死 session 单 turn 慢 6× | 是 | 否(饿死消失) | – | + +**残留风险**:reset-on-success 是 reactive 修复——session 必须先经历 N 次失败才迁移,并且第一次失败的那个 turn 仍然慢。在严苛容量下(如把 trace 改成 ts=2 或 sess 数翻倍),迁移阈值可能频繁触发,重新逼近 v1 的 thrashing 区域。**未在更紧 workload 上验证。** + +### 2.2 §2:D 端 LRU 跟不上 → 8% errors — **被 ts=1 自然吸收** + +| 维度 | TEAM_REPORT 状态 | v2 状态 | 原因 | +|---|---|---|---| +| 单 run KVTransferError | 369 次 | 0 次(无 mooncake timeout) | ts=1 inter-turn gap p50 = 2.5s 给 D 充分 drain 时间 | +| D 峰值 token_usage | 6 个 D 全顶到 0.97-1.00 | 偶发 0.97-1.00(burst),常态 0.4-0.85 | 同上 | +| LRU trim 触发次数 | 9-43(远不够) | 不需要——D 自然回落 | ts=1 工作流 | + +**残留风险**:这条**没有机制层面修好**。把 ts 调回 10、或者 session 数从 52 增到 100+、或者 model 切到更大、都会立刻让 D 容量重新顶死,LRU 再次跟不上。**TEAM_REPORT §2 是潜在的,不是消失的。** + +### 2.3 §3:无 D→Replay backpressure — **代码已写但冷藏** + +| 维度 | TEAM_REPORT 状态 | v2 状态 | +|---|---|---| +| 代码实现 | 提议 | 已合入:`--enable-backpressure` flag、`recommended_pause_ms` 字段、`_compute_backpressure_pause_hint` | +| 是否启用 | – | 默认 **off** | +| 启用后效果 | 预期 errors 370→<50 | 未验证(ts=1 下无作用对象) | + +**残留风险**:代码冷藏意味着发生在生产 RDMA / 更大 trace 上的回归不会触发保护。**如果团队决定项目要支持 ts=10 / 更大 sessions,需要把 backpressure 默认 on 并补 smoke 验证。** + +### 2.4 §4:P-side round-robin 不感知 D 健康 — **1P 配置不可测** + +v2 是 1P3D,单 P,无从测试 P-side 调度。TEAM_REPORT 数据来自 2P6D 配置。 + +**残留风险**:未来如果扩到 2P+ 必须重新审查 P 侧调度。**当前数据无法支持也无法反驳。** + +### 2.5 §5:Admission RPC 与 scheduler 互相干扰 — **ts=1 下不显著** + +TEAM_REPORT 现象(1Hz polling 让 errors 涨 46×)来自 ts=10 高压时的 scheduler 主循环争抢。ts=1 下 D scheduler 大部分时间空闲,RPC 进来不阻塞 batched prefill。 + +**残留风险**:与 §2 同源——属于 ts=10 高压 artifact。 + +### 2.6 §6:time-scale=10 失真 — **DONE,作为前置条件锁定** + +| 现象 | ts=10 | ts=1 | 比例 | +|---|---:|---:|---:| +| Errors | 372-912 | 5(trace input-超限 artifact) | **74×↓** | +| TTFT P50 | 0.07-0.18s | 0.04s | 4.5×↓ | +| Per-D spread | ±26% | ±3.8% | 7×↓ | +| Lat P99 | 18-29s | 8.7s | 2-3×↓ | + +**REFACTOR_PLAN_V1 把这条当作所有后续讨论的前置条件——ts=10 数据从此不参与 KVC vs DP 比较。** + +### 2.7 §7:execution_mode 标签错位 — **部分修复** + +`pd-router-fallback-large-append-*` 在 v1+ 被细分成: +- `pd-router-fallback-real-large-append-session-cap`(实际 append > 阈值) +- `pd-router-fallback-session-not-resident-session-cap`(session 在该 D 上没住过) +- `pd-router-fallback-no-d-capacity`(D 全满) +- `pd-router-fallback-session-not-resident-seed-filter-early-turn` + +**残留**:error_count 在 KVC vs DP 之间口径不一致(见 §4.3),未统一。 + +### 2.8 §8:N=1 不可信 — **ts=1 下规则改写** + +| Trace 区间 | N 要求 | +|---|---| +| ts=10 高压 | N≥3(v5 rerun 显示 errors 漂移 2.5×) | +| ts=1 常规 | N=1 可信(baseline N=3 显示 0/4449 records 跨 run 不同) | + +**残留**:v2 引入了新代码路径(reset-on-success + threshold=8192)但仅 N=1。新分支是否仍保持 categorical 确定性**未验证**。这是 critic 标 MINOR 但未关闭的点。 + +### 2.9 §9:microbench 把 KVC 失效条件全规避 — **保留为方法学原则** + +v2 的胜利证明 microbench 的"赢 PD disagg"在 SWE-Bench 上也能复现,但 TEAM_REPORT §2.9 的方法学原则仍然成立——micro-benchmark 应该主动构造能触发 fallback 的 workload。 + +--- + +## 3. v2 的真实性能拆解(path-level) + +v2 整体跑得快不仅因为 "KVC 机制好",更因为 **91.6% 请求被路由到了几乎免费的 fast path**。需要看路径级细节才能理解胜利的来源。 + +### 3.1 v2 内部 execution_mode 分布 + +``` +kvcache-direct-to-d-session 4076 (91.6%) ← 快路径 +pd-router-d-session-reseed 150 (3.4%) ← 慢路径:mooncake reseed +pd-router-fallback-session-not-resident-session-cap 50 (1.1%) +pd-router-fallback-session-not-resident-seed-filter-early-turn 52 (1.2%) +pd-router-turn1-seed 52 (1.2%) +pd-router-fallback-no-d-capacity 31 (0.7%) +pd-router-fallback-real-large-append-session-cap 25 (0.6%) +其余 ~13 (<0.3%) +``` + +### 3.2 path-level 延迟 vs DP + +| Path | n | 占比 | TTFT P50 | TTFT P99 | Lat P50 | +|---|---:|---:|---:|---:|---:| +| KVC `direct-to-d-session` | 4076 | 91.6% | **42ms** | 89ms | 0.470s | +| KVC `d-session-reseed` | 150 | 3.4% | ~1.0s | 7.51s | ~2.5s | +| KVC `no-d-capacity` fallback | 31 | 0.7% | ~1.0s | 7.66s | ~3.0s | +| KVC `session-not-resident-*` | 102 | 2.3% | 0.3-2.3s | – | 1-3s | +| DP `dp-colo-router` | 4449 | 100% | 90ms | **427ms** | 0.659s | + +**关键事实**: +- KVC 的 91.6% fast path 在 TTFT 上确实碾压 DP(42ms vs 90ms) +- 但 KVC 的 8.4% slow path 比 DP 慢 7-17 倍(1-7s vs 0.4s) +- DP **没有 slow path**——每个请求在本地 worker 完整 prefill,最坏情况也是 P99 8s 量级 + +### 3.3 Fast path 的工作量比 DP 少 6.9× —— 不是 mechanism 更快 + +| 路径 | Mean uncached tokens | +|---|---:| +| KVC direct-to-D | **341** | +| DP dp-colo-router | **2355** | + +**KVC 之所以快**,是因为 91.6% 请求的 prefix KV **已经在目标 D 上**,本次只需 append 平均 341 token;DP 同样请求要 prefill 平均 2355 token(**6.9× 工作量**)。 + +这是结构性的 KVC vs DP 差异——**KVC 的设计就是利用 session 间 KV 复用**,所以"工作量少"本身就是机制核心目标。但在比较时必须诚实: + +> KVC 的 TTFT 优势 = **session-aware 路由减少了 prefill 工作量**,**不是** D 端硬件层面更快。 + +如果工作量做归一化(比如限定都做 2000 token 以上 uncached prefill),KVC 应该和 DP 在同一速度量级。 + +--- + +## 4. v2 暴露的新结构性问题(critic 审查发现) + +Critic agent 对 v2 vs 4DP 的对等性做了 10 项审查。下面只列 MAJOR / CRITICAL 级别。 + +### 4.1 TTFT p99 被刻意从 headline 表删除 — **MAJOR** + +`docs/V2_RESULTS_ZH.md §2` 的 headline table 列了:lat mean/p50/p90/**p99**、TTFT mean/p50/**p90**。**TTFT p99 是表里缺失的那一项**。 + +实测数字: + +| 指标 | KVC v2 | DP | Ratio | +|---|---:|---:|---:| +| TTFT p50 | 0.042s | 0.090s | 0.47× (KVC 优) | +| TTFT p90 | 0.091s | 0.252s | 0.36× (KVC 优) | +| **TTFT p99** | **1.285s** | **0.427s** | **3.01× (DP 优)** | +| **TTFT p99.5** | **2.65s** | **0.485s** | **5.47× (DP 优)** | +| **TTFT > 1s 计数** | **59** | **9** | **6.5× (DP 优)** | + +**Lat p99 (DP 仅胜 3%) 在表中保留,TTFT p99 (KVC 输 3 倍) 被删除——cherry-picking 嫌疑。** + +### 4.2 TTFT p99 恶化的根因:8.3% 非 direct 路径的 mooncake reseed + +59 个 TTFT > 1s 请求的 mode 分布: +``` +49 个 pd-router-d-session-reseed (83%) ← session 被驱逐/迁移后重新拉 KV + 5 个 pd-router-fallback-no-d-capacity (8%) + 4 个 pd-router-fallback-session-not-resident-session-cap (7%) + 1 个 pd-router-fallback-real-large-append-session-cap (2%) +``` + +按 session 分布:88% (52/59) 集中在 5 个超大输入 session(22080 / 44800 / 22400 / 58080 / 45280,input 60-90K)。 + +**机理**:reseed 必须把 session 整段 KV(50-90K tokens)通过 mooncake TCP loopback 从 P 推到 D。单次 transfer 实测 3-7s。DP 没有这条路径,每个请求在本地 worker 直接 prefill,相同 input 量做完只需 0.5-1s。 + +**这是 KVC 机制本身的代价,不是 measurement bug。** 修复方向: +- (a) 用 RDMA 替换 mooncake TCP loopback(生产部署时自然解决) +- (b) D 容量扩大让大 session 永不被驱逐(不可扩展) +- (c) 改 reseed 为增量 fetch(只 transfer overlap 之外的 delta) + +### 4.3 Error 统计口径双向不一致 — **MAJOR** + +文档说"DP 同样有 5 个 input-too-long abort,真实 mechanism errors 双方都是 0"。**两条都错。** + +**错 1:DP 实际有 67 个 abort,不是 5** + +实测 `dp4_metrics.jsonl`: +- sess 6880 turn 133-149:17 个 abort +- sess 35680 turn 125-149:25 个 abort +- sess 39360 turn 125-149:25 个 abort +- 总计 **67 个** + +而 KVC v2 只有 **5 个 ReadTimeout**。原因:DP 的 `--max-input-len` 限制是 87811,KVC 的限制是 92098——DP 在 input>87811 时早就拒了 67 个,KVC 一直服务到 input>92098 才拒 5 个。**这是模型配置不对等,不是机制差异。** + +**错 2:DP 的 67 个 abort 计入 latency stats,KVC 的 5 个 timeout 被排除** + +代码层 `metrics.py:124` 的过滤是 `if row.latency_s is not None`: +- DP 的 67 abort:`error=null` + `finish_reason='abort'` + `latency_s≈0.08s`(fast 400)→ **计入** count=4449 +- KVC 的 5 timeout:`error='ReadTimeout'` + `latency_s=null` → **排除**,count=4444 + +**67 个 ~0.08s 快速失败被算成 DP 的"快请求"**,把 DP 的 p50/mean 数字拉低。**KVC 的 5 个真失败被完全隐藏。** 双向都不诚实。 + +**修复**:要么两边都排除(DP 也按 `finish_reason=abort` 过滤),要么两边都计入(KVC 的 5 个按 `request_timeout_s=300s` 当 timeout 计入 lat)。两套口径都要重算并并列展示。 + +### 4.4 拓扑不对等:KVC 的 prefill GPU 90%+ 时间闲置 — **MAJOR** + +| 拓扑 | GPU 配置 | Decode 容量 | Prefill 利用率 | +|---|---|---|---| +| KVC 1P3D | 1× prefill-only + 3× decode | 3 GPU | ~8.3%(仅 ~373/4449 请求走 P 路径) | +| 4DP CA | 4× fused (P+D 同一 worker) | 4 GPU | 100%(每 req 都用 P+D) | + +`per_prefill_load: prefill-0: 4449` 是 dispatcher 计数,不是实际 GPU 使用。实际 prefill-0 GPU 只在 8.3% 请求时被激活(seed + reseed + fallback 路径)。 + +**结论**:KVC 用了 4 GPU,但实际"工作 GPU"只有 ~3.08 个。如果用同样的 4 GPU 跑 4DP 或者 naive 4D PD-disagg,DP 拓扑里 GPU 是 100% 满载的。**胜率不能直接横向比。** + +**修复对照实验**: +- 跑 KVC 4D0P(取消 prefill 角色,所有 GPU 都做 P+D) +- 或跑 DP 3-worker(限制到 3 GPU) + +### 4.5 Cache fragmentation 是架构差异,不是策略胜利 — **MINOR 但被错误归因** + +| 维度 | DP | KVC v2 | +|---|---|---| +| Cache 分布 | 4 workers 各 ~30M token | 3 D 各 ~43M token | +| 平均 cache 占用比例 | 0.940 | 0.961 | +| Session affinity | hash 路由(自然但弱) | 显式 session→D pin(强) | +| Policy | `kv-aware` | `kv-aware` | + +**两边都跑 kv-aware policy**。差异来自: +- DP 物理 fragment 跨 4 workers:单 session 的 KV 可能落到任意 worker +- KVC 显式 affinity:session 固定到 1 个 D,cache 集中 + +`docs/V2_RESULTS_ZH.md §10` 把这归因为 "kv-aware policy 的胜利"——**错。** kv-aware policy 两边都开。差异是**拓扑 + admission**。 + +### 4.6 v2 N=1 + 新代码路径未验证确定性 — **MINOR** + +TEAM_REPORT §2.8 改写规则后允许 ts=1 N=1,理由是 baseline N=3 显示 0/4449 records 跨 run 不同。 + +但 v2 新增了两条状态可变路径: +- `policies.py: session_d_rejects` Counter(每次失败累积、每次 direct 成功清零) +- `replay.py` 内 reject 触发 condition 改写 + +**新代码引入的非确定性未单独测过。** v2 当前结论严格说基于 N=1。 + +### 4.7 缺乏 naive 1P3D 对照 — **CRITICAL(方法学)** + +**仓库里没有 vanilla SGLang PD disagg 1P3D 的实验数据**。所有 `pd-disaggregation-default` 都是 **1P1D**(2 GPU),全部 ts=10。 + +当前比较是: + +``` +KVC 1P3D (kvc 层 + kv-aware policy + admission) vs 4DP CA (4-way fused) +``` + +但要归因 KVC 层的实际价值,缺少的对照是: + +``` +naive 1P3D (vanilla SGLang xPyD, policy=default, 无 KVC 层) +``` + +没有这个对照就回答不了: +- v2 的胜利有多少来自"P/D 解耦本身"? +- 多少来自"kv-aware session-pin + admission 控制"? +- 当前 KVC vs 4DP 实质混淆**拓扑差异**和**策略差异** + +**这是 critic 列出的唯一 CRITICAL 级问题。** + +--- + +## 5. Fast path / Slow path 的本质:KVC 是 bimodal 系统 + +把 §3 / §4 综合起来,可以把 v2 看作两个不同性质的系统叠加: + +### 5.1 Fast path (91.6%) + +``` +路径:kvcache-direct-to-d-session +工作量:mean 341 token append-prefill in D +延迟特征:TTFT 42ms, Lat 0.47s +机制依赖:session affinity + worker admission + threshold=8192 +``` + +**优势来源**:跳过 P→D mooncake transfer + 跳过 P 端 prefill kernel + 直接 reuse D 上的 prefix cache。 + +### 5.2 Slow path (8.3%) + +``` +路径:reseed / no-d-capacity / session-not-resident +工作量:mean 50-90K token prefill on P + mooncake transfer to D +延迟特征:TTFT 1-7s, Lat 3-12s +触发条件:session 第一次到这个 D、session 被 LRU 驱逐、append 超过 threshold、D 容量满 +``` + +**劣势来源**:mooncake TCP loopback 推 KV 时间随 session size 线性增长。 + +### 5.3 整体表现 = 加权平均 + +``` +v2 mean = 0.916 × 0.47s + 0.084 × ~3.5s = 0.43 + 0.29 = 0.72s (但实测 lat mean 1.43s,差异来自长尾) +v2 p50 = fast path 主导 → 0.576s +v2 p99 = slow path 主导 → 8.69s (KVC) vs 8.43s (DP) 接近 +``` + +**对比 DP**:DP 是 unimodal 系统,每个请求做完整 prefill。TTFT 分布更紧,没有 slow path 长尾。 + +### 5.4 工程含义 + +- **要让 v2 的胜利更扎实**:把 8.3% slow path 比例继续压下来(或加快 reseed) +- **要让 v2 在更高压下不退化**:slow path 容易因为 D 容量紧张反弹回 v0 baseline 形态 +- **当前的 7/8 胜不是稳定均势**:换个 trace、换个模型大小、换个 ts、随时可能让 slow path 占比涨到 20%+ + +--- + +## 6. 综合性能评估 + +把所有 caveats 应用回去,KVC v2 vs 4DP 的实际胜负是: + +### 6.1 重新计算的 headline 表(含 TTFT p99 + 对等口径) + +| 指标 | KVC v2 | 4DP CA | Winner | 说明 | +|---|---:|---:|---|---| +| Lat mean | 1.432s | 1.443s | KVC -0.8% | 微胜,量级内 | +| Lat p50 | 0.576s | 0.659s | KVC -12.6% | 真实优势,但工作量不对等 | +| Lat p90 | 3.615s | 3.641s | KVC -0.7% | 平 | +| Lat p99 | 8.687s | 8.433s | DP +3.0% | 平 | +| TTFT mean | 0.098s | 0.129s | KVC -24% | 工作量不对等放大 | +| TTFT p50 | 0.042s | 0.090s | KVC -53% | 同上 | +| TTFT p90 | 0.091s | 0.252s | KVC -64% | 同上 | +| **TTFT p99** | **1.285s** | **0.427s** | **DP -67%** | **结构性 slow path 代价** | +| Errors(对等口径,含 abort) | 5 | 67 | KVC -92% | DP `max-input-len` 更紧 | + +**修正后实际胜率**:5 项 KVC 胜 / 1 项 DP 胜 / 3 项打平。从"7/8 全胜"修正为"5/1/3"——KVC 仍然是赢家,但不是"全面碾压"。 + +### 6.2 v2 真正解决了什么 / 没解决什么 + +| 项目 | v2 解决度 | +|---|---| +| TEAM_REPORT §1 session pin 饿死 | ✅ 完全消除 | +| TEAM_REPORT §6 ts=10 失真 | ✅ 切到 ts=1 | +| TEAM_REPORT §7 metric 标签错位 | 🟡 部分(KVC 端修了;KVC-vs-DP error 口径仍不一致) | +| TEAM_REPORT §2 D LRU 跟不上 | 🟠 被 ts=1 自然 drain 掩盖,不是机制修好 | +| TEAM_REPORT §3 无 backpressure | 🟠 代码写了但冷藏 | +| TEAM_REPORT §4 P-side 调度 | – 1P 无从测试 | +| TEAM_REPORT §5 admission RPC 干扰 | 🟠 ts=1 下不显著 | +| TEAM_REPORT §8 N=1 不可信 | ✅ 规则改写(ts=1 categorical 确定) | +| **新问题:TTFT p99 reseed 代价** | ❌ 未修复 | +| **新问题:拓扑不对等(1P 90% idle)** | ❌ 未修复 | +| **新问题:缺乏 naive 1P3D 对照** | ❌ 未修复 | + +**6 个 TEAM_REPORT 原问题里:2 个机制修好,1 个部分修,3 个被工作流条件掩盖。同时 v2 引入 3 个新问题。净改善 +(-1)。** + +--- + +## 7. 推荐补做的实验 + +按 ROI 排序。 + +### 7.1 必做(验证当前结论的鲁棒性) + +1. **naive 1P3D ts=1 N=1**(vanilla SGLang xPyD,policy=default 和 policy=kv-aware 各一次) + - 用途:隔离 KVC 层贡献 vs 1P3D 拓扑贡献 + - 工程:~6h GPU × 2 run + - 这是 critic 标的唯一 CRITICAL,**最高 ROI** + +2. **v2 N=2 或 N=3** + - 用途:验证新代码路径(reset-on-success + threshold=8192)下 ts=1 仍 categorical 确定 + - 工程:~11h GPU × 2 run(同时跑双独立 GPU group 也行) + +### 7.2 强烈推荐(清理对等性) + +3. **对等口径重算**(无需新 run,纯分析脚本) + - 把 DP 的 67 个 abort 按 `finish_reason='abort'` 过滤 + - 把 KVC 的 5 个 ReadTimeout 当 300s timeout 计入 lat + - 两套口径并列展示,看 v2 是否仍胜 + +4. **DP `max-input-len` 调到 92098**(与 KVC 一致),重跑 N=1 + - 用途:消除 abort 数量不对等 + - 工程:~5.5h GPU + +5. **headline 表加 TTFT p99**(更新 `V2_RESULTS_ZH.md`) + +### 7.3 看团队带宽(探索 v2 边界) + +6. **threshold sweep**:2048 / 4096 / 8192 / 16384 / 32768,找 trace-specific 最优 +7. **更长 trace(>200 sessions)**:验证 §2.1 残留风险下 v2 的容量边界 +8. **8 GPU 重测**(2P6D KVC v2 vs 8DP CA)在 ts=1 下验证 4 GPU 结论可外推 +9. **真 RDMA**:mooncake TCP loopback 换 RDMA,看 slow path 代价能否压下来 + +### 7.4 不要做的事 + +- **回到 ts=10**:那是 benchmark artifact 主导区间,不代表真实部署 +- **修 §2 D LRU 分层 eviction**:被 ts=1 自然吸收,超出 KISS 边界 +- **修 §3 backpressure 默认 on**:除非要支持 ts=10 / 更紧 workload + +--- + +## 8. 决策点 + +需要团队回答以下问题以确定项目下一步方向: + +| # | 决策 | 选项 | +|---|---|---| +| D1 | 接受 v2 的胜利作为项目 milestone? | Yes / Yes + 补对照 / No 等补完 | +| D2 | 跑 naive 1P3D 对照实验? | Yes / No | +| D3 | 跑 v2 N=2/3 验证确定性? | Yes / No | +| D4 | 重写 `V2_RESULTS_ZH.md` headline 表(加 TTFT p99 + 对等错误口径)? | Yes / No | +| D5 | 修复 KVC vs DP `max-input-len` 不对等? | Yes / No | +| D6 | 启用 backpressure 默认值?(影响未来 workload 韧性) | Off / On | +| D7 | 项目目标是否扩展到 ts=10 / 更长 trace? | 不扩 / 扩 | + +**作者建议**:D1 → Yes + 补对照;D2/D3/D4 → Yes(成本低 + 防止外部审查破防);D5 → Yes;D6 → 暂时 Off,但写明触发回退条件;D7 → 暂时不扩,先把 ts=1 配置稳定。 + +--- + +## 9. 局限与未验证(本文自身) + +1. **4 GPU 缩配**:所有 ts=1 数据都是 4 GPU。8 GPU 时 KVC 2P6D vs 8DP CA 的对比是否同样 KVC 胜未知。 +2. **N=1 for v2**:上文 §4.6 已述。 +3. **单 trace**:所有结论建立在 SWE-Bench 50sess trace 上。其他 agentic workload(写作、研究、多模态)行为未验证。 +4. **Mooncake TCP loopback**:单机环境模拟生产 RDMA。生产环境 transfer 开销显著降低,slow path 占比可能变小,KVC 优势可能放大;也可能引入其他 artifact。 +5. **Critic 审查 N=1**:用了 opus agent 单次审查。完全可能漏掉其他对等性问题。 +6. **§5 的 bimodal 模型是描述而非证明**:尚未做工作量归一化的对照实验来证明"KVC 的 D 端速度本身 ≈ DP"。 + +--- + +## 附录 A:本文数据来源 + +| 章节 | 数据源 | +|---|---| +| §1.2 | `outputs/qwen3-30b-tp1-{ts1-validation, ts1-migration-v1, ts1-migration-v2}/*.json` | +| §2 | TEAM_REPORT §1-§9 原数据 + ts=1 新数据交叉 | +| §3 | v2 metrics.jsonl 按 execution_mode 聚合(直接计算) | +| §4 | Critic agent ID `a34c7673fc5a3fa76` 审查结果 + 本文直接验证 | +| §5 | v2 + DP metrics.jsonl 路径级延迟统计 | +| §6 | 重算自上述数据 | + +## 附录 B:相关文档 + +- `docs/TEAM_REPORT_AGENTIC_PD_HYBRID_ZH.md` — 本文基线(v3-v6 ts=10 状态) +- `docs/REFACTOR_PLAN_V1_ZH.md` — ts=1 验证后的方向决策 +- `docs/MIGRATION_V1_FINDINGS_ZH.md` — v1 thrashing 诊断 +- `docs/V2_RESULTS_ZH.md` — v2 结果原始报告(本文是对它的 critique) +- `docs/AGENTIC_FIT_ANALYSIS_ZH.md` — 早期 fit 分析(§1-§7 来源) +- `docs/STRUCTURAL_VALIDATION_REPORT_ZH.md` — ts=10 结构性 claim 验证 + +## 附录 C:相关代码 + +- `src/agentic_pd_hybrid/policies.py` — `RoutingState.session_d_rejects` + `KvAwarePolicy.migration_reject_threshold` +- `src/agentic_pd_hybrid/replay.py` — `_run_request` reset-on-success + `_fallthrough_reason` 分类 +- `src/agentic_pd_hybrid/metrics.py:124,170` — latency/truncation 过滤逻辑 +- CLI flags: `--kvcache-migration-reject-threshold` / `--kvcache-direct-max-uncached-tokens` / `--enable-backpressure` + +--- + +**核心句**:v2 让 KVC 第一次在 SWE-Bench 上证明了价值——但当前的"胜利"是 KVC 的 fast path 在工作量不对等的对比里赢了 DP,slow path 的 reseed 代价仍是结构性短板。补 3 个对照(naive 1P3D / N≥2 / 对等口径)之后,结论才能站住外部审查。