Compare commits
3 Commits
feat/d-to-
...
7590e55189
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7590e55189 | ||
|
|
5a2fb8799c | ||
|
|
506d360160 |
364
docs/ONBOARDING_NEXT_AGENT_ZH.md
Normal file
364
docs/ONBOARDING_NEXT_AGENT_ZH.md
Normal file
@@ -0,0 +1,364 @@
|
||||
# 接班 Agent 上手手册
|
||||
|
||||
**对象**:接手本项目的下一个 SWE/research agent
|
||||
**目标**:30 分钟读完后达到当前主 agent 的认知水平,能独立跑对照实验、看懂数据、避开历史坑
|
||||
**作者状态**:本手册定稿于 `kvc-debug-journey-v1-to-v4 @ 506d360`,下一个工作分支是 `feat/d-to-p-sync`
|
||||
|
||||
---
|
||||
|
||||
## 0. 你是谁,你将要做什么(5 行 TL;DR)
|
||||
|
||||
1. 你接手的是 **agentic-pd-hybrid**——SGLang xPyD 基础上加 session-aware KVCache 层的 LLM serving 框架,目标是在多轮长 context coding agent workload 上比 vanilla DP 快
|
||||
2. v2(迁移机制 + threshold tuning)已经在 SWE-Bench 50sess trace ts=1 上**击败 4DP CA** 6/8 个 latency/TTFT 指标,但 **TTFT p99 输 3×**(1.28s vs 0.43s)
|
||||
3. 上一个 agent 已诊断出 TTFT p99 长尾的根因——8.3% 请求走 reseed 慢路径,每次需要 P 重算 prefill + mooncake transfer = 3-7s
|
||||
4. **你的任务**:在有 GPU + IB RDMA 的环境上跑 2 组对照实验,验证 (a) naive 1P3D + kv-aware 相对 KVC 的边际贡献、(b) 启用真 RDMA 后 KVC v2 的 TTFT p99 是否能压到 ~0.7s 量级
|
||||
5. 跑完结果 push 到 `outputs/`,主 agent 会拉下来更新 paper draft 和 future-work 文档
|
||||
|
||||
---
|
||||
|
||||
## 1. 必读文档(按这个顺序读,**不要乱跳**)
|
||||
|
||||
### Level 1:核心 30 分钟(**必读**,读完就能开始干活)
|
||||
|
||||
| # | 文档 | 时长 | 为什么读它 |
|
||||
|---|---|---:|---|
|
||||
| 1 | `docs/PROJECT_OVERVIEW.md` | 5min | 项目目标 + 三种 mechanism(pd-disagg / pd-colo / kvcache-centric)的术语区分 |
|
||||
| 2 | `docs/V2_DEEP_ANALYSIS_ZH.md` §0 (TL;DR) + §6 (生产决策) | 10min | 当前状态最准确的 snapshot——v2 赢什么、输什么、为什么 |
|
||||
| 3 | `docs/KVC_ROUTER_ALGORITHM.md` §1-§3 + §9 | 10min | 形式化的算法(Algorithm 1/2/3)+ 4 个 open questions。**§9 OQ#4 就是你正在解决的问题** |
|
||||
| 4 | `docs/RESEED_SLOW_PATH_AND_D_TO_P_GAP_ZH.md` §0-§2 | 5min | reseed 路径完整时间线(t=0 → t=4550ms),知道每段耗时分别来自哪里 |
|
||||
|
||||
读完上面 4 篇就能跑实验了。如果你时间紧张,**就只读这 4 篇 + 本手册**。
|
||||
|
||||
### Level 2:进阶(**遇到具体问题时再读**)
|
||||
|
||||
| 文档 | 何时读 |
|
||||
|---|---|
|
||||
| `docs/REFACTOR_PLAN_V1_ZH.md` | 想理解为什么从 ts=10 切到 ts=1 |
|
||||
| `docs/MIGRATION_V1_FINDINGS_ZH.md` | 想理解 v1→v2 演化(v1 为何 thrashing,v2 reset-on-success 怎么修的) |
|
||||
| `docs/V2_RESULTS_ZH.md` | v2 原始战报(注意:headline 表略乐观,请优先看 `V2_DEEP_ANALYSIS_ZH.md` 的修订版) |
|
||||
| `docs/V2_DEEP_ANALYSIS_ZH.md` §4 全文 | 论文 reviewer 的对等性挑战 + 我们的辩驳;写 paper 时必读 |
|
||||
| `docs/TEAM_REPORT_AGENTIC_PD_HYBRID_ZH.md` | 想理解 ts=10 时代的 §1-§9 结构性问题清单(很多问题在 ts=1 下消失,但底层机制仍在) |
|
||||
|
||||
### Level 3:归档(**别读**,是历史包袱)
|
||||
|
||||
- `docs/archive/AGENTIC_FIT_ANALYSIS_ZH.md`:ts=10 时代的早期分析,结论已被 ts=1 数据 supersede
|
||||
- `docs/archive/STRUCTURAL_VALIDATION_REPORT_ZH.md`:ts=10 数据下的结构性验证,同上
|
||||
- `docs/archive/KVC_DEBUG_JOURNEY_V1_TO_V5.md`:v1-v5 调优 sweep 的过程笔记,知道有这个文件就行
|
||||
- `docs/archive/V5_PROFILE_INVESTIGATION_ZH.md`:profile 调查,已 supersede
|
||||
- `docs/archive/REFACTOR_PLAN_ZH.md`:v0 重构计划,已被 V1 supersede
|
||||
- `docs/archive/SWEBENCH_EXPERIMENT_*.md`:早期实验日志
|
||||
|
||||
### Level 0:本手册的"姐妹"文档(**读这个之前你应该已经在看本文了**)
|
||||
|
||||
- `docs/ONBOARDING_NEXT_AGENT_ZH.md`(就是本文)
|
||||
|
||||
---
|
||||
|
||||
## 2. 项目当前状态快照(用一张表说清)
|
||||
|
||||
```
|
||||
Trace: outputs/qwen35-swebench-50sess.jsonl (4449 reqs / 52 sessions, time-scale=1.0)
|
||||
Hardware: 4× H100 80GB + Mellanox mlx5_0/_1 @ 200 Gb/s IB (active, but **未启用** in current sweep)
|
||||
Model: Qwen3-30B-A3B-Instruct-2507 (TP1)
|
||||
Branch: kvc-debug-journey-v1-to-v4 = 主分支(v2 已合入)
|
||||
feat/d-to-p-sync = 预留给 D→P 增量同步的开发,**当前空**
|
||||
main = 旧 baseline,比主分支落后 18 commit
|
||||
```
|
||||
|
||||
### 已得出的结论(高置信度)
|
||||
|
||||
1. **v2 (reset-on-success + threshold 8192) 击败 4DP CA**:lat mean -1.4%、p50 -13%、TTFT mean -25%、TTFT p50 -55%、TTFT p90 -67%
|
||||
2. **TTFT p99 KVC 输 3×**:1.28s vs 0.43s。来自 8.3% reseed/fallback 慢路径
|
||||
3. **慢路径耗时五五开**:P 端 re-prefill ~1.5-3s + mooncake P→D transfer ~1.5-4s(**当前是 TCP loopback**,未启用真 RDMA)
|
||||
4. **capacity-backup 救不了 slow path**:直接 audit 过,P 端 backup 不会随 direct-to-D append 更新,是 seed-time 静态快照
|
||||
5. **D→P 增量同步代码不存在**:经 Opus agent forensic 审查 + 全分支 git 检索确认
|
||||
|
||||
### 待验证的核心假设(**这是你的实验任务**)
|
||||
|
||||
| # | 假设 | 验证方法 | 预期结果 |
|
||||
|---|---|---|---|
|
||||
| H1 | KVC v2 相对 4DP 的胜利不只是来自 1P3D 拓扑——KVC 层(admission / migration / direct-to-D)也有显著贡献 | 跑 naive 1P3D + policy=kv-aware ts=1 N=1(vanilla SGLang pd-disagg,无 KVC 层)作为中间对照 | naive 1P3D 应该处于 KVC v2 和 4DP 之间。如果它 ≈ KVC v2 → 胜利来自拓扑而非 KVC 层;如果 ≈ 4DP → 胜利来自 KVC 层 |
|
||||
| H2 | 启用真 RDMA 把 mooncake P→D transfer 从 1.5-4s 压到 200-400ms,TTFT p99 从 1.28s 降到 ~0.7s | 在 v2 sweep 加 `--force-rdma --ib-device mlx5_0`,跑同 trace 同 ts=1 | TTFT p99 应该 ~0.5-0.8s 区间。如果没改变 → mooncake 实际没用 RDMA / 配置错误;如果降到 ~0.3s → 我们对 transfer 段贡献的估计偏低 |
|
||||
| H3 | 即使启用 RDMA,TTFT p99 仍然输 DP(因为 re-prefill 段不动) | 同 H2 实验结果 | 应该看到 TTFT p99 ~0.7s > DP 0.43s。如果 ≤ DP → 我们对 re-prefill 段成本的估计错了,可能整个 slow path 理论需要重审 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 你要跑的实验(the main task)
|
||||
|
||||
### 3.1 实验矩阵(按 ROI 排序)
|
||||
|
||||
GPU hour 珍贵,砍掉了原计划的 naive 1P3D + policy=default baseline(low-ROI——naive 1P3D 用 default policy 在多轮 cache 命中上几乎必败,没必要拿这个对比当 H1 的对照点)。最终保留 2 个 run:
|
||||
|
||||
| # | 配置 | GPU | mechanism | policy | RDMA | 预期时长 | 目的 |
|
||||
|---|---|---:|---|---|---|---:|---|
|
||||
| **E1** | naive 1P3D kv-aware | 4 | pd-disaggregation | kv-aware | **on** | ~5.5h | H1:分离"1P3D + kv-aware policy"贡献 vs "KVC 层(admission/migration/direct-to-D)"贡献 |
|
||||
| **E2** | KVC v2 + RDMA | 4 | kvcache-centric | kv-aware | **on** | ~5.5h | H2/H3:验证 RDMA 能把 TTFT p99 从 1.28s 压到 ~0.7s |
|
||||
|
||||
两个 run 串行约 11h,并行用两组 GPU 可压到 ~5.5h。
|
||||
|
||||
### 3.2 启动配置:详细 flag 清单
|
||||
|
||||
参考 `scripts/sweep_ts1_migration_v2.sh` 作为底版。两个新 sweep 脚本的关键 flag:
|
||||
|
||||
#### E1: naive 1P3D kv-aware
|
||||
|
||||
```bash
|
||||
python -m agentic_pd_hybrid \
|
||||
--mechanism pd-disaggregation \
|
||||
--policy kv-aware \
|
||||
--topology-pd 1P3D \
|
||||
--transfer-backend mooncake \
|
||||
--force-rdma --ib-device mlx5_0 \ # ← 单独测拓扑+policy 而非 transport,必须开 RDMA 才能跟 E2 公平
|
||||
--trace outputs/qwen35-swebench-50sess.jsonl \
|
||||
--time-scale 1.0 \
|
||||
--concurrency 32 \
|
||||
--request-timeout-s 300 \
|
||||
--max-input-len 87811 \ # ← 拉齐到 DP 限,消除 abort 数量不对等
|
||||
--output-root outputs/qwen3-30b-tp1-ts1-naive-1p3d-kvaware
|
||||
```
|
||||
|
||||
#### E2: KVC v2 + RDMA
|
||||
|
||||
参考 `scripts/sweep_ts1_migration_v2.sh`,**只加两个 flag**:
|
||||
|
||||
```diff
|
||||
--transfer-backend mooncake \
|
||||
+ --force-rdma --ib-device mlx5_0 \
|
||||
+ --max-input-len 87811 \
|
||||
--kvcache-direct-max-uncached-tokens 8192 \
|
||||
--kvcache-migration-reject-threshold 3 \
|
||||
--kvcache-prefill-backup-policy release-after-transfer \
|
||||
```
|
||||
|
||||
**保留 v2 的其它所有配置**——这是 v2 + RDMA 的 ablation,**不要顺手改其它东西**。
|
||||
|
||||
### 3.3 实验前的环境验证(**别跳**)
|
||||
|
||||
```bash
|
||||
# 1. GPU
|
||||
nvidia-smi -L # 应该看到 4 张 H100 80GB
|
||||
|
||||
# 2. RDMA
|
||||
ibstat | grep -E "State|Rate|Port"
|
||||
# 期望:mlx5_0 / mlx5_1 都是 State=Active, Rate=200 Gb/s
|
||||
|
||||
# 3. Mooncake 能识别 RDMA 设备
|
||||
python -c "from mooncake_transfer_engine import TransferEngine; e=TransferEngine(); print(e.get_local_topology())"
|
||||
# 期望:输出包含 mlx5_0 / mlx5_1
|
||||
|
||||
# 4. 现有 v2 数据可读
|
||||
python3 scripts/analysis/recompute_summary.py outputs/qwen3-30b-tp1-ts1-migration-v2/kvc_1p3d_migration_v2_run1_metrics.jsonl
|
||||
# 期望:打印出 failure_count=45, abort_count=40 等
|
||||
|
||||
# 5. 算法实现 syntax check
|
||||
python3 -m py_compile src/agentic_pd_hybrid/{policies,replay,metrics,benchmark,cli}.py
|
||||
# 期望:全过
|
||||
```
|
||||
|
||||
任何一步失败**立刻停下来排查**,不要硬上。
|
||||
|
||||
---
|
||||
|
||||
## 4. 已踩过的坑(避免重复)
|
||||
|
||||
| # | 坑 | 症状 | 教训 |
|
||||
|---|---|---|---|
|
||||
| 1 | **abort 被计入 latency stats** | DP/KVC 都有 0.08s 的快速失败被算成"快请求",拉低 mean/p50 | 已在 `metrics.py` 修复(commit `5eac9b4`)。新 run 出 summary 时会自动包含 `abort_count` / `failure_count` 字段 |
|
||||
| 2 | **max-input-len 双方不一致**(KVC=92098 vs DP=87811) | SGLang 按 mem_fraction_static 自动算 max_total_num_tokens,KVC decode-only worker GPU 内存多 2 GB | 跑新 run 时显式传 `--max-input-len 87811` 强制对齐 |
|
||||
| 3 | **mooncake 默认 TCP loopback** | sweep 脚本只传 `--transfer-backend mooncake` 不够,会落到 TCP,跑出来比 RDMA 慢 10× | 必须加 `--force-rdma --ib-device mlx5_0` |
|
||||
| 4 | **capacity-backup 不是 D→P 同步** | flag 名字误导,看代码就会发现它只是"reseed 完不关 P session",KV 是 seed-time 静态快照 | 不要在 capacity-backup 上浪费时间;要真正消灭 reseed 长尾必须实现 D→P,去 `feat/d-to-p-sync` |
|
||||
| 5 | **N=1 在 ts=1 下"够用"是有条件的** | baseline N=3 确认 categorical 完全确定,但 v2 引入的 reset-on-success 等新代码路径未独立验证 | v2 + RDMA 的对照建议 N=2,对 RDMA-on/off 各一次 |
|
||||
| 6 | **ts=10 数据**别参考 | 当年的 372/912/396 errors 是 benchmark artifact,不代表真实生产 | 所有比较锁定 ts=1,不要尝试 ts=10 "复现"或验证 |
|
||||
| 7 | **critic agent 的 "MAJOR" 别盲信** | 上一轮 critic 把 cache fragmentation / prefill 闲置标为 MAJOR,其实是 KVC 的**设计意图** | 详见 `V2_DEEP_ANALYSIS_ZH §4.4 / §4.5`。Audit 视角和生产视角要分清 |
|
||||
| 8 | **GPU utilization 图布局有残留小问题** | 组标签 (KVC 1P3D / DP 4-way CA) 与 subplot title 视觉上仍有轻微挤压 | 已被用户接受为可发表状态。不要再花时间调这张图 |
|
||||
|
||||
---
|
||||
|
||||
## 5. CLI 速查表
|
||||
|
||||
### 跑实验
|
||||
```bash
|
||||
# 完整 sweep(参考 v2)
|
||||
bash scripts/sweep_ts1_migration_v2.sh
|
||||
|
||||
# 写自己的 sweep:复制 sweep_ts1_migration_v2.sh,改 mechanism/policy/output-root
|
||||
```
|
||||
|
||||
### 看数据
|
||||
```bash
|
||||
# 修复版 summary(推荐用这个,旧的 summary.json 含 abort 污染)
|
||||
python3 scripts/analysis/recompute_summary.py outputs/<run>/*_metrics.jsonl
|
||||
|
||||
# 跨配置对照
|
||||
python3 scripts/analysis/analyze_ts1_validation.py # 比较 KVC vs DP ts=1 4-run
|
||||
```
|
||||
|
||||
### 出图(参考 v2 流程)
|
||||
```bash
|
||||
# 4 张已有的图,对应不同 viz 问题
|
||||
python3 scripts/analysis/plot_v2_path_breakdown.py # execution_mode 分布 + path-level latency
|
||||
python3 scripts/analysis/plot_ttft_pdf.py # TTFT PDF (KVC vs DP)
|
||||
python3 scripts/analysis/plot_gpu_utilization.py # GPU 利用率(请求计数 vs 工作量)
|
||||
python3 scripts/analysis/plot_cache_efficiency.py # cache 效率(hit rate vs turn + uncached ECDF)
|
||||
|
||||
# 数据更新后重新出图:直接 rerun,每个脚本都参数化了输入路径
|
||||
```
|
||||
|
||||
### Git
|
||||
```bash
|
||||
# 主分支(实验)
|
||||
git checkout kvc-debug-journey-v1-to-v4
|
||||
|
||||
# 新功能分支(D→P 同步,空)
|
||||
git checkout feat/d-to-p-sync
|
||||
|
||||
# 远程
|
||||
origin = git@ipads.se.sjtu.edu.cn:wangjh/agentic-pd-hybrid.git
|
||||
|
||||
# Push 用 (SSH known_hosts 第一次需要 accept)
|
||||
GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=~/.ssh/known_hosts' git push
|
||||
|
||||
# user.email 没设全局,建议 per-commit 传:
|
||||
git -c user.email=YOUR_EMAIL -c user.name=YOUR_NAME commit -m "..."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 跑完结果后看什么数字(checklist)
|
||||
|
||||
每个 run 跑完,**至少**收集以下几个数字(用 `recompute_summary.py`):
|
||||
|
||||
```
|
||||
☐ request_count (期望 4449)
|
||||
☐ error_count + abort_count + failure_count
|
||||
☐ latency_stats_s.{mean, p50, p90, p99}
|
||||
☐ ttft_stats_s.{mean, p50, p90, p99} ← 别忘 p99!这是 KVC 的真实代价点
|
||||
☐ execution_modes 分布
|
||||
☐ per_decode_load 分布(看负载均衡)
|
||||
☐ per_prefill_load (注意:dispatcher 计数 ≠ GPU 工作量)
|
||||
☐ cache_hit_request_count + total_cached_tokens (推 cache hit rate)
|
||||
```
|
||||
|
||||
### 两组对照实验跑完后看以下"决定性数字"
|
||||
|
||||
| 比较 | 关键看点 | 决策 |
|
||||
|---|---|---|
|
||||
| E1 (naive 1P3D kv-aware) vs E2 (KVC v2 + RDMA) | TTFT p50/p99、direct-to-D 占比 | 量化"KVC 层(admission/migration/direct-to-D)在 kv-aware 之上的额外收益"(H1) |
|
||||
| KVC v2 (TCP, 历史 v2 run) vs E2 (KVC v2 + RDMA) | TTFT p99、reseed mode 的耗时(execution_mode == reseed 的 ttft_s p50) | 验证 H2/H3:RDMA 救多少 transfer 段 |
|
||||
| E1 (naive 1P3D kv-aware) vs DP 4w(历史 ts=1 baseline)| 全部 latency / TTFT 指标 | 间接锚定"拓扑差异 + kv-aware policy"的天花板 |
|
||||
|
||||
### 期待的数字范围(如果实验顺利)
|
||||
|
||||
| 配置 | lat p50 | lat p99 | TTFT p50 | TTFT p99 | direct-to-D % |
|
||||
|---|---:|---:|---:|---:|---:|
|
||||
| **E1** naive 1P3D kv-aware | ~0.75s | ~8-10s | ~0.20s | ~0.8-1.2s | N/A |
|
||||
| **E2** KVC v2 + RDMA | ~0.58s | ~7-8s | ~0.04s | **~0.5-0.8s** | ~91% |
|
||||
| (参考) KVC v2 + TCP(历史) | 0.58s | 8.7s | 0.04s | 1.29s | 91.6% |
|
||||
| (参考) DP 4w(历史 ts=1) | 0.67s | 8.4s | 0.09s | 0.43s | N/A |
|
||||
|
||||
**如果你看到的数字偏离这个范围 ≥ 2×**,先停下来检查配置(环境验证 §3.3 那些项目),不是写报告。
|
||||
|
||||
---
|
||||
|
||||
## 7. 遇到 X 怎么办(FAQ)
|
||||
|
||||
**Q: 跑出来 KVC v2 + RDMA 的 TTFT p99 比预期高很多(> 1s)。**
|
||||
|
||||
A: 大概率 RDMA 没真用上。检查:
|
||||
1. `outputs/<run>/<subdir>/benchmark-config.json` 里 `force_rdma` 是不是 `True`、`ib_device` 是不是 `"mlx5_0"`
|
||||
2. 服务器 startup log(`outputs/<run>/<subdir>/logs/prefill-0.log`)有没有 "MOONCAKE_DEVICE=mlx5_0" / "using RDMA" 类信息
|
||||
3. `ibstat mlx5_0` 看 active 状态没掉
|
||||
|
||||
**Q: KVC v2 + RDMA 跑出来 TTFT p99 ≤ DP(违反 H3)。**
|
||||
|
||||
A: 这是个好消息。可能性:
|
||||
1. 我们对 re-prefill 段耗时估计偏高(实际 SGLang 的 prefix cache 把 P 端 re-prefill 救了一半)
|
||||
2. RDMA 直接快到把 transfer 段压到 ~50ms 量级,整个 reseed < 1.5s
|
||||
3. v2 的 reseed 触发频率被 RDMA 间接降低(某种 race condition 改善了 LRU 行为)
|
||||
|
||||
任一情况都值得**深挖**,建议把 reseed mode 的 `ttft_s` 分布单独拉出来看(应该有清晰的双峰:fast reseed + 极少数 outlier)。
|
||||
|
||||
**Q: naive 1P3D 跑不起来 / SGLang 报错。**
|
||||
|
||||
A: 仓库里 `outputs/qwen3-30b-exps/pd-disaggregation-default-20260427T062616Z/` 有过历史的 1P1D 跑通配置可以参考。常见坑:
|
||||
1. `--mechanism pd-disaggregation` 和 `--topology` 必须配合,topology 不能用 KVC 的 1P3D 名字
|
||||
2. SGLang vendored 在 `third_party/sglang/`,**不要**`pip install sglang` 用外部版本——可能 API 不对齐
|
||||
3. `--policy default` 时不要传 `--kvcache-*` 系列 flag,会被 ignore 但会污染 config 输出
|
||||
|
||||
**Q: 我想跑别的对照(更大 trace / 更多 GPU / 真实 RDMA 跨节点)。**
|
||||
|
||||
A: 先把上面 2 个 E1-E2 跑完。这 2 个是论文核心 contribution 的 ablation,不能跳。其它对照(更长 trace、8 GPU 2P6D、真跨节点 RDMA、补 naive 1P3D + policy=default)见 `V2_DEEP_ANALYSIS_ZH §7.3`,作为 follow-up。
|
||||
|
||||
**Q: 跑完后想自动出对比图。**
|
||||
|
||||
A: 4 个现有 `plot_*.py` 脚本都是参数化的,把输入路径改成你的新 run 就能复用。如果对比维度变多(如三方对比 naive vs KVC vs DP),可以扩展现有脚本而不是新写——见 `plot_ttft_pdf.py` 的模板。
|
||||
|
||||
**Q: 发现 metrics.jsonl 字段不一致 / 缺字段。**
|
||||
|
||||
A: 看 `src/agentic_pd_hybrid/metrics.py` 里 `RequestMetrics` dataclass。所有新增字段必须在那里加,否则 `recompute_summary.py` 会报 KeyError。**注意**:dataclass 的 `field_names` 是按 `RequestMetrics.__dataclass_fields__` 取的,不是 jsonl 里所有 key。
|
||||
|
||||
---
|
||||
|
||||
## 8. 如果你完全卡住
|
||||
|
||||
读这一段:
|
||||
|
||||
1. **不要**尝试在没看本手册 §1 必读文档的情况下硬上代码
|
||||
2. **不要**在 main 分支或 `feat/d-to-p-sync` 上跑实验——用 `kvc-debug-journey-v1-to-v4`
|
||||
3. **不要**修 metrics.py 的统计字段,除非你能解释清楚为什么它当前的 abort 排除是对的
|
||||
4. **不要**信任 critic agent 的"MAJOR"标签,要看代码层证据
|
||||
5. **不要**跳过环境验证(§3.3)直接跑长 sweep——5h 跑出垃圾数据浪费的成本更高
|
||||
|
||||
如果你卡住超过 30 分钟,把卡点写成一句话,去主 agent 留言(git commit message / branch 注释)。
|
||||
|
||||
---
|
||||
|
||||
## 9. 主 agent 留给你的两个具体期待
|
||||
|
||||
1. **两组对照实验跑完后**,在新 commit message 里给我以下数字(用 `recompute_summary.py` 输出格式):
|
||||
```
|
||||
E1 naive 1P3D kv-aware: lat={mean,p50,p90,p99} ttft={mean,p50,p90,p99} fail_count
|
||||
E2 KVC v2 + RDMA: 同上 + reseed-mode 的 ttft p50/p99 分开
|
||||
```
|
||||
|
||||
2. **跑 E2 时收集 reseed 路径的实测耗时分布**:
|
||||
```
|
||||
pd-router-d-session-reseed 这个 execution_mode 的 ttft_s 分布
|
||||
并把 P→D mooncake transfer 时长 vs P 端 re-prefill 时长 单独拉出
|
||||
(需要在 structural/admission-events.jsonl 里找 timestamp diff)
|
||||
```
|
||||
|
||||
这两组数字直接决定 paper future-work 章节怎么写 D→P sync 的必要性。
|
||||
|
||||
---
|
||||
|
||||
## 附录 A:关键文件位置速查
|
||||
|
||||
| 你在找什么 | 在哪 |
|
||||
|---|---|
|
||||
| 算法实现 | `src/agentic_pd_hybrid/policies.py` (KvAwarePolicy + RoutingState) |
|
||||
| 整个 replay orchestration | `src/agentic_pd_hybrid/replay.py` (~3000 行,**慢慢读**) |
|
||||
| 指标统计 | `src/agentic_pd_hybrid/metrics.py` |
|
||||
| CLI 入口 | `src/agentic_pd_hybrid/cli.py` |
|
||||
| Server 启动配置 | `src/agentic_pd_hybrid/stack.py` |
|
||||
| SGLang 改动 | `third_party/sglang/python/sglang/srt/{managers/scheduler.py, managers/io_struct.py, disaggregation/mooncake/...}` |
|
||||
| 历史 sweep 脚本 | `scripts/sweep_ts1_*.sh` |
|
||||
| 分析脚本 | `scripts/analysis/*.py` |
|
||||
| 实验输出 | `outputs/qwen3-30b-tp1-ts1-*/` |
|
||||
|
||||
## 附录 B:关键 commit 速查(按"想理解什么改动看什么 commit"组织)
|
||||
|
||||
| 想理解 | 看 commit |
|
||||
|---|---|
|
||||
| v2 的核心改动 | `2ec0deb feat(kvc): session migration with reset-on-success + direct-append threshold tuning` |
|
||||
| metrics.py 修复 | `5eac9b4 fix(metrics): exclude aborted requests from latency/ttft/tpot stats` |
|
||||
| 完整 analysis 文档(多版本叠加修订)| `c01d610` (latest) / `9ccd853` / `b5af195` / `c551906` / `517677d` |
|
||||
| 算法形式化定义 | `37e9caa docs(kvc): production-decision reframe + formal router algorithm spec` |
|
||||
| 各种 figure 脚本 | `c551906` (TTFT PDF) / `b5af195` (path breakdown) / `517677d` (GPU + cache) |
|
||||
| backpressure 代码 | `c47adaf feat(kvc): honor admission backpressure hints` 和 `ca4b64c feat(sglang): expose backpressure pause hint` |
|
||||
|
||||
---
|
||||
|
||||
**核心句**:先读 §1 Level 1 的 4 篇文档(30 min)+ 本手册(30 min),然后按 §3 跑 E1/E2/E3 三组实验,按 §6 收集决定性数字,遇到坑查 §4,结果 push 到 `outputs/` 下。**别瞎改不属于本任务的代码**——你的工作是验证 v2 的胜利在 ablation 中是否站得住,不是开发新机制(那是 `feat/d-to-p-sync` 分支的事,下一阶段才做)。
|
||||
|
||||
跑完之后期待你的 commit!
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
**日期**:2026-05-08
|
||||
**前置文档**:
|
||||
- `docs/REFACTOR_PLAN_ZH.md`(v0,已被本文 supersede——v0 的 backpressure 切入点结论已撤回)
|
||||
- `docs/archive/REFACTOR_PLAN_ZH.md`(v0,已被本文 supersede——v0 的 backpressure 切入点结论已撤回)
|
||||
- `docs/TEAM_REPORT_AGENTIC_PD_HYBRID_ZH.md`(包含 §1-§7 结构性问题清单)
|
||||
- `docs/STRUCTURAL_VALIDATION_REPORT_ZH.md`(ts=10 数据下的早期验证)
|
||||
- `docs/archive/STRUCTURAL_VALIDATION_REPORT_ZH.md`(ts=10 数据下的早期验证)
|
||||
|
||||
**触发**:`outputs/qwen3-30b-tp1-ts1-validation/` 4 个 run 完成(KVC 1P3D × N=3 + 4DP CA × 1,全部 ts=1)
|
||||
|
||||
@@ -372,11 +372,11 @@ score = (
|
||||
## 附录 B:相关文档
|
||||
|
||||
- `docs/TEAM_REPORT_AGENTIC_PD_HYBRID_ZH.md` — §1-§7 原结构性问题清单
|
||||
- `docs/REFACTOR_PLAN_ZH.md` — v0 重构计划(本文 supersede)
|
||||
- `docs/AGENTIC_FIT_ANALYSIS_ZH.md` — 早期 fit 分析(§1-§7 来源)
|
||||
- `docs/STRUCTURAL_VALIDATION_REPORT_ZH.md` — ts=10 结构性 claim 验证
|
||||
- `docs/KVC_DEBUG_JOURNEY_V1_TO_V5.md` — v1→v5 演进
|
||||
- `docs/V5_PROFILE_INVESTIGATION_ZH.md` — v5+profile 调查(已 critic 修订)
|
||||
- `docs/archive/REFACTOR_PLAN_ZH.md` — v0 重构计划(本文 supersede)
|
||||
- `docs/archive/AGENTIC_FIT_ANALYSIS_ZH.md` — 早期 fit 分析(§1-§7 来源)
|
||||
- `docs/archive/STRUCTURAL_VALIDATION_REPORT_ZH.md` — ts=10 结构性 claim 验证
|
||||
- `docs/archive/KVC_DEBUG_JOURNEY_V1_TO_V5.md` — v1→v5 演进
|
||||
- `docs/archive/V5_PROFILE_INVESTIGATION_ZH.md` — v5+profile 调查(已 critic 修订)
|
||||
- `scripts/sweep_ts1_kvc_n3_plus_dp.sh` — 本次 4 run sweep 脚本
|
||||
- `scripts/analysis/analyze_ts1_validation.py` — 本次分析脚本
|
||||
|
||||
|
||||
@@ -633,9 +633,9 @@ errors 漂移 **2.5×**(372→912),P50 latency 漂移 ~30%,TTFT P50 漂
|
||||
## 附录 B:相关已有文档
|
||||
|
||||
- `docs/PROJECT_OVERVIEW.md` — 项目目标、microbench 结论
|
||||
- `docs/AGENTIC_FIT_ANALYSIS_ZH.md` — 结构性缺陷的早期分析(本报告 §2 的来源)
|
||||
- `docs/KVC_DEBUG_JOURNEY_V1_TO_V5.md` — v1→v5 详细演进日记
|
||||
- `docs/V5_PROFILE_INVESTIGATION_ZH.md` — v5+profile 调查(含 critic 修订)
|
||||
- `docs/SWEBENCH_EXPERIMENT_RESULTS.md` — SWE 35B 早期实验
|
||||
- `docs/REFACTOR_PLAN_ZH.md` — 当前重构计划
|
||||
- `docs/STRUCTURAL_VALIDATION_REPORT_ZH.md` — 结构性 claim 验证(本报告的精简版)
|
||||
- `docs/archive/AGENTIC_FIT_ANALYSIS_ZH.md` — 结构性缺陷的早期分析(本报告 §2 的来源)
|
||||
- `docs/archive/KVC_DEBUG_JOURNEY_V1_TO_V5.md` — v1→v5 详细演进日记
|
||||
- `docs/archive/V5_PROFILE_INVESTIGATION_ZH.md` — v5+profile 调查(含 critic 修订)
|
||||
- `docs/archive/SWEBENCH_EXPERIMENT_RESULTS.md` — SWE 35B 早期实验
|
||||
- `docs/archive/REFACTOR_PLAN_ZH.md` — 当前重构计划
|
||||
- `docs/archive/STRUCTURAL_VALIDATION_REPORT_ZH.md` — 结构性 claim 验证(本报告的精简版)
|
||||
|
||||
@@ -609,8 +609,8 @@ v2 p99 = slow path 主导 → 8.69s (KVC) vs 8.43s (DP) 接近
|
||||
- `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 验证
|
||||
- `docs/archive/AGENTIC_FIT_ANALYSIS_ZH.md` — 早期 fit 分析(§1-§7 来源)
|
||||
- `docs/archive/STRUCTURAL_VALIDATION_REPORT_ZH.md` — ts=10 结构性 claim 验证
|
||||
|
||||
## 附录 C:相关代码
|
||||
|
||||
|
||||
@@ -271,8 +271,8 @@ p99 +3% 几乎全部来自这 5 个 timeout(每个 ~30s 拉到 p99)。**修
|
||||
- `docs/TEAM_REPORT_AGENTIC_PD_HYBRID_ZH.md` — §1-§9 原结构性问题清单
|
||||
- `docs/REFACTOR_PLAN_V1_ZH.md` — 重构方向 + 三情景分支
|
||||
- `docs/MIGRATION_V1_FINDINGS_ZH.md` — v1 thrashing 诊断
|
||||
- `docs/AGENTIC_FIT_ANALYSIS_ZH.md` — 早期 fit 分析
|
||||
- `docs/STRUCTURAL_VALIDATION_REPORT_ZH.md` — ts=10 结构性 claim 验证
|
||||
- `docs/archive/AGENTIC_FIT_ANALYSIS_ZH.md` — 早期 fit 分析
|
||||
- `docs/archive/STRUCTURAL_VALIDATION_REPORT_ZH.md` — ts=10 结构性 claim 验证
|
||||
- `scripts/sweep_ts1_migration_v2.sh` — 本次 v2 sweep 脚本
|
||||
- `scripts/analysis/analyze_ts1_validation.py` — ts=1 4-way 对比分析
|
||||
|
||||
|
||||
34
docs/archive/README.md
Normal file
34
docs/archive/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# 归档文档说明
|
||||
|
||||
本目录保留项目历史阶段的过程文档。**新加入项目的 agent / 人员不需要阅读这些文档**,直接看 `docs/ONBOARDING_NEXT_AGENT_ZH.md` 即可。
|
||||
|
||||
保留它们的目的:
|
||||
1. 论文写作时追溯 v1-v5 调优演化过程
|
||||
2. 未来若回到 ts=10 高压区间或更大 trace 时,可参考当年的结构性问题诊断
|
||||
3. 满足学术可追溯性要求
|
||||
|
||||
## 每个文档的简要说明
|
||||
|
||||
| 文档 | 归档原因 | 何时回头看 |
|
||||
|---|---|---|
|
||||
| `AGENTIC_FIT_ANALYSIS_ZH.md` | ts=10 时代的 §1-§7 结构性问题分析;结论已被 ts=1 数据全面 supersede | 想知道当年 ts=10 下我们认为有什么结构性问题时 |
|
||||
| `STRUCTURAL_VALIDATION_REPORT_ZH.md` | 用 ts=10 数据对 AGENTIC_FIT_ANALYSIS 的 claim 做验证;同样被 ts=1 时代 supersede | 同上 |
|
||||
| `KVC_DEBUG_JOURNEY_V1_TO_V5.md` | v1-v5 5 个调优 sweep 的过程笔记;包含 errors 9→912 漂移、direct-to-D 占比变化等历史数据 | 写 paper 时要写 "as we explored configurations v1-v5..." 段落 |
|
||||
| `V5_PROFILE_INVESTIGATION_ZH.md` | 给 v5 加 1Hz polling instrumentation 的调查;让 errors 涨 46× 的现象记录 | 想理解 "admission RPC 干扰 scheduler 主循环" 这条 §5 残留风险时 |
|
||||
| `REFACTOR_PLAN_ZH.md` | v0 重构计划,**已被 `REFACTOR_PLAN_V1_ZH.md` supersede** | 不需要看;只有想看作者一开始的设想时翻一翻 |
|
||||
| `KVCACHE_CENTRIC_PROGRESS_ZH.md` | 项目最早期(2026-04-27)的进度记录;当时还没有完整的 sweep 数据 | 几乎不需要看;满足"项目起源记录"职能 |
|
||||
| `SWEBENCH_EXPERIMENT_PROGRESS.md` | SWE-Bench trace 早期实验进度记录 | 想知道当年的 trace 生成 / 采样配置时 |
|
||||
| `SWEBENCH_EXPERIMENT_RESULTS.md` | 同上,早期 result snapshot | 同上 |
|
||||
|
||||
## 当前活跃文档(在 `docs/` 顶层)
|
||||
|
||||
跳转去看:
|
||||
- `docs/ONBOARDING_NEXT_AGENT_ZH.md` — 新人上手手册
|
||||
- `docs/PROJECT_OVERVIEW.md` — 项目目标 + 术语
|
||||
- `docs/KVC_ROUTER_ALGORITHM.md` — 算法形式化
|
||||
- `docs/V2_DEEP_ANALYSIS_ZH.md` — v2 完整分析
|
||||
- `docs/V2_RESULTS_ZH.md` — v2 原始战报
|
||||
- `docs/REFACTOR_PLAN_V1_ZH.md` — ts=1 方向决策
|
||||
- `docs/MIGRATION_V1_FINDINGS_ZH.md` — v1 thrashing 诊断
|
||||
- `docs/RESEED_SLOW_PATH_AND_D_TO_P_GAP_ZH.md` — reseed 长尾 + D→P 缺口审计
|
||||
- `docs/TEAM_REPORT_AGENTIC_PD_HYBRID_ZH.md` — ts=10 时代的结构性问题清单(作为历史 baseline 仍在主目录)
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 216 KiB |
@@ -136,7 +136,7 @@ def main() -> None:
|
||||
bar_colors = [KVC_P_COLOR, KVC_D_COLOR, KVC_D_COLOR, KVC_D_COLOR,
|
||||
DP_COLOR, DP_COLOR, DP_COLOR, DP_COLOR]
|
||||
|
||||
fig, axes = plt.subplots(1, 2, figsize=(15, 6.5))
|
||||
fig, axes = plt.subplots(1, 2, figsize=(15, 7.0))
|
||||
x = np.arange(len(all_gpus))
|
||||
|
||||
# -- Left: per-GPU request count ----------------------------------
|
||||
@@ -148,20 +148,24 @@ def main() -> None:
|
||||
ax.set_xticks(x)
|
||||
ax.set_xticklabels(labels, fontsize=9.5)
|
||||
ax.set_ylabel("Number of requests touching this GPU", fontsize=11)
|
||||
ax.set_title("Per-GPU request count\n(naïve view: P seems idle)", fontsize=12, pad=10)
|
||||
# Headroom for the annotation: extend ylim 35% above tallest bar
|
||||
ax.set_ylim(0, max(counts) * 1.40)
|
||||
ax.set_title("Per-GPU request count\n(naïve view: P seems idle)",
|
||||
fontsize=12, pad=24)
|
||||
ax.grid(axis="y", linestyle=":", alpha=0.4)
|
||||
ax.set_axisbelow(True)
|
||||
|
||||
# Annotate: KVC P GPU is "low frequency"
|
||||
# Place in upper-right area (over DP group) so it doesn't sit on KVC D bars
|
||||
p_idx = 0
|
||||
p_pct = counts[p_idx] / sum(counts[:4]) * 100 # vs KVC total
|
||||
ax.annotate(
|
||||
f"P GPU only sees\n"
|
||||
f"{counts[p_idx]:,} requests\n"
|
||||
f"({counts[p_idx]/len(kvc)*100:.1f}% of total)",
|
||||
f"({counts[p_idx]/len(kvc)*100:.1f}% of all KVC requests)",
|
||||
xy=(p_idx, counts[p_idx]),
|
||||
xytext=(p_idx + 0.6, max(counts) * 0.55),
|
||||
fontsize=9, color=KVC_P_COLOR, fontweight="bold",
|
||||
xytext=(2.4, max(counts) * 1.20),
|
||||
fontsize=10, color=KVC_P_COLOR, fontweight="bold", ha="center",
|
||||
bbox=dict(facecolor="white", edgecolor=KVC_P_COLOR, alpha=0.92, pad=4),
|
||||
arrowprops=dict(arrowstyle="->", color=KVC_P_COLOR, lw=1.0),
|
||||
)
|
||||
|
||||
@@ -185,31 +189,42 @@ def main() -> None:
|
||||
ax.set_xticks(x)
|
||||
ax.set_xticklabels(labels, fontsize=9.5)
|
||||
ax.set_ylabel("Compute tokens (millions)", fontsize=11)
|
||||
# Headroom for the annotation
|
||||
ax.set_ylim(0, max(total_M) * 1.45)
|
||||
ax.set_title("Per-GPU compute work\n(work view: P is comparable to each D)",
|
||||
fontsize=12, pad=10)
|
||||
fontsize=12, pad=24)
|
||||
ax.grid(axis="y", linestyle=":", alpha=0.4)
|
||||
ax.set_axisbelow(True)
|
||||
# Legend placed at upper-left where bars are tallest is fine after raising ylim
|
||||
ax.legend(loc="upper left", fontsize=10, framealpha=0.95)
|
||||
|
||||
# Annotate: KVC P GPU does similar work to each D
|
||||
# Annotate: KVC P GPU does similar work to each D.
|
||||
# Place over DP region (right side) so it doesn't sit on KVC D bars.
|
||||
ax.annotate(
|
||||
f"P GPU does {total_M[p_idx]:.2f}M tokens of\n"
|
||||
f"prefill — comparable per-GPU\n"
|
||||
f"load to each KVC D worker",
|
||||
f"P GPU does {total_M[p_idx]:.2f}M tokens of prefill\n"
|
||||
f"— comparable per-GPU load to each KVC D worker\n"
|
||||
f"(KVC D avg = {np.mean(total_M[1:4]):.2f}M)",
|
||||
xy=(p_idx, total_M[p_idx]),
|
||||
xytext=(p_idx + 0.6, max(total_M) * 0.62),
|
||||
fontsize=9, color=KVC_P_COLOR, fontweight="bold",
|
||||
xytext=(5.5, max(total_M) * 1.30),
|
||||
fontsize=10, color=KVC_P_COLOR, fontweight="bold", ha="center",
|
||||
bbox=dict(facecolor="white", edgecolor=KVC_P_COLOR, alpha=0.92, pad=4),
|
||||
arrowprops=dict(arrowstyle="->", color=KVC_P_COLOR, lw=1.0),
|
||||
)
|
||||
|
||||
# Separator + group labels
|
||||
# Separator + group labels (placed in axes-fraction coords, below subplot
|
||||
# title at pad=24 we now have safe room for these at y_axes_frac ≈ 1.02)
|
||||
for ax in axes:
|
||||
ax.axvline(3.5, color="gray", linestyle="--", linewidth=1.0, alpha=0.5)
|
||||
ymin, ymax = ax.get_ylim()
|
||||
ax.text(1.5, ymax * 1.05, "KVC 1P3D", ha="center", fontsize=11,
|
||||
fontweight="bold", color="#444")
|
||||
ax.text(5.5, ymax * 1.05, "DP 4-way CA", ha="center", fontsize=11,
|
||||
fontweight="bold", color="#444")
|
||||
ax.text(0.25, 1.02, "KVC 1P3D",
|
||||
transform=ax.transAxes, ha="center", va="bottom",
|
||||
fontsize=11.5, fontweight="bold", color="#444",
|
||||
bbox=dict(facecolor="#F2F2F2", edgecolor="#888",
|
||||
alpha=0.85, pad=3))
|
||||
ax.text(0.75, 1.02, "DP 4-way CA",
|
||||
transform=ax.transAxes, ha="center", va="bottom",
|
||||
fontsize=11.5, fontweight="bold", color="#444",
|
||||
bbox=dict(facecolor="#F2F2F2", edgecolor="#888",
|
||||
alpha=0.85, pad=3))
|
||||
|
||||
fig.suptitle(
|
||||
"Per-GPU utilization: \"is KVC's prefill GPU wasted?\"\n"
|
||||
|
||||
Reference in New Issue
Block a user