MB2 inter-node: dash1↔dash2 transfer cost is identical to intra-node

Sweep on dash1 GPU 0 → dash2 GPU 0 over 200 Gbps RoCE.
remote_bootstrap_addr=http://172.27.123.142:8998. Same 9-size × 5-rep
config as the 2026-05-27 intra-node run.

Per-size pure_transfer (p50) lines up within 1–3% of the intra-node
numbers across all sizes:

  size      intra p50   inter p50
   512 tok    5.3 ms      5.2 ms
  2048 tok   20.6         20.0
  8192 tok   83.7         80.9
 32k  tok  320.9        309.6
 64k  tok 1895          1734       (bimodal in both)
128k  tok 2835          2818       (bimodal in both)

=> Mooncake's batch_transfer_sync_write **does not use NVLink** for
intra-node peers; both paths go through the 200 Gbps RDMA NIC, with
the 200 Gbps NIC (not the GPU interconnect) being the bottleneck. The
~9.7 GB/s steady-state ceiling and the 6+ GiB variance regime are
identical across topologies.

Operational implication for §3.2: PD-disaggregation does not get
cheaper by co-locating P and D on the same node — every routed request
pays the same ~10 GB/s ceiling for KV transfer, no matter where it
lands. Halving the transfer cost cannot be bought back by topology.

Caveat: B's receive_kv events did not log on dash2 — `MB2_LOG_DIR`
env var did not propagate through vLLM's EngineCore subprocess on
the consumer host (cat /proc/$ENGINE_PID/environ is empty on dash2
for that var, but the producer host on dash1 worked). For this run
pure_transfer numbers are from A's send_blocks alone; full rx_total
breakdown is not available, but pure_transfer is the dominant term.

Adds:
- analyze_mb2_send_only.py — analyzer that works from A's send_blocks
  alone when B's receive_kv events are absent
- plot_mb2_compare.py — overlay intra vs inter on the same axes
- plot_mb2.py — tolerate the `rows`-less send-only schema
- figs/mb2_transfer_{time,bw}_inter.png — inter-node single-curve
- figs/mb2_transfer_{time,bw}_compare.png — intra vs inter overlay
- analysis/mb2/A_inter_kvboth.jsonl, inter_kvboth_client.json,
  inter_kvboth_breakdown.json
- analysis/mb2/README.md — Summary block updated to reference both
  paths, dated 2026-05-27 run-log entry appended with the full table
  and the topology-independence framing

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 20:56:08 +08:00
parent 50f72d8875
commit 90127c3389
11 changed files with 1096 additions and 5 deletions

View File

@@ -10,8 +10,19 @@ the EAR paper. Re-runs append a dated section at the bottom; the
| Path | Steady-state BW | Agentic-tail p99 transfer (11.5 GiB KV) |
|---|---|---|
| **intra-node** (dash1 GPU 0↔1, kv_both, Mooncake 0.3.11) | **~9.7 GB/s** (96 MiB 3 GiB) | p50 **1.9 s** · min **1.5 s** · max **10 s** |
| inter-node (dash1 ↔ dash2, RDMA) | TODO | TODO |
| **intra-node** (dash1 GPU 0↔1) | **~9.7 GB/s** (96 MiB 3 GiB) | p50 **1.9 s** · min **1.5 s** · max **10 s** |
| **inter-node** (dash1 GPU0 → dash2 GPU0, 200 Gbps RoCE) | **~10.0 GB/s** (essentially identical) | p50 **1.7 s** · min **1.3 s** · max **9.2 s** |
**Cross-cutting finding** (2026-05-27): **Mooncake transfer cost is
topology-independent** on this hardware. Intra-node and inter-node curves
are statistically indistinguishable (see `figs/mb2_transfer_time_compare.png`,
`figs/mb2_transfer_bw_compare.png`). Mechanism: Mooncake's
`batch_transfer_sync_write` always goes through the RDMA NIC, including
the intra-node case (RDMA loopback). The 200 Gbps NIC, not NVLink, is
the bottleneck. **Implication for §3.2**: PD-disaggregation does not
get cheaper by co-locating P and D on the same node — the ~9.7 GB/s
ceiling applies regardless. Halving the transfer cost cannot be bought
back by topology.
**Headline for the paper §3.2**: at the agentic tail, **pure KV transfer
takes 1.5 10 s**. A median agentic decode is **50 200 ms** of tool-call
@@ -229,3 +240,61 @@ Result table above. **9.7 GB/s steady-state up to 3 GiB**, variance
opens at 6 GiB, p99 agentic-tail transfer 1.5 10 s.
Committed as `de164e5`.
### 2026-05-27 — inter-node, kv_both, dash1 GPU 0 → dash2 GPU 0
Same sweep config. 200 Gbps RoCE between hosts (RTT ~0.2 ms ping).
Producer A on dash1 GPU 0, consumer B on dash2 GPU 0.
remote_bootstrap_addr=`http://172.27.123.142:8998` (dash1's internal IP).
Raw events: `A_inter_kvboth.jsonl` (45 send_blocks + 6 sanity).
B's receive_kv events are **missing** for this run — the
`MB2_LOG_DIR` env var did not propagate from the start-script through
vLLM's EngineCore subprocess on dash2 (visible via
`cat /proc/$ENGINE_PID/environ` shows empty for dash2 but contains
MB2_LOG_DIR for dash1 — bookmark for future investigation, likely
spawn-vs-fork difference in vLLM's multiproc executor across hosts).
Pure-transfer numbers below come from A's send_blocks alone; full
rx_total breakdown not available for this run.
Per-size pure-transfer (analyzed by `analyze_mb2_send_only.py`):
| input_tokens | KV (MiB) | n | pure_ms p50 | min | max | BW p50 (GB/s) | BW max |
|---:|---:|---:|---:|---:|---:|---:|---:|
| 512 | 48 | 5 | 5.2 | 5.1 | 65.8 | 9.76 | 9.81 |
| 1024 | 96 | 5 | 10.2 | 10.1 | 10.4 | 9.91 | 10.00 |
| 2048 | 192 | 5 | 20.0 | 20.0 | 20.5 | 10.06 | 10.07 |
| 4096 | 384 | 5 | 40.1 | 40.1 | 40.5 | 10.04 | 10.05 |
| 8192 | 768 | 5 | 80.9 | 80.7 | 82.5 | 9.96 | 9.98 |
| 16384 | 1536 | 5 | 161.8 | 161.7 | 164.8 | 9.96 | 9.96 |
| 32768 | 3072 | 5 | 309.6 | 307.7 | 526.9 | 10.40 | 10.47 |
| 65536 | 6144 | 5 | 1733.6 | 653.5 | 1921.2 | 3.72 | 9.86 |
| 131072 | 12288 | 5 | 2818.4 | 1283.0 | 9158.6 | 4.57 | 10.04 |
Side-by-side comparison with the 2026-05-27 intra-node run:
| Size | intra p50 ms | inter p50 ms | gap | intra GB/s | inter GB/s |
|---|---:|---:|---:|---:|---:|
| 512 | 5.3 | 5.2 | 2% | 9.40 | 9.76 |
| 1024 | 10.4 | 10.2 | 2% | 9.68 | 9.91 |
| 2048 | 20.6 | 20.0 | 3% | 9.75 | 10.06 |
| 4096 | 41.5 | 40.1 | 3% | 9.71 | 10.04 |
| 8192 | 83.7 | 80.9 | 3% | 9.62 | 9.96 |
| 16384 | 167.1 | 161.8 | 3% | 9.64 | 9.96 |
| 32768 | 320.9 | 309.6 | 3% | 10.04 | 10.40 |
| 65536 | 1895.1 | 1733.6 | 9% | 3.40 | 3.72 |
|131072 | 2835.1 | 2818.4 | 1% | 4.54 | 4.57 |
The two paths produce essentially the same numbers — **mooncake intra-
node is not using NVLink**, it's going through RDMA-loopback on the
local NIC and gets the same ~10 GB/s ceiling as cross-node RDMA. The
6+ GiB variance regime is also identical between paths.
Figures: `figs/mb2_transfer_time_inter.png`, `figs/mb2_transfer_bw_inter.png`,
`figs/mb2_transfer_time_compare.png` (overlay), `figs/mb2_transfer_bw_compare.png`.
This collapses the §3.2 narrative to a single number: **PD-disagg
across this cluster costs ~9.710 GB/s of transfer bandwidth no matter
how you place P and D** (within-node or across-node). For p99 agentic
KV (11.5 GiB), that's 1.310 s of transfer; for 6 GiB it's 0.72 s.
Decode is 50200 ms. So PD-disagg's cost dominates regardless of layout.