From 337195254a116b43d077ce9dd261d02f8abd8b56 Mon Sep 17 00:00:00 2001 From: Zhiyi Hong <2497491955@qq.com> Date: Fri, 31 Jul 2026 13:50:27 +0800 Subject: [PATCH] [Docs] summarize Phase 2 hardware attribution --- README.md | 4 + ...glang_hardware_contention_attribution.html | 114 ++++++++++++--- .../analysis.md | 138 ++++++++++++++++++ .../manifest.json | 20 +++ .../dsv4pro-phase2-20260731-130125/report.md | 34 +++++ .../service/head_server_cmd.txt | 1 + .../service/worker_server_cmd.txt | 1 + .../summary.json | 45 ++++++ .../推理优化计划.html | 69 +++++++-- 9 files changed, 395 insertions(+), 31 deletions(-) create mode 100644 docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/analysis.md create mode 100644 docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/manifest.json create mode 100644 docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/report.md create mode 100644 docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/service/head_server_cmd.txt create mode 100644 docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/service/worker_server_cmd.txt create mode 100644 docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/summary.json diff --git a/README.md b/README.md index a0b47e7..f416104 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # sskj — 多平台大模型推理性能基准测试项目 +> **更新(2026-07-31 13:40:03 CST)** +> +> 完成 DeepSeek-V4-Pro 双机 Pro6000D SGLang TP16 的 Phase 2 首轮硬件归因。正式 Run `dsv4pro-phase2-20260731-130125` 在 26 分 26 秒内完成 8/8 个 benchmark,无 OOM;混合负载下 Decode Output TPS 下降 24.03%,TPOT P95 增加 66.79%。两端双 Rail `NET/IB + GDRDMA` 流量均衡、错误增量为 0,最高每 Rail 平均约 70 Gbit/s,原始 RoCE 带宽未饱和;整机 CPU 与 GPU 频率也未见全局瓶颈。档案补充了 6000D 无 NVLink、机内 PCIe P2P/IPC、跨机 GDRDMA 的真实通信路径,并记录 Worker DCGM Host Engine 未启动、Case 时间窗过宽和 `pidstat` 日志过大的采集限制。 +> > **更新(2026-07-31 13:11:40 CST)** > > 新增 Phase 1 与 Phase 2 的独立代码详解 HTML 档案,行号固定到提交 `ca1f2f63375c`。文档从唯一入口展开到配置来源、文件调用关系、双机服务与 RDMA 门禁、benchmark 请求生成、混合 Prefill/Decode 时序、两节点采集器、Case 时间窗切片和结构化结果,并为 `MEM_FRACTION_STATIC` 等关键变量记录“默认值定义 → Shell 传递 → 服务参数 → Run 证据”的完整追踪路径。代码档案保持独立,不加入主计划 HTML 或阶段介绍 HTML 的导航。 diff --git a/docs/dsv4pro_pro6000d_2node_sglang/phase2_dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution.html b/docs/dsv4pro_pro6000d_2node_sglang/phase2_dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution.html index 5db3d8e..47043dc 100644 --- a/docs/dsv4pro_pro6000d_2node_sglang/phase2_dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution.html +++ b/docs/dsv4pro_pro6000d_2node_sglang/phase2_dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution.html @@ -135,7 +135,7 @@
节点:174.1.51.5 + 174.1.51.7 拓扑:SGLang TP16 / EP2 - 更新:2026-07-31 12:26:00 CST + 更新:2026-07-31 13:40:03 CST
@@ -144,9 +144,10 @@ 返回推理优化主计划

- 当前状态:Phase 2 代码已实现,静态检查、5 项单元测试与本地 Dry-run 已通过。 - 尚未启动双机模型服务或正式采集 GPU 数据。真机运行后,本页只保留成功 Run 的 - Run ID、命令、结果与结论。 + 当前状态:Phase 2 首次正式双机 Run 已完成。 + Run dsv4pro-phase2-20260731-130125 在 26 分 26 秒内完成 + 8/8 个 benchmark,无 OOM;GPU、CPU 和双 Rail RDMA 数据已完成首轮归因。 + 本阶段在此停止,不自动进入 Phase 3。

1. Phase 1 交接结果

@@ -292,7 +293,7 @@ dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution/ 顶层仍只保留一个 Shell 文件,不创建额外 tmux、launch、start 或 stop 脚本。

-

7. 预期结果结构

+

7. 结果结构

results/<RUN_ID>/
   manifest.json
   run.log
@@ -331,15 +332,14 @@ dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution/
summary.json report.md -

8. 验收条件

+

8. 验收结果

9. 实施记录

@@ -352,15 +352,95 @@ dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution/ 2026-07-30 22:55:37 CST完成 Phase 1 阶段交接双 Rail 门禁和 12/12 正式结果通过;选定纯 Prefill、并发 Prefill、混合干扰三个诊断负载 2026-07-31 12:26:00 CST完成 Phase 2 代码扩展为五个固定负载和混合 A/B;实现双节点 GPU/DCGM/CPU/NUMA/网络/RDMA 采集、时间对齐和异常清理 2026-07-31 12:26:00 CST本地验证bash -n、Python 编译、5 项单元测试与全流程 Dry-run 通过;未占用 GPU + 2026-07-31 13:27:51 CST完成正式双机 RunRun dsv4pro-phase2-20260731-130125:8/8 benchmark 成功,总用时 26 分 26 秒,无 OOM + 2026-07-31 13:40:03 CST完成首轮结果归因排除原始双 Rail 带宽饱和、整机 CPU 饱和和频率塌陷作为首要原因;锁定 TP16 Kernel、调度与同步时间线

10. 真机结果

-

- 尚未运行正式双机诊断。代码和本地 Dry-run 已完成;下一步是在 - 174.1.51.5 做服务器端静态检查与 Dry-run,随后由同一 - all 入口启动正式 Run。正式完成后本节将替换为成功 Run 的结果和瓶颈判断。 +

+ Run:dsv4pro-phase2-20260731-130125,状态 + COMPLETED运行时间为 13:01:25 至 13:27:51 CST, + 8 个结果全部成功,0 个失败。正式入口仅在 174.1.51.5 执行; + Worker 服务和采集器由脚本通过 SSH 自动启动。

+
cd /data/hzy/sskj/experiments/pro6000/dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution
+
+RUN_ID=dsv4pro-phase2-20260731-130125
+tmux new-session -d -s dsv4pro-phase2 \
+  "RUN_ID=${RUN_ID} bash run_hardware_contention_attribution.sh all \
+   2>&1 | tee /data/hzy/${RUN_ID}.log"
+ +

10.1 代表负载

+ + + + + + + + + + + +
CaseInput TPSOutput TPSTTFT P95TPOT P95
128K → 1, C=12,618.530.0250.036 s
32K → 1, C=163,116.200.10161.899 s
1K → 1K, C=32447.41447.4110.144 s65.63 ms
1K → 4K, C=1679.35317.411.727 s50.01 ms
128K → 1K, C=11,610.8912.5948.489 s32.12 ms
+ +

10.2 混合 Prefill/Decode

+ + + + + + + + + + +
Decode 指标Control注入 128K Prefill变化
Output TPS454.39345.20-24.03%
TTFT P959.437 s9.869 s+4.58%
TPOT P9566.17 ms110.36 ms+66.79%
E2E P9572.225 s117.941 s+63.30%
+

+ 这再次证明 Prefill 会明显干扰正在进行的 Decode。ITL P95 仍约为 + 62 ms,并不与 TPOT 恶化矛盾:少量同步长停顿可能不足全部 token 间隔的 5%, + 因而会被全局 token 级 ITL P95 隐藏,而请求级 TPOT 和 E2E 会暴露它。 +

+ +

10.3 GPU、CPU 与通信

+ + +

10.4 卡间通信路径

+ + + + + + + + +
范围实际路径本轮是否测量
单机 8 卡内部无 NVLink;NCCL P2P/IPC 走 PCIe。GPU0–3、GPU4–7 各自在 PCIe Switch 内为 PIX,两组之间为 SYS采集了 DCGM PCIe 指标;未做独立 P2P 带宽/延迟微基准
两机之间mlx5_0 + mlx5_3 双 Rail NET/IB + GDRDMA已测量每 Case HCA 流量、均衡性和错误增量
+

+ 在进入 Phase 3 前只需一次性补 p2pBandwidthLatencyTest、单机 8 卡 + all_reduce_perf 和双机 16 卡 all_reduce_perf, + 分开量化机内 PCIe 与跨机 RoCE 的硬件基线;后续阶段不重复跑这些微基准。 +

+ +

10.5 首轮结论与采集限制

+

+ 当前证据支持把下一步缩到 TP16 的 Kernel、Scheduler、PCIe/RDMA Collective + 和 Rank 同步时间线。Phase 3 只分析真实请求中通信出现的位置、耗时和与计算的 + 重叠关系,不重复 Phase 2 的平均 GPU/CPU/RDMA 采集。原始双 Rail 带宽、整机 + CPU 容量和降频都不像首要瓶颈;但 Phase 2 粗粒度指标还不能给出具体 Kernel 根因。 +

+

返回 Phase 1 实施记录

返回推理优化主计划

diff --git a/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/analysis.md b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/analysis.md new file mode 100644 index 0000000..ca411bd --- /dev/null +++ b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/analysis.md @@ -0,0 +1,138 @@ +# Phase 2 Hardware Attribution Analysis + +## Run + +- Run ID: `dsv4pro-phase2-20260731-130125` +- Status: `COMPLETED` +- Time: `2026-07-31 13:01:25` to `13:27:51 CST` +- Duration: 26 minutes 26 seconds +- Topology: two Pro6000D nodes, SGLang TP16 / EP2 +- Bench result: 8 completed, 0 failed, no OOM + +The command was run only on `174.1.51.5`: + +```bash +cd /data/hzy/sskj/experiments/pro6000/dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution + +RUN_ID=dsv4pro-phase2-20260731-130125 +tmux new-session -d -s dsv4pro-phase2 \ + "RUN_ID=${RUN_ID} bash run_hardware_contention_attribution.sh all \ + 2>&1 | tee /data/hzy/${RUN_ID}.log" +``` + +The entry script started the Worker and its collectors on `174.1.51.7` over SSH. +The full Phase 2 command must not be run a second time on the Worker. + +## Endpoint Results + +| Case | Input TPS | Output TPS | TTFT P95 | TPOT P95 | E2E P95 | +|---|---:|---:|---:|---:|---:| +| 128K -> 1, C=1 | 2,618.53 | 0.02 | 50.036 s | - | 50.036 s | +| 32K -> 1, C=16 | 3,116.20 | 0.10 | 161.899 s | - | 161.899 s | +| 1K -> 1K, C=32 | 447.41 | 447.41 | 10.144 s | 65.63 ms | 73.189 s | +| 1K -> 4K, C=16 | 79.35 | 317.41 | 1.727 s | 50.01 ms | 206.427 s | +| 128K -> 1K, C=1 | 1,610.89 | 12.59 | 48.489 s | 32.12 ms | 81.343 s | + +## Mixed Prefill/Decode + +| Decode metric | Control | With one 128K Prefill | Change | +|---|---:|---:|---:| +| Output TPS | 454.39 | 345.20 | -24.03% | +| TTFT P95 | 9.437 s | 9.869 s | +4.58% | +| TPOT P95 | 66.17 ms | 110.36 ms | +66.79% | +| E2E P95 | 72.225 s | 117.941 s | +63.30% | + +This reproduces the Phase 1 contention result. Prefill mainly damages ongoing +Decode progress rather than its first-token latency. Global token-level ITL P95 +stayed near 62 ms because a small number of synchronized long stalls can remain +below the top 5% of all token gaps. Per-request TPOT and E2E expose the impact +more clearly. + +## Hardware Evidence + +### GPU + +- During the 128K Prefill injection, average GPU utilization was 99.78% on the + Head and 99.34% on the Worker; average power was about 274 W on both nodes. +- During 32K -> 1, C=16 Prefill, average GPU utilization was about 82% on both + nodes and power was about 265 W. +- GPU clocks remained around 2.38 to 2.41 GHz. There is no evidence of a + frequency collapse. +- GPU memory stayed near 83.2 to 83.4 GiB of 85,651 MiB per GPU, leaving only + about 2.3 GiB of headroom. +- Head DCGM data is valid. During the injection window, `GRACT=0.995`, + `SMACT=0.648`, `SMOCC=0.215`, `Tensor Active=0.108`, and + `DRAM Active=0.412`. + +### CPU + +- Whole-machine CPU utilization stayed around 8% to 11% across 128 logical + CPUs, with zero average I/O wait. +- A few individual cores were saturated. During the injection window, 5 Head + cores and 4 Worker cores averaged above 80%. +- Therefore the machine is not globally CPU-bound, but scheduler, affinity, or + NUMA hot threads remain plausible contributors. + +### Inter-node RDMA + +- NCCL logs on both nodes verified `NET/IB + GDRDMA` over + `mlx5_0,mlx5_3`. +- Both rails carried nearly identical traffic and all recorded RDMA error + deltas were zero. +- The largest average traffic occurred in 32K -> 1, C=16 Prefill: + about 140.0 Gbit/s total transmit on the Head and 139.3 Gbit/s on the Worker, + or about 70 Gbit/s per 400G rail. +- This is only about 17.5% of each rail's nominal line rate. Raw RoCE bandwidth + saturation is therefore not the primary ceiling, although collective + latency and synchronization overhead are not ruled out. + +### Intra-node GPU Communication + +- RTX Pro 6000D has no NVLink. `nvidia-smi nvlink --status` reports no links. +- `nvidia-smi topo -m` shows GPU0-3 and GPU4-7 connected through local PCIe + switches (`PIX`), while traffic between the two four-GPU groups crosses the + host bridge and CPU/NUMA interconnect (`SYS`). +- NCCL logs show intra-node transfers through `P2P/IPC`; on this machine that + means CUDA peer-to-peer over PCIe, not NVLink. +- Phase 2 collected DCGM PCIe counters but did not run a dedicated GPU-to-GPU + bandwidth/latency microbenchmark. A later short diagnostic should run + `p2pBandwidthLatencyTest`, 8-GPU `all_reduce_perf`, and 16-GPU + `all_reduce_perf`. + +## Preliminary Attribution + +The first successful Phase 2 run supports three conclusions: + +1. Prefill/Decode resource contention is real and reproducible. +2. Raw dual-rail RoCE bandwidth, whole-machine CPU capacity, and clock + throttling do not explain the observed slowdown. +3. The next useful target is the TP16 execution timeline: GPU kernels, + scheduler gaps, PCIe/RDMA collectives, and synchronization between ranks. + +This is a bottleneck direction, not a final kernel-level root cause. Phase 3 +should capture short Prefill, Decode, and mixed timelines rather than repeat the +full benchmark matrix. + +## Collection Limitations + +- Worker DCGM exited because `nvidia-dcgm` hostengine was inactive on + `174.1.51.7`. Before another hardware run, execute on the Worker: + + ```bash + systemctl start nvidia-dcgm + systemctl is-active nvidia-dcgm + dcgmi discovery -l + ``` + + The main Phase 2 entry still runs only on the Head. + +- Current Case windows include benchmark-client startup, tokenizer/data + preparation, warm-up, the measured run, and client exit. Hardware averages + are therefore diluted outside the true main benchmark interval. Future + profiling must add explicit main-run start/end markers. +- `pidstat -durwt` at one-second intervals generated about 850 MB on the Head + and 735 MB on the Worker. The next run should use process-level sampling + and/or a five-second interval. +- Worker teardown logged a Gloo connection reset after the Head stopped. It + occurred after all eight benchmark rows completed and is a cleanup artifact, + not a benchmark failure. diff --git a/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/manifest.json b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/manifest.json new file mode 100644 index 0000000..2e2159a --- /dev/null +++ b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/manifest.json @@ -0,0 +1,20 @@ +{ + "run_id": "dsv4pro-phase2-20260731-130125", + "status": "COMPLETED", + "created_at": "2026-07-31T13:01:25+08:00", + "completed_at": "2026-07-31T13:27:51+08:00", + "experiment": "dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution", + "git_commit": "ca1f2f63375cd6e2bd249a91cbdbe7576aafad7e", + "git_dirty": false, + "phase1_entry": "/data/hzy/sskj/experiments/pro6000/dsv4pro_pro6000d_2node_sglang_tp16_quick_map/run_quick_map.sh", + "head_node": "10.101.0.11", + "worker_node": "10.101.0.13", + "fixed_case_ids": "long_prefill_latency_128k_c1,mid_prefill_throughput_32k_c16,decode_throughput_1k_to_1k_c32,long_output_decode_1k_to_4k_c16,long_context_decode_128k_to_1k_c1", + "run_mixed_case": true, + "sample_interval_s": 1, + "numastat_interval_s": 5, + "clock_skew_tolerance_s": 2, + "idle_baseline_s": 15, + "post_run_cooldown_s": 15, + "dry_run": false +} diff --git a/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/report.md b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/report.md new file mode 100644 index 0000000..ddb618c --- /dev/null +++ b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/report.md @@ -0,0 +1,34 @@ +# Phase 2 Hardware Attribution + +- Generated: `2026-07-31T13:27:51+08:00` +- Bench rows: `8` +- Failed bench rows: `0` +- GPU summary rows: `16` +- RDMA summary rows: `4` +- Case windows: `8` +- Collector status counts: `{"EXITED_BEFORE_STOP": 1, "STARTED": 18, "STOPPED": 17}` + +## Bench + +| Run | Case | Status | Input TPS | Output TPS | TTFT P95 (ms) | TPOT P95 (ms) | +|---|---|---|---:|---:|---:|---:| +| fixed_decode_throughput_1k_to_1k_c32 | decode_throughput_1k_to_1k_c32 | COMPLETED | 447.41274460374615 | 447.41274460374615 | 10144.207949569682 | 65.62598442892012 | +| fixed_long_context_decode_128k_to_1k_c1 | long_context_decode_128k_to_1k_c1 | COMPLETED | 1610.8926328335153 | 12.585098694011839 | 48488.74244495528 | 32.11543163640164 | +| fixed_long_output_decode_1k_to_4k_c16 | long_output_decode_1k_to_4k_c16 | COMPLETED | 79.35259394563253 | 317.41037578253014 | 1726.5846392256208 | 50.00692894707874 | +| fixed_long_prefill_latency_128k_c1 | long_prefill_latency_128k_c1 | COMPLETED | 2618.53322910782 | 0.019977823098051604 | 50036.02714801673 | 0.0 | +| fixed_mid_prefill_throughput_32k_c16 | mid_prefill_throughput_32k_c16 | COMPLETED | 3116.2035105433815 | 0.0950989840864069 | 161899.06251549837 | 0.0 | +| mixed_prefill_decode_interference | decode_control_1k_to_1k_c32 | COMPLETED | 454.3923063408163 | 454.3923063408163 | 9436.576361441985 | 66.170705189718 | +| mixed_prefill_decode_interference | decode_with_128k_prefill_1k_to_1k_c32 | COMPLETED | 345.2031620939666 | 345.2031620939666 | 9868.98645934416 | 110.36397890971698 | +| mixed_prefill_decode_interference | long_prefill_injection_128k_to_1_c1 | COMPLETED | 2844.468616501081 | 0.021701573307045603 | 45999.09703899175 | 0.0 | + +## Machine-readable summaries + +- `gpu_summary.csv` +- `rdma_summary.csv` +- `bench_summary.csv` +- `case_windows.csv` +- `case_gpu_summary.csv` +- `case_rdma_summary.csv` +- `summary.json` + +The final bottleneck conclusion is written only after aligning these files with `markers.csv`, raw DCGM/sysstat logs, and SGLang service logs. diff --git a/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/service/head_server_cmd.txt b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/service/head_server_cmd.txt new file mode 100644 index 0000000..bd8d931 --- /dev/null +++ b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/service/head_server_cmd.txt @@ -0,0 +1 @@ +docker run -d --name dsv4pro_pro6000d_2node_sglang_tp16_quick_map_head --gpus all --network host --ipc host --shm-size 20g --ulimit memlock=-1 --ulimit stack=67108864 -v /data/hf_models/DeepSeek-V4-Pro:/data/hf_models/DeepSeek-V4-Pro:ro -v /data/hzy/sglang_cache/dsv4_pro_tp16:/root/.cache -e CUDA_VISIBLE_DEVICES=0\,1\,2\,3\,4\,5\,6\,7 -e PYTHONUNBUFFERED=1 -e HF_HUB_OFFLINE=1 -e TRANSFORMERS_OFFLINE=1 -e PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True -e NCCL_SOCKET_IFNAME=eth0 -e NCCL_IB_HCA==mlx5_0:1\,mlx5_3:1 -e NCCL_CROSS_NIC=1 -e NCCL_DEBUG=INFO -e SGLANG_SHARED_EXPERT_TP1=1 --device /dev/infiniband/rdma_cm --device /dev/infiniband/uverbs0 --device /dev/infiniband/uverbs3 --entrypoint python3 lmsysorg/sglang:nightly-dev-cu13-20260720-b3570a45 -m sglang.launch_server --model-path /data/hf_models/DeepSeek-V4-Pro --tp-size 16 --ep-size 2 --nnodes 2 --node-rank 0 --dist-init-addr 10.101.0.11:20002 --trust-remote-code --host 0.0.0.0 --port 30002 --mem-fraction-static 0.9 --cuda-graph-max-bs-decode 64 --max-running-requests 256 diff --git a/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/service/worker_server_cmd.txt b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/service/worker_server_cmd.txt new file mode 100644 index 0000000..3b18997 --- /dev/null +++ b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/service/worker_server_cmd.txt @@ -0,0 +1 @@ +docker run -d --name dsv4pro_pro6000d_2node_sglang_tp16_quick_map_worker --gpus all --network host --ipc host --shm-size 20g --ulimit memlock=-1 --ulimit stack=67108864 -v /data/hf_models/DeepSeek-V4-Pro:/data/hf_models/DeepSeek-V4-Pro:ro -v /data/hzy/sglang_cache/dsv4_pro_tp16:/root/.cache -e CUDA_VISIBLE_DEVICES=0\,1\,2\,3\,4\,5\,6\,7 -e PYTHONUNBUFFERED=1 -e HF_HUB_OFFLINE=1 -e TRANSFORMERS_OFFLINE=1 -e PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True -e NCCL_SOCKET_IFNAME=eth0 -e NCCL_IB_HCA==mlx5_0:1\,mlx5_3:1 -e NCCL_CROSS_NIC=1 -e NCCL_DEBUG=INFO -e SGLANG_SHARED_EXPERT_TP1=1 --device /dev/infiniband/rdma_cm --device /dev/infiniband/uverbs0 --device /dev/infiniband/uverbs3 --entrypoint python3 lmsysorg/sglang:nightly-dev-cu13-20260720-b3570a45 -m sglang.launch_server --model-path /data/hf_models/DeepSeek-V4-Pro --tp-size 16 --ep-size 2 --nnodes 2 --node-rank 1 --dist-init-addr 10.101.0.11:20002 --trust-remote-code --host 0.0.0.0 --port 30002 --mem-fraction-static 0.9 --cuda-graph-max-bs-decode 64 --max-running-requests 256 diff --git a/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/summary.json b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/summary.json new file mode 100644 index 0000000..4a55636 --- /dev/null +++ b/docs/dsv4pro_pro6000d_2node_sglang/results/dsv4pro-phase2-20260731-130125/summary.json @@ -0,0 +1,45 @@ +{ + "generated_at": "2026-07-31T13:27:51+08:00", + "bench_rows": 8, + "failed_bench_rows": 0, + "gpu_summary_rows": 16, + "rdma_summary_rows": 4, + "case_windows": 8, + "case_gpu_summary_rows": 128, + "case_rdma_summary_rows": 32, + "collector_status_counts": { + "STARTED": 18, + "STOPPED": 17, + "EXITED_BEFORE_STOP": 1 + }, + "collector_files": { + "head": { + "dcgm_dmon.log": 1638191, + "docker_top.log": 11692641, + "gpu_samples.csv": 726449, + "markers.csv": 1860, + "mpstat.log": 15587271, + "numastat.log": 3280062, + "perf_stat.log": 744719, + "pidstat.log": 850254976, + "rdma.csv": 230202, + "sar_net.log": 2118579, + "static_after.log": 1195680, + "static_before.log": 1306492 + }, + "worker": { + "dcgm_dmon.log": 243, + "docker_top.log": 11989768, + "gpu_samples.csv": 758155, + "markers.csv": 1902, + "mpstat.log": 15587260, + "numastat.log": 3579303, + "perf_stat.log": 747768, + "pidstat.log": 734994477, + "rdma.csv": 242603, + "sar_net.log": 2383072, + "static_after.log": 1195267, + "static_before.log": 1306098 + } + } +} diff --git a/docs/dsv4pro_pro6000d_2node_sglang/推理优化计划.html b/docs/dsv4pro_pro6000d_2node_sglang/推理优化计划.html index 7586581..9f99ec8 100644 --- a/docs/dsv4pro_pro6000d_2node_sglang/推理优化计划.html +++ b/docs/dsv4pro_pro6000d_2node_sglang/推理优化计划.html @@ -400,7 +400,7 @@
节点:174.1.51.5 + 174.1.51.7 资源:16 × RTX PRO 6000 Blackwell - 版本:2026-07-30 22:55:37 CST + 版本:2026-07-31 13:40:03 CST
@@ -415,7 +415,7 @@

6000D 双机 DeepSeek-V4-Pro 推理优化计划

-

适用环境:174.1.51.5 + 174.1.51.7,每台 8 张 RTX PRO 6000 Blackwell Server Edition
当前部署:DeepSeek-V4-Pro,16 张 GPU 组成一个完整实例
当前约束:模型暂时只能使用全部 16 张 GPU,无法额外复制一套模型进行 PD 分离
计划版本:2026-07-30 22:55:37 CST

+

适用环境:174.1.51.5 + 174.1.51.7,每台 8 张 RTX PRO 6000 Blackwell Server Edition
当前部署:DeepSeek-V4-Pro,16 张 GPU 组成一个完整实例
当前约束:模型暂时只能使用全部 16 张 GPU,无法额外复制一套模型进行 PD 分离
计划版本:2026-07-31 13:40:03 CST

当前执行状态与阶段档案

@@ -439,7 +439,7 @@ - +
DeepSeek-V4-Pro / 双机 Pro6000D / SGLang 硬件与资源竞争归因代码、单元测试与本地 Dry-run 已完成;等待服务器端 Dry-run 与正式运行首轮正式 Run 已完成;8/8 benchmark 成功,已获得 GPU、CPU 与双 Rail RDMA 瓶颈方向 打开 Phase 2 档案
@@ -475,6 +475,14 @@ 400 Gbit/s ≈ 50 GB/s 只是单向理论上限,NCCL 的 algbw/busbw 与端到端模型吞吐都不能直接等同于该数字。

+

+当前 6000D 机内没有 NVLink。单机 8 卡由 PCIe 连接: +GPU0–3 与 GPU4–7 各自在本地 PCIe Switch 内通信,两组之间还要经过 Host Bridge +和 CPU/NUMA 互联。NCCL 机内日志中的 P2P/IPC 是 CUDA P2P over PCIe; +两机之间则使用 mlx5_0/mlx5_3 双 Rail +NET/IB + GDRDMA。Phase 2 已测跨机 HCA 流量,但机内 PCIe 的独立 +GPU-to-GPU 带宽和延迟仍需微基准补齐。 +

1. 目标与原则

1.1 最终目标

在不做 PD 分离的前提下,定位 DeepSeek-V4-Pro 在双机 6000D 上的端到端瓶颈,并提高:

@@ -727,10 +735,24 @@ TPOT P95 增加 66.55%。Phase 2 将围绕这两个现象采集硬件时间序 Phase 2:硬件与资源竞争归因档案。本阶段重放长 Prefill、并发 Prefill、 普通 Decode、长输出 Decode、长上下文 Decode,以及 -1K → 1K, C=32 的混合 A/B。目标是在约 30 分钟内区分 GPU、 -CPU、NUMA、双 Rail、调度排队、频率节流和节点不均衡。 +1K → 1K, C=32 的混合 A/B。正式 Run +dsv4pro-phase2-20260731-130125 已在 26 分 26 秒内完成 8/8 个结果, +无 OOM;本阶段先停在首轮归因,不自动进入 Phase 3。

-

6.1 GPU

+

6.1 首轮归因结果

+ +

+首轮仍有两个采集限制:Worker 的 DCGM Host Engine 未启动,因此只有 Head DCGM +有效;Case 时间窗包含客户端准备和 Warm-up,硬件均值并非纯主测量窗口。重跑前应先在 +.7 启动 nvidia-dcgm,并增加主 benchmark 精确起止标记。 +

+

6.2 GPU

测试期间持续记录:

nvidia-smi dmon -s pucvmt -d 1
 
@@ -751,7 +773,7 @@ CPU、NUMA、双 Rail、调度排队、频率节流和节点不均衡。
  • PCIe Throughput。
  • GPU Stall 与 XID。
  • -

    6.2 CPU

    +

    6.3 CPU

    记录服务主进程与 Worker 线程:

    pidstat -t -p <PID> 1
     mpstat -P ALL 1
    @@ -764,7 +786,7 @@ numastat -p <PID>
     
  • Worker 是否跨 NUMA 访问。
  • CPU 空洞是否对应 GPU 空洞。
  • -

    6.3 网络

    +

    6.4 网络

    Phase 1 正式 Run 已从两端 NCCL 日志确认 NET/IB 同时识别 mlx5_0/mlx5_3,跨节点 Channel @@ -788,7 +810,7 @@ ethtool -S eth3 NCCL_DEBUG_SUBSYS=INIT,NET,GRAPH,TUNING

    该日志开销较高,不应在正式性能结果中长期启用。

    -

    6.4 NCCL_CROSS_NIC 快速 A/B

    +

    6.5 NCCL_CROSS_NIC 快速 A/B

    Phase 1 已证明 NCCL_CROSS_NIC=1 可以稳定完成端到端 Run, 但这不代表它是性能最优值。固定其余环境后比较 0/1/2, @@ -800,12 +822,12 @@ Phase 1 已证明 NCCL_CROSS_NIC=1 可以稳定完成端到端 Run

  • 每个值重启同配置 SGLang 服务,仅重放一个 Decode 高并发代表点,比较 Output TPS、TPOT P95 与稳定性。
  • 先排除不正确或不稳定的值,再比较 NCCL 中位带宽,最终以 SGLang 端到端结果决定生产值。
  • -

    6.5 与其他阶段的组合边界

    +

    6.6 与其他阶段的组合边界

    7. Phase 3:时间线 Profiling(Nsight Systems 为主)

    @@ -814,15 +836,34 @@ Nsight Systems、PyTorch Profiler 和 NVTX 是三件不同的东西:Nsight Sys 记录系统级 CUDA/NCCL/CPU 时间线;PyTorch Profiler 由框架接口触发; NVTX 只是在时间线上添加可读标记。启用 NVTX 不等于已经启动 Nsight。

    -

    7.1 捕获策略

    +

    7.1 与 Phase 2 的分工

    + + + + + + + + + + + +
    问题负责阶段或工具是否在 Phase 3 重复
    GPU/CPU 平均利用率、功耗、频率、显存Phase 2 轻量采样否;Phase 3 只保留最低限度健康检查
    双 Rail 流量、均衡与错误计数Phase 2 HCA Counter
    机内 PCIe P2P 与 8/16 卡 Collective 峰值能力一次性通信微基准:p2pBandwidthLatencyTestall_reduce_perf只建立一次硬件基线,不随每个 Phase 重跑
    真实请求中 NCCL Kernel 在何时发生、耗时多久Phase 3 Nsight Systems Timeline是,Phase 3 的核心
    通信是否与 Attention/MoE Kernel 重叠、GPU 是否在等待 RankPhase 3 Nsight Systems Timeline是,Phase 2 无法回答
    +

    +因此 Phase 3 可以分析卡间通信,但分析的是真实请求里的时间与依赖关系, +不是再次统计平均网络带宽。通信微基准负责给出硬件上限,Phase 3 负责解释 SGLang +距离该上限有多远,以及通信是否落在关键路径上。 +

    +

    7.2 捕获策略

    -

    7.2 vLLM

    +

    7.3 vLLM

    当前版本支持时,使用 CUDA Profiler 动态 Capture:

    export VLLM_WORKER_MULTIPROC_METHOD=spawn
     
    @@ -839,7 +880,7 @@ nsys profile \
     

    压测端使用支持 Profile Trigger 的 Bench:

    vllm bench serve ... --profile
     
    -

    7.3 SGLang

    +

    7.4 SGLang

    以下 SGLANG_TORCH_PROFILER_DIR/start_profile 属于 SGLang 的 PyTorch Profiler 路径,可用于框架级时间线,但不能把生成物