[Docs] gate phase archives on completed results

This commit is contained in:
Zhiyi Hong 2026-07-31 17:05:19 +08:00
parent 7be3062c51
commit 5096661ce3
6 changed files with 14 additions and 1206 deletions

View File

@ -1,5 +1,9 @@
# sskj — 多平台大模型推理性能基准测试项目 # sskj — 多平台大模型推理性能基准测试项目
> **更新2026-07-31 17:01:56 CST**
>
> 固定阶段档案生成门禁:某个 Phase 在实验结束、结果汇总并完成汇报确认前,不创建或维护 `phaseN_exp.html``phaseN_code.html`;进行中只维护代码、原始结果和主计划状态。阶段确认完成后再一次性生成两份最终 HTML。Phase 2 尚待最终正式复跑,因此暂时撤下其两份 HTML 及导航;已完成的 Phase 1 档案继续保留。
>
> **更新2026-07-31 16:46:05 CST** > **更新2026-07-31 16:46:05 CST**
> >
> 统一 DeepSeek-V4-Pro 推理优化档案命名与导航Phase 1/2 实验页分别更名为 `phase1_exp.html``phase2_exp.html`,代码页保持 `phase1_code.html``phase2_code.html`。主计划中的入口统一为“打开 Phase N 实验档案 / 代码详解”并为实验页与代码页补齐双向链接。Phase 1 状态同步为固定点 11/11、混合 A/B 3/3、阶段总结果 14/14。 > 统一 DeepSeek-V4-Pro 推理优化档案命名与导航Phase 1/2 实验页分别更名为 `phase1_exp.html``phase2_exp.html`,代码页保持 `phase1_code.html``phase2_code.html`。主计划中的入口统一为“打开 Phase N 实验档案 / 代码详解”并为实验页与代码页补齐双向链接。Phase 1 状态同步为固定点 11/11、混合 A/B 3/3、阶段总结果 14/14。

View File

@ -843,12 +843,7 @@ curl -fsS http://10.101.0.11:30002/health || true
docker ps --filter name=dsv4pro_pro6000d_2node_sglang_tp16_quick_map docker ps --filter name=dsv4pro_pro6000d_2node_sglang_tp16_quick_map
nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv</code></pre> nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv</code></pre>
<p> <p>下一阶段Phase 2 正在进行,完成最终复跑与汇报后生成实验档案。</p>
下一阶段:
<a class="back" href="./phase2_exp.html">
打开 Phase 2 实验档案
</a>
</p>
<p><a class="back" href="./推理优化计划.html">返回推理优化主计划</a></p> <p><a class="back" href="./推理优化计划.html">返回推理优化主计划</a></p>
</main> </main>
</body> </body>

View File

@ -1,419 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light">
<title>Phase 2 CodeDSV4-Pro 双机 Pro6000D SGLang 硬件竞争归因</title>
<style>
:root {
--canvas: #eef3f4;
--paper: #ffffff;
--ink: #182126;
--muted: #5a6970;
--line: #d4dee1;
--navy: #17363d;
--teal: #087c72;
--teal-soft: #e8f5f3;
--amber: #a64c14;
--amber-soft: #fff1e7;
--code-bg: #17252b;
--code-ink: #eaf2f3;
}
* { box-sizing: border-box; letter-spacing: 0; }
html { scroll-behavior: smooth; }
body {
margin: 0;
color: var(--ink);
background: var(--canvas);
font-family: "PingFang SC", "Microsoft YaHei", "Noto Sans CJK SC", Arial, sans-serif;
font-size: 16px;
line-height: 1.72;
}
header { color: #f6fbfb; background: var(--navy); border-bottom: 5px solid #d2692b; }
.header-inner, main { width: min(100% - 36px, 1120px); margin: 0 auto; }
.header-inner { padding: 34px 0 30px; }
.eyebrow { margin: 0 0 6px; color: #9edbd5; font-size: 13px; font-weight: 700; }
h1 { margin: 0; font-size: clamp(28px, 4vw, 42px); line-height: 1.25; }
.meta { margin-top: 15px; color: #d6e5e7; font-size: 14px; }
main {
margin-top: 30px;
margin-bottom: 70px;
padding: 38px 48px 58px;
background: var(--paper);
border: 1px solid var(--line);
border-radius: 6px;
box-shadow: 0 12px 30px rgba(27, 45, 51, 0.07);
}
h2 {
margin: 46px 0 15px;
padding-bottom: 8px;
font-size: 25px;
line-height: 1.35;
border-bottom: 2px solid #adbbc0;
}
h2:first-of-type { margin-top: 18px; }
h3 { margin: 29px 0 10px; color: #21454d; font-size: 19px; }
h4 { margin: 22px 0 8px; font-size: 16px; }
p, ul, ol { margin-top: 0; margin-bottom: 16px; }
li + li { margin-top: 5px; }
a { color: var(--teal); text-underline-offset: 3px; }
code {
padding: 2px 5px;
color: #85380d;
background: var(--amber-soft);
border-radius: 3px;
font-family: "SFMono-Regular", Consolas, monospace;
overflow-wrap: anywhere;
}
pre {
margin: 14px 0 22px;
padding: 16px 18px;
overflow: auto;
color: var(--code-ink);
background: var(--code-bg);
border-radius: 5px;
font: 13px/1.62 "SFMono-Regular", Consolas, monospace;
}
pre code { padding: 0; color: inherit; background: transparent; }
table { width: 100%; margin: 16px 0 26px; border-collapse: collapse; font-size: 14px; }
th, td {
padding: 9px 11px;
vertical-align: top;
text-align: left;
border: 1px solid var(--line);
overflow-wrap: anywhere;
}
th { color: #153b41; background: #eaf2f2; }
tbody tr:nth-child(even) { background: #fafcfc; }
.callout { margin: 18px 0 26px; padding: 14px 18px; background: var(--teal-soft); border-left: 4px solid var(--teal); }
.warning { margin: 18px 0 26px; padding: 14px 18px; background: var(--amber-soft); border-left: 4px solid var(--amber); }
.toc { columns: 2; column-gap: 38px; margin: 16px 0 24px; padding-left: 22px; }
.toc li { break-inside: avoid; }
.path { font-family: "SFMono-Regular", Consolas, monospace; font-size: 13px; }
footer { margin-top: 48px; padding-top: 18px; color: var(--muted); border-top: 1px solid var(--line); }
@media (max-width: 760px) {
main { padding: 28px 20px 42px; }
.toc { columns: 1; }
table { display: block; overflow-x: auto; }
}
</style>
</head>
<body>
<header>
<div class="header-inner">
<p class="eyebrow">Standalone Code Walkthrough / Phase 2</p>
<h1>DSV4-Pro 双机 Pro6000D SGLang 硬件竞争归因:代码详解</h1>
<div class="meta">
行号基线:<code>39fc2ba565a3</code> 
生成时间2026-07-31 15:25:00 CST 
唯一入口:<code>run_hardware_contention_attribution.sh all</code>
</div>
</div>
</header>
<main>
<p>
<a href="./推理优化计划.html">返回推理优化主计划</a> ·
<a href="./phase2_exp.html">打开 Phase 2 实验档案</a>
</p>
<div class="callout">
<strong>文档边界:</strong>本文只解释提交 <code>39fc2ba565a3</code> 的 Phase 2
代码和文件调用关系。Phase 1 负责模型服务与请求Phase 2 负责通信基线、
两节点监控、精确时间切片和逐指标报告。
</div>
<h2 id="read">1. 阅读导航</h2>
<ul class="toc">
<li><a href="#flow">总体控制流</a></li>
<li><a href="#files">文件职责与调用关系</a></li>
<li><a href="#config">配置来源</a></li>
<li><a href="#communication">通信微基准</a></li>
<li><a href="#collectors">采集器实现</a></li>
<li><a href="#alignment">精确测量窗口</a></li>
<li><a href="#report">逐指标报告</a></li>
<li><a href="#index">函数行号索引</a></li>
</ul>
<h2 id="flow">2. 总体控制流</h2>
<pre><code>main "$@" → run_all
├─ validate_config
├─ preflight_node_tools
│ └─ 两节点 dcgmi discovery -l 必须成功
├─ preflight_clock_sync + preflight_gpus_idle
├─ run_communication_baseline
│ ├─ 两节点 CUDA P2P 全矩阵
│ ├─ 两节点各自 8-rank AllReduce
│ └─ 16-rank AllReduceCROSS_NIC=0/1/2
├─ start_service → Phase 1 start
├─ capture_static_snapshots before
├─ start_collectors → Head/Worker 同时采集
├─ idle → fixed cases → mixed A/B → cooldown
├─ check_collectors + stop_collectors
├─ capture_static_snapshots after
├─ stop_service → Phase 1 stop
├─ summarize_results
│ └─ 按正式 benchmark 窗口生成第 5 节逐项数据表
└─ finish_manifest</code></pre>
<p>
<code>all</code> 是唯一正式入口。<code>communication</code><code>summarize</code>
<code>stop</code> 是排错/恢复 action不需要在正常执行前手工调用。
</p>
<h2 id="files">3. 文件职责与调用关系</h2>
<table>
<thead><tr><th>文件</th><th>行数</th><th>职责</th></tr></thead>
<tbody>
<tr><td class="path">config.env</td><td>61</td><td>节点、Case、分层采样周期、通信尺寸、NCCL 选择和 fail-closed 策略。</td></tr>
<tr><td class="path">run_hardware_contention_attribution.sh</td><td>1036</td><td>唯一 Shell 编排器预检、通信文件分发、通信基线、Phase 1 委托、采集器、Case 和清理。</td></tr>
<tr><td class="path">communication_baseline.py</td><td>227</td><td>CUDA P2P 全矩阵及 PyTorch/NCCL AllReduce 正确性、延迟和带宽测试。</td></tr>
<tr><td class="path">hardware_contention_attribution.py</td><td>1480</td><td>解析所有原始采集器,按 Case 切片,聚合通信并生成 CSV/JSON/report.md。</td></tr>
<tr><td class="path">tests/test_hardware_contention_attribution.py</td><td>322</td><td>9 项纯 Python 单元测试,覆盖 worker 无仓库依赖、精确窗口、解析器、RDMA 单位和通信聚合。</td></tr>
</tbody>
</table>
<pre><code>用户
└─ Phase2/run_hardware_contention_attribution.sh all
├─ source Phase2/config.env
├─ docker/torchrun → Phase2/communication_baseline.py
├─ env ... bash Phase1/run_quick_map.sh start/fixed/mixed/stop
│ └─ Phase1/quick_map_results.py 写 benchmark meta
├─ Shell 采集 Head/Worker 原始时间序列
└─ Phase2/hardware_contention_attribution.py summarize
├─ 读取 Phase1 bench/cases/*/meta.json
├─ 读取 Head/Worker 原始监控
├─ 读取 communication/COMM_RESULT
└─ 输出逐 Case、逐节点、逐指标表和 report.md</code></pre>
<h3>3.1 Phase 1 与 Phase 2 的边界</h3>
<table>
<thead><tr><th>问题</th><th>由哪个文件负责</th><th>证据</th></tr></thead>
<tbody>
<tr><td>模型路径、镜像、TP16、EP、显存比例</td><td>Phase 1 <code>config.env</code> + <code>run_quick_map.sh</code></td><td><code>service/head_server_cmd.txt</code><code>worker_server_cmd.txt</code></td></tr>
<tr><td>ISL/OSL/C、random 请求和 mixed A/B</td><td>Phase 1 场景表与 benchmark 函数</td><td><code>bench/*/bench_cmd.txt</code><code>bench.json</code></td></tr>
<tr><td>通信基线、监控周期、Case 选择</td><td>Phase 2 <code>config.env</code></td><td>Phase 2 <code>manifest.json</code></td></tr>
<tr><td>硬件归因和数值报告</td><td>Phase 2 Python 汇总器</td><td><code>case_*_summary.csv</code><code>report.md</code></td></tr>
</tbody>
</table>
<h2 id="config">4. 配置来源</h2>
<table>
<thead><tr><th>行号</th><th>配置组</th><th>关键变量</th></tr></thead>
<tbody>
<tr><td><code>config.env:L3-L16</code></td><td>入口与节点</td><td><code>PHASE1_ENTRY</code>、Head/Worker、端口和容器名。</td></tr>
<tr><td><code>L18-L21</code></td><td>诊断 Case</td><td>五个 fixed Case、mixed A/B 开关。</td></tr>
<tr><td><code>L23-L39</code></td><td>采样与严格性</td><td>GPU/DCGM/RDMA 1 秒CPU/进程/网络/NUMA/perf 5 秒;精确窗口和采集器 fail-closed。</td></tr>
<tr><td><code>L40-L55</code></td><td>通信基线</td><td>镜像、消息尺寸、迭代次数、P2P 大小、CROSS_NIC 列表、Socket/HCA。</td></tr>
<tr><td><code>L57-L61</code></td><td>路径与模式</td><td><code>RESULT_BASE</code>、Runtime、Dry-run、是否允许部分采集器。</td></tr>
</tbody>
</table>
<p>
<code>MEM_FRACTION_STATIC</code> 不在 Phase 2 重复定义。它仍来自 Phase 1
最终展开为 SGLang 的 <code>--mem-fraction-static</code>。判断某次 Run 的真实值,
应读取 <code>service/head_server_cmd.txt</code>,不能只看默认配置。
</p>
<h2 id="communication">5. 通信微基准</h2>
<h3>5.1 Shell 如何编排</h3>
<p>
<code>run_hardware_contention_attribution.sh:L281-L513</code> 负责源码暂存、
Docker 命令、两节点同步和清理。所有命令先写入 <code>commands/*.txt</code>
</p>
<ul>
<li><code>L281-L319</code>:从 Head 将当次通信脚本暂存到两节点并校验 SHA256。</li>
<li><code>L321-L374</code>构造容器命令Head/Worker 各跑一次 P2P。</li>
<li><code>L376-L404</code>Head/Worker 各跑一次 8-rank AllReduce。</li>
<li><code>L406-L467</code>:每个 CROSS_NIC 值先启动 Worker rank再运行 Head rank。</li>
<li><code>L469-L513</code>:只清理本实验前缀的通信容器和本次 `/tmp` 暂存目录。</li>
</ul>
<p>
Docker 使用和 SGLang 一致的 CUDA 13 nightly 镜像,并显式透传
<code>rdma_cm</code><code>uverbs0</code><code>uverbs3</code>
<code>NCCL_DEBUG=INFO</code> 只在微基准中打开,用于证明 NET/IB/GDRDMA 路径。
Worker 不要求存在 Git 仓库;容器只读挂载自动分发的
<code>/tmp/.../&lt;RUN_ID&gt;/communication_baseline.py</code>。结果目录同时保存
当次源码副本和 SHA256避免两个节点 checkout 不一致造成版本漂移。
</p>
<h3>5.2 P2P 代码</h3>
<p>
<code>communication_baseline.py:L45-L106</code> 遍历所有源 GPU 和目标 GPU
先调用 <code>torch.cuda.can_device_access_peer</code>,再对 256 MiB FP16 Tensor
做预热和 CUDA Event 计时。输出包括方向、P50/P95 latency 和 GB/s。
汇总器按拓扑拆成同 PCIe Switch 的 PIX 与跨 NUMA 的 SYS。
</p>
<h3>5.3 AllReduce 代码</h3>
<p>
<code>communication_baseline.py:L107-L198</code> 初始化 NCCL process group
对 1 MiB、64 MiB、1 GiB 分别预热和重复测量。每轮先把各 rank latency
gather 到 rank 0使用最慢 rank 作为 collective 完成时间,并检查归约结果:
</p>
<pre><code>algbw = message_bytes / latency
busbw = algbw × 2 × (world_size - 1) / world_size
wrong_values = count(output != expected_sum)</code></pre>
<p>
这样不会用某个提前返回 rank 的时间美化结果;<code>wrong_values=0</code>
才算正确完成。
</p>
<h2 id="collectors">6. 两节点采集器</h2>
<h3>6.1 启动前门禁</h3>
<p>
Shell <code>L67-L199</code> 完成配置、工具、时钟和 GPU 空闲检查。
<code>preflight_node_tools</code> 不只检查 <code>dcgmi</code> 文件存在,
还实际运行 <code>dcgmi discovery -l</code>;两节点任一 Host Engine 不可用即退出。
</p>
<h3>6.2 采集器包装</h3>
<p>
<code>start_stream_collector</code> 位于 Shell <code>L517-L551</code>
它保存完整命令、PID、唯一进程 tag 和日志;<code>check_collectors</code>
<code>L722-L740</code> 检查采集器是否提前退出,默认不允许部分成功。
</p>
<table>
<thead><tr><th>采集器</th><th>Shell 位置</th><th>周期</th><th>输出</th></tr></thead>
<tbody>
<tr><td><code>nvidia-smi</code></td><td><code>L552-L565</code></td><td>1 秒</td><td><code>gpu_samples.csv</code></td></tr>
<tr><td>RDMA HCA counters</td><td><code>L566-L592</code></td><td>1 秒</td><td><code>rdma.csv</code></td></tr>
<tr><td>DCGM</td><td><code>L645-L655</code></td><td>1 秒</td><td><code>dcgm_dmon.log</code></td></tr>
<tr><td><code>mpstat</code></td><td><code>L656-L663</code></td><td>5 秒</td><td><code>mpstat.log</code></td></tr>
<tr><td><code>pidstat -durw</code></td><td><code>L664-L671</code></td><td>5 秒,进程级</td><td><code>pidstat.log</code></td></tr>
<tr><td><code>sar -n DEV,EDEV</code></td><td><code>L672-L678</code></td><td>5 秒</td><td><code>sar_net.log</code></td></tr>
<tr><td><code>perf stat</code></td><td><code>L680-L689</code></td><td>5 秒</td><td><code>perf_stat.log</code></td></tr>
<tr><td><code>numastat</code></td><td><code>L618-L644</code></td><td>5 秒</td><td><code>numa_samples.csv</code></td></tr>
</tbody>
</table>
<p>
CPU、进程、perf 和 sar 的每行均由 Shell 增加
<code>wall_time_ns TAB node TAB payload</code>。NUMA 直接转成结构化 CSV
避免旧版线程级 1 秒日志过大,也让所有指标能按 Case 切片。
</p>
<h2 id="alignment">7. 精确测量窗口</h2>
<h3>7.1 Phase 1 如何标记主测量</h3>
<p>
Phase 1 <code>run_quick_map.sh:L547-L564</code> 每 100 ms 观察 bench 日志;
发现 <code>Starting main benchmark run</code> 后调用
<code>quick_map_results.py mark-measurement-start</code>
<code>quick_map_results.py:L340-L385</code> 用这个起点和
<code>bench.json.duration</code> 生成:
</p>
<pre><code>measurement_started_at
measurement_ended_at
measurement_duration_s
measurement_window_source = bench_main_marker_plus_duration</code></pre>
<h3>7.2 Phase 2 如何使用</h3>
<p>
<code>hardware_contention_attribution.py:L509-L560</code> 优先读取上述字段。
只有兼容旧结果时才可能使用进程级窗口;正式配置
<code>REQUIRE_PRECISE_WINDOWS=1</code> 会拒绝任何 fallback。
<code>L561-L841</code> 对 GPU、DCGM、CPU、进程、perf、NUMA、netdev 和 RDMA
使用同一个 <code>started_ns ≤ sample ≤ ended_ns</code> 条件。
</p>
<h2 id="report">8. 逐指标报告</h2>
<p>
Python <code>summarize</code> 位于
<code>hardware_contention_attribution.py:L1036-L1378</code>
它不只生成一个抽象结论,而是按 Phase 2 第 5 节依次写出:
</p>
<table>
<thead><tr><th>指标</th><th>解析函数</th><th>Case 汇总文件</th></tr></thead>
<tbody>
<tr><td>GPU</td><td><code>summarize_gpu_rows L377-L413</code></td><td><code>case_gpu_summary.csv</code><code>case_gpu_node_summary.csv</code></td></tr>
<tr><td>DCGM</td><td><code>parse_dcgm L167-L192</code></td><td><code>case_dcgm_summary.csv</code></td></tr>
<tr><td>CPU</td><td><code>parse_mpstat L193-L222</code></td><td><code>case_cpu_summary.csv</code></td></tr>
<tr><td>进程</td><td><code>parse_pidstat L223-L289</code></td><td><code>case_process_summary.csv</code></td></tr>
<tr><td>perf</td><td><code>parse_perf L290-L310</code></td><td><code>case_perf_summary.csv</code></td></tr>
<tr><td>NUMA</td><td>结构化 CSV + <code>summarize_case_metrics</code></td><td><code>case_numa_summary.csv</code></td></tr>
<tr><td>Linux netdev</td><td><code>parse_sar_net L311-L358</code></td><td><code>case_netdev_summary.csv</code></td></tr>
<tr><td>RDMA</td><td><code>summarize_rdma_rows L424-L484</code></td><td><code>case_rdma_summary.csv</code></td></tr>
<tr><td>P2P/NCCL</td><td><code>load_communication_rows</code> + <code>aggregate_communication_rows L842-L928</code></td><td><code>communication_summary.csv</code><code>communication_aggregate.csv</code></td></tr>
</tbody>
</table>
<p>
<code>report.md</code> 对每组都打印有效样本数、Mean/P95/Max、Head/Worker
或 Case 间比较和源文件。解析不到的值保留为 <code>-</code>,不会被写成 0。
</p>
<h2 id="outputs">9. 结果目录</h2>
<pre><code>results/&lt;RUN_ID&gt;/
manifest.json
commands/
communication/
service/
bench/&lt;phase1-sub-run&gt;/
head/
gpu_samples.csv
dcgm_dmon.log
mpstat.log
pidstat.log
perf_stat.log
sar_net.log
numa_samples.csv
rdma.csv
collector_commands/
worker/
...同上...
case_windows.csv
bench_summary.csv
case_gpu_summary.csv
case_gpu_node_summary.csv
case_dcgm_summary.csv
case_cpu_summary.csv
case_process_summary.csv
case_perf_summary.csv
case_numa_summary.csv
case_netdev_summary.csv
case_rdma_summary.csv
communication_summary.csv
communication_aggregate.csv
summary.json
report.md</code></pre>
<h2 id="index">10. 函数行号索引</h2>
<h3>10.1 Shell 编排器</h3>
<table>
<thead><tr><th>行号</th><th>函数组</th><th>职责</th></tr></thead>
<tbody>
<tr><td>L26-L66</td><td>日志、远端执行、命令证据</td><td>基础设施。</td></tr>
<tr><td>L67-L199</td><td>配置、工具、时钟、GPU 空闲门禁</td><td>正式运行前 fail-fast。</td></tr>
<tr><td>L200-L268</td><td>Manifest、marker、Phase 1 委托</td><td>运行身份与复用边界。</td></tr>
<tr><td>L281-L513</td><td>通信基线</td><td>按 Run 分发源码、P2P、8/16-rank AllReduce、CROSS_NIC A/B 与清理。</td></tr>
<tr><td>L448-L516</td><td>服务和静态快照</td><td>启停 Phase 1 双机服务并保存环境。</td></tr>
<tr><td>L517-L710</td><td>采集命令与启动</td><td>两节点分层采样。</td></tr>
<tr><td>L711-L772</td><td>采集器检查和停止</td><td>fail-closed 与残留清理。</td></tr>
<tr><td>L782-L835</td><td>fixed/mixed Case</td><td>代表负载编排。</td></tr>
<tr><td>L836-L858</td><td>汇总、Manifest、trap</td><td>结果收口。</td></tr>
<tr><td>L859-L928</td><td><code>run_all</code></td><td>完整状态机。</td></tr>
<tr><td>L929-L968</td><td>辅助 action 与 main</td><td><code>communication/all/summarize/stop</code> 分发。</td></tr>
</tbody>
</table>
<h3>10.2 Python 文件</h3>
<table>
<thead><tr><th>文件/行号</th><th>职责</th></tr></thead>
<tbody>
<tr><td><code>communication_baseline.py:L20-L44</code></td><td>尺寸解析、分位数和 JSON 结果协议。</td></tr>
<tr><td><code>L45-L106</code></td><td>CUDA P2P 全矩阵。</td></tr>
<tr><td><code>L107-L198</code></td><td>NCCL AllReduce 与正确性。</td></tr>
<tr><td><code>hardware_contention_attribution.py:L76-L166</code></td><td>时间、CSV、数字统计基础函数。</td></tr>
<tr><td><code>L167-L358</code></td><td>DCGM、mpstat、pidstat、perf、sar 解析器。</td></tr>
<tr><td><code>L359-L508</code></td><td>通信、GPU、RDMA、bench 读取与汇总。</td></tr>
<tr><td><code>L509-L841</code></td><td>精确窗口和全部 Case 指标切片。</td></tr>
<tr><td><code>L842-L1035</code></td><td>通信聚合、CSV、Marker、Manifest。</td></tr>
<tr><td><code>L1036-L1378</code></td><td>全部输出表和逐指标 <code>report.md</code></td></tr>
<tr><td><code>L1379-L1480</code></td><td>CLI 子命令。</td></tr>
</tbody>
</table>
<footer>
本文只描述提交 <code>39fc2ba565a3</code>。Nsight Systems、SGLang Profiler 和
Kernel Timeline 属于 Phase 3不加入 Phase 2避免重复采集和职责混淆。
</footer>
</main>
</body>
</html>

View File

@ -1,769 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Phase 2DeepSeek-V4-Pro 双机 Pro6000D SGLang 硬件与资源竞争归因</title>
<style>
:root {
color-scheme: light;
--ink: #18202a;
--muted: #5b6570;
--line: #d8dde3;
--paper: #ffffff;
--page: #f3f5f7;
--blue: #1769aa;
--green: #16734a;
--amber: #9a5a00;
--red: #a13232;
--code: #f0f3f6;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--page);
color: var(--ink);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 16px;
line-height: 1.65;
}
header {
background: #202a34;
color: #fff;
border-bottom: 5px solid #34a17a;
}
.header-inner, main {
width: min(1120px, calc(100% - 32px));
margin: 0 auto;
}
.header-inner { padding: 38px 0 32px; }
h1, h2, h3 { letter-spacing: 0; }
h1 {
margin: 4px 0 12px;
font-size: clamp(26px, 4vw, 42px);
line-height: 1.2;
}
h2 {
margin: 38px 0 12px;
padding-bottom: 7px;
border-bottom: 2px solid var(--line);
font-size: 24px;
}
h3 { margin: 26px 0 8px; font-size: 19px; }
.eyebrow {
margin: 0;
color: #8fd8bd;
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
}
.meta {
display: flex;
flex-wrap: wrap;
gap: 8px 22px;
color: #d7dee5;
font-size: 14px;
}
main {
margin-top: 24px;
margin-bottom: 48px;
padding: 30px 38px 42px;
background: var(--paper);
border: 1px solid var(--line);
border-radius: 6px;
}
.status {
padding: 14px 16px;
border-left: 4px solid var(--amber);
background: #fff7e7;
}
.decision {
padding: 14px 16px;
border-left: 4px solid var(--green);
background: #eef8f3;
}
a { color: var(--blue); }
.back {
display: inline-block;
margin-bottom: 10px;
font-weight: 650;
}
code {
padding: 1px 5px;
background: var(--code);
border-radius: 3px;
font-family: "SFMono-Regular", Consolas, monospace;
font-size: 0.92em;
}
pre {
overflow-x: auto;
padding: 14px 16px;
background: #202a34;
color: #f4f7fa;
border-radius: 5px;
line-height: 1.5;
}
pre code { padding: 0; background: transparent; color: inherit; }
table {
width: 100%;
margin: 14px 0 22px;
border-collapse: collapse;
font-size: 14px;
}
th, td {
padding: 10px 11px;
border: 1px solid var(--line);
text-align: left;
vertical-align: top;
}
th { background: #edf1f4; }
.pass { color: var(--green); font-weight: 700; }
.pending { color: var(--amber); font-weight: 700; }
.fail { color: var(--red); font-weight: 700; }
li + li { margin-top: 5px; }
@media (max-width: 720px) {
main { padding: 22px 18px 30px; }
table { display: block; overflow-x: auto; white-space: nowrap; }
}
</style>
</head>
<body>
<header>
<div class="header-inner">
<p class="eyebrow">Design, Implementation &amp; Result Record</p>
<h1>Phase 2DeepSeek-V4-Pro 双机 Pro6000D SGLang 硬件与资源竞争归因</h1>
<div class="meta">
<span>节点174.1.51.5 + 174.1.51.7</span>
<span>拓扑SGLang TP16 / EP2</span>
<span>更新2026-07-31 16:46:05 CST</span>
</div>
</div>
</header>
<main>
<a class="back" href="./推理优化计划.html">返回推理优化主计划</a>
<a class="back" href="./phase2_code.html">打开 Phase 2 代码详解</a>
<p class="status">
<strong>当前状态Phase 2 最终采集代码已完成,等待最终双机复跑。</strong>
首次 Run <code>dsv4pro-phase2-20260731-130125</code> 的 8/8 个 benchmark
均成功;提交 <code>30664faa41f8</code> 已补齐正式测量窗口、双节点 DCGM 门禁、
低开销进程采样、机内 PCIe P2P、单/双机 AllReduce 与逐指标自动报告。
本阶段复跑完成并汇报后才进入 Phase 3。
</p>
<h2>1. Phase 1 交接结果</h2>
<table>
<thead>
<tr><th>代表负载</th><th>关键结果</th><th>Phase 2 用途</th></tr>
</thead>
<tbody>
<tr><td>128K → 1C=1</td><td>Input TPS 2,710.16TTFT P95 48.344 s</td><td>纯长 Prefill 的计算、显存与通信归因</td></tr>
<tr><td>32K → 1C=16</td><td>Input TPS 3,112.77TTFT P95 162.087 s</td><td>并发 Prefill 的排队、Chunk 调度与节点均衡</td></tr>
<tr><td>1K → 1KC=32</td><td>Output TPS 461.68TPOT P95 63.31 ms</td><td>普通 Decode 的 GPU、CPU 与通信基线</td></tr>
<tr><td>1K → 4KC=16</td><td>Output TPS 310.02TPOT P95 50.33 ms</td><td>持续 Decode、KV 增长和稳态资源占用</td></tr>
<tr><td>128K → 1KC=1</td><td>TTFT P95 49.326 sTPOT P95 32.24 ms</td><td>分离长 Prefill 与长上下文 Decode 成本</td></tr>
<tr><td>1K → 1KC=32 + 128K 注入</td><td>Output TPS -24.08%TPOT P95 +66.55%</td><td>Prefill 干扰 Decode 时的硬件资源竞争</td></tr>
</tbody>
</table>
<p>
最终基线已由 Head 与 Worker 日志证明使用
<code>mlx5_0/mlx5_3</code> 双 Rail <code>NET/IB + GDRDMA</code>
正式测量请求为冷 Prefix。正式矩阵 12/12、长 Decode 补测 2/2 均成功。
Phase 2 保持相同服务配置和请求口径。
</p>
<h2>2. 本阶段的边界</h2>
<ul>
<li>只测试 SGLang不测试 vLLM。</li>
<li>保留模型、镜像、TP16、EP2、显存比例和已验证的双 Rail NCCL 配置。</li>
<li>模型端到端 Case 不启用 Nsight Systems、PyTorch Profiler、NCCL DEBUG 或投机解码;独立通信基线临时启用 NCCL INFO 以保存实际路径证据。</li>
<li>不调参,不尝试优化;先获得足以区分瓶颈类别的硬件证据。</li>
<li>只重放五个固定代表负载和一组混合 A/B不重复 Phase 1 全矩阵。</li>
<li>采集器从请求开始前启动,到请求结束后停止,不能中途补采后声称完整。</li>
</ul>
<h2>3. 待验证假设</h2>
<table>
<thead>
<tr><th>假设</th><th>预期硬件表现</th><th>后续方向</th></tr>
</thead>
<tbody>
<tr><td>DSV4/NSA Prefill Kernel 计算受限</td><td>GPU 持续忙、高功耗和稳定频率;双 Rail 流量不高</td><td>Phase 3 捕获 Kernel 与 Attention/Indexer 时间线</td></tr>
<tr><td>权重或激活显存带宽受限</td><td>GPU Memory Utilization 高SM 指标未必饱和;功耗可能低于纯计算</td><td>补 DCGM/Profiler 的 DRAM Active再看 Kernel</td></tr>
<tr><td>TP16 跨机通信受限</td><td>RoCE 吞吐高或两条 Rail 明显失衡GPU 出现等待</td><td>NCCL_CROSS_NIC 0/1/2 快速 A/B随后看 NCCL Timeline</td></tr>
<tr><td>CPU Scheduler 或 Kernel Launch 受限</td><td>GPU 利用率锯齿或有空洞,单 CPU 核持续满载</td><td>定位 Scheduler/Tokenizer 线程与 launch gap</td></tr>
<tr><td>频率、功耗或温度限制</td><td>P-state、SM Clock 或 Power 持续异常,可能出现节流原因</td><td>修正电源、散热或 Clock Policy 后复测</td></tr>
<tr><td>节点或 Rank 不均衡</td><td>两节点或不同 GPU 的利用率、功耗、网络流量存在固定偏差</td><td>检查 NUMA、GPU-NIC 亲和与慢 Rank</td></tr>
</tbody>
</table>
<h2>4. 诊断 Run</h2>
<ol>
<li>确认 16 张 GPU 空闲,先跑两节点 PCIe P2P、单机 8 rank AllReduce 和双机 16 rank AllReduce双机分别测试 <code>NCCL_CROSS_NIC=0/1/2</code></li>
<li>保存两节点静态快照GPU/NIC/NUMA 拓扑、驱动、CUDA、镜像与服务命令。</li>
<li>复用 Phase 1 已验证的 <code>run_quick_map.sh start</code> 启动同配置双机服务。</li>
<li>在 Head 和 Worker 同时启动 GPU、CPU、网卡与 RDMA 采样,先记录 15 秒空闲基线。</li>
<li>依次重放 <code>128K → 1, C=1</code><code>32K → 1, C=16</code><code>1K → 1K, C=32</code></li>
<li>重放 <code>1K → 4K, C=16</code><code>128K → 1K, C=1</code>,观察持续与长上下文 Decode。</li>
<li>重放 <code>1K → 1K, C=32</code> Control 与 128K Prefill 注入 Treatment保留相同注入时序。</li>
<li>请求结束后继续采样 15 秒,再停止采集器和服务。</li>
<li>按时间戳将请求、GPU、CPU 和双 Rail 指标对齐,生成摘要与判定。</li>
</ol>
<pre><code>idle 15s
│ 128K→1 C1 │ 32K→1 C16 │ 1K→1K C32
│ 1K→4K C16 │ 128K→1K C1
│ Decode Control │ Decode + Prefill
cooldown 15s
Head 与 Worker 的所有采集器覆盖完整诊断窗口。</code></pre>
<p>
Phase 1 中服务加载约 5 分 30 秒;通信基线、五个固定负载、混合 A/B、
静态快照、采样和清理组成一次完整 Phase 2 Run。
</p>
<h3>4.1 你只需要运行的入口</h3>
<p class="decision">
<strong>操作规则:先在 Worker <code>.7</code> 做一次 DCGM 准备,再只在
Head <code>.5</code> 执行 Phase 2 的 <code>all</code></strong>
不要手工执行 Phase 1 的 <code>start</code><code>stop</code>
Phase 2 会在内部复用它们并负责异常退出时的采集器、Head、Worker 清理。
</p>
<pre><code class="language-bash"># [仅在 Worker 174.1.51.7 执行一次]
# 不需要 source、conda activate也不要在 .7 运行 Phase 2 的 all
systemctl start nvidia-dcgm
systemctl is-active nvidia-dcgm
dcgmi discovery -l
# 预期:第二条输出 active第三条列出本机 8 张 GPU
# [以下仅在 Head 174.1.51.5 执行]
cd /data/hzy/sskj/experiments/pro6000/dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution
# 第一次先展开全部命令,不启动服务、不占用 GPU、不发送请求
DRY_RUN=1 RUN_ID=dsv4pro-phase2-dryrun-$(date +%Y%m%d-%H%M%S) \
bash run_hardware_contention_attribution.sh all
# 正式实验:仍然只有同一个 all 入口tmux 只负责断线后继续运行
RUN_ID=dsv4pro-phase2-$(date +%Y%m%d-%H%M%S)
tmux new-session -d -s dsv4pro-phase2 \
"RUN_ID=${RUN_ID} bash run_hardware_contention_attribution.sh all \
2&gt;&amp;1 | tee /data/hzy/${RUN_ID}.log"
tmux attach -t dsv4pro-phase2</code></pre>
<p>
<code>.7</code> 的三条命令只负责让 Worker DCGM Host Engine 可用;
SGLang Worker、其余采集器和结果回收仍由 <code>.5</code> 的唯一入口通过 SSH 管理。
若需要机器重启后自动启动 DCGM应由运维另行决定是否执行
<code>systemctl enable nvidia-dcgm</code>
</p>
<p><strong><code>all</code> 内部执行顺序:</strong></p>
<pre><code>配置、工具、DCGM 与 GPU 空闲门禁
→ 通信基线:两节点 P2P、两组单机 8-rank AllReduce、
三组双机 16-rank NCCL_CROSS_NIC A/B
→ Phase 1 start启动同配置 TP16 服务
→ 两节点静态快照
→ 启动两节点采集器并记录 15 秒 idle
→ 五个固定 Case
→ 混合 Prefill/Decode A/B
→ 15 秒 cooldown
→ 停止采集器并保存后快照
→ Phase 1 stop停止 Head/Worker
→ 生成按第 5 节逐项对应的 CSV、JSON 与 report.md</code></pre>
<p>
Phase 1 的作用是提供已经验证过的双机 Docker 服务和 Benchmark 实现,
不是第二个用户入口。实际展开的服务、Benchmark 和采集命令都会写入
<code>results/&lt;RUN_ID&gt;/service/</code><code>commands/</code>
<code>head|worker/collector_commands/</code>,不依赖跨文档猜测。
</p>
<h2>5. 采集指标</h2>
<p>
本节记录正式实现使用的命令,而不是建议性伪代码。命令由
<code>run_hardware_contention_attribution.sh</code> 在 Head 和 Worker 同时启动;
每条展开后的命令会另外保存在
<code>results/&lt;RUN_ID&gt;/head|worker/collector_commands/</code>
</p>
<table>
<thead>
<tr><th>层级</th><th>连续采样</th><th>静态或前后快照</th></tr>
</thead>
<tbody>
<tr><td>GPU</td><td>利用率、Memory Utilization、显存、功耗、SM/Memory Clock、温度、P-state</td><td><code>nvidia-smi topo -m</code>、Compute Process</td></tr>
<tr><td>CPU</td><td>每核利用率、上下文切换、服务进程 CPU/内存</td><td>NUMA 拓扑、容器 PID 与 CPU Affinity</td></tr>
<tr><td>Network</td><td><code>eth0/eth3</code> RX/TX</td><td><code>ethtool -S</code> 错误计数前后差</td></tr>
<tr><td>RDMA</td><td><code>mlx5_0/mlx5_3</code> port_xmit/recv_data 差分</td><td>Port State、GID 与错误计数</td></tr>
<tr><td>DCGM</td><td>SM Active、DRAM Active、Tensor Active、PCIe</td><td>工具版本与可用 Field</td></tr>
</tbody>
</table>
<h3>5.1 时间对齐与 Case Marker</h3>
<pre><code class="language-bash"># 每条 GPU/RDMA 样本写入相同格式的宿主机墙钟时间
date +%s%N
# 实验前检查两节点秒级时钟差
date +%s
# Case 开始、结束和服务状态由 Python 写入 markers.csv
python3 hardware_contention_attribution.py marker \
--path markers.csv \
--node head \
--event case_start \
--case-id long_prefill_latency_128k_c1</code></pre>
<table>
<thead><tr><th>数据</th><th>含义</th><th>为什么需要</th></tr></thead>
<tbody>
<tr><td><code>wall_time_ns</code></td><td>Unix Epoch 纳秒时间</td><td>把 GPU、CPU、RDMA 与 Benchmark 放到同一时间轴</td></tr>
<tr><td><code>case_start/case_end</code></td><td>一个 Case 的编排边界</td><td>从整段连续采样中切出对应负载</td></tr>
<tr><td><code>CLOCK_SKEW_TOLERANCE_S=2</code></td><td>两节点允许的最大秒级时钟差</td><td>避免 Head/Worker 的同一时刻被错位比较</td></tr>
</tbody>
</table>
<p>
最终实现由 Phase 1 监听 <code>bench.log</code> 中的
<code>Starting main benchmark run</code>,立刻写入
<code>measurement_start.json</code>;再使用 SGLang <code>bench.json</code>
的正式 benchmark duration 计算结束时间。Phase 2 优先读取
<code>measurement_started_at/measurement_ended_at</code>,不会把数据生成和
Warm-up 混入硬件均值。<code>REQUIRE_PRECISE_WINDOWS=1</code> 时,任何 Case
缺少精确窗口都会让汇总失败,而不是悄悄回退。
</p>
<h3>5.2 GPU 基础状态:<code>nvidia-smi</code></h3>
<pre><code class="language-bash">nvidia-smi \
--query-gpu=index,timestamp,utilization.gpu,utilization.memory,\
memory.used,memory.total,power.draw,temperature.gpu,\
clocks.sm,clocks.mem,pstate \
--format=csv,noheader,nounits</code></pre>
<p>脚本每秒运行一次,并在每行前加入 <code>wall_time_ns</code> 和节点角色。</p>
<table>
<thead><tr><th>字段</th><th>代表什么</th></tr></thead>
<tbody>
<tr><td><code>utilization.gpu</code></td><td>采样周期内至少有一个 Kernel 在执行的时间比例</td></tr>
<tr><td><code>utilization.memory</code></td><td>采样周期内显存控制器处于忙碌状态的时间比例</td></tr>
<tr><td><code>memory.used/total</code></td><td>当前总显存分配量与设备显存容量</td></tr>
<tr><td><code>power.draw</code></td><td>GPU 当前功耗,用于比较不同负载的能耗状态</td></tr>
<tr><td><code>clocks.sm/clocks.mem</code></td><td>SM 与显存当前工作频率</td></tr>
<tr><td><code>pstate</code></td><td>GPU 性能状态P0 通常是最高性能态</td></tr>
</tbody>
</table>
<p>
原始输出为 <code>head|worker/gpu_samples.csv</code>
<code>gpu_summary.csv</code> 汇总整段运行,
<code>case_gpu_summary.csv</code> 按节点、Case 和 GPU 汇总平均值与峰值。
</p>
<h3>5.3 GPU Profiling CounterDCGM</h3>
<pre><code class="language-bash">DCGM_FIELD_IDS=1001,1002,1003,1004,1005,1009,1010
dcgmi dmon \
-e 1001,1002,1003,1004,1005,1009,1010 \
-d 1000</code></pre>
<table>
<thead><tr><th>Field ID</th><th>Field Tag</th><th>含义</th></tr></thead>
<tbody>
<tr><td>1001</td><td><code>gr_engine_active</code></td><td>Graphics/Compute Engine 活跃比例,接近整体 GPU 执行忙碌度</td></tr>
<tr><td>1002</td><td><code>sm_active</code></td><td>SM 至少有一个 Warp 活跃的比例</td></tr>
<tr><td>1003</td><td><code>sm_occupancy</code></td><td>活跃 Warp 相对硬件可容纳 Warp 的比例</td></tr>
<tr><td>1004</td><td><code>tensor_active</code></td><td>Tensor Core 指令活跃比例</td></tr>
<tr><td>1005</td><td><code>dram_active</code></td><td>设备显存接口活跃比例Pro6000D 为 GDDR7用于判断设备显存带宽压力</td></tr>
<tr><td>1009</td><td><code>pcie_tx_bytes</code></td><td>GPU 经 PCIe 发出的字节速率</td></tr>
<tr><td>1010</td><td><code>pcie_rx_bytes</code></td><td>GPU 经 PCIe 接收的字节速率</td></tr>
</tbody>
</table>
<p>
<code>sm_active</code> 高而 <code>sm_occupancy</code> 低,表示 SM 经常有工作,
但同时驻留的 Warp 不多;后续通过 Kernel Timeline 区分小 Kernel、
寄存器/共享内存约束和同步。DCGM 是 NVIDIA Data Center GPU Manager
<code>nvidia-dcgm</code>/<code>nv-hostengine</code> 是后台 Host Engine
<code>dcgmi</code> 是客户端Field ID 是指标编号。最终代码在两节点预检
<code>dcgmi discovery -l</code>,任一 Host Engine 不可用即 fail-fast
正式结果必须同时包含 Head 和 Worker 的 <code>case_dcgm_summary.csv</code>
</p>
<h3>5.4 CPU、进程与 Kernel Launch 侧证据</h3>
<pre><code class="language-bash"># 全部逻辑 CPU每 5 秒输出一次
mpstat -P ALL 5
# 找到容器内进程对应的宿主 PID
docker top &lt;container&gt; -eo pid,ppid,psr,pcpu,pmem,stat,comm,args
# 最终命令:进程级 CPU、I/O、缺页、上下文切换不展开全部线程
pidstat -durw -p "&lt;comma-separated-host-pids&gt;" 5
# 每 5 秒输出一次硬件/软件计数器增量
perf stat -p "&lt;comma-separated-host-pids&gt;" -I 5000 \
-e cycles,instructions,cache-misses,context-switches,\
cpu-migrations,page-faults
# mpstat/pidstat/perf 每行都由包装器增加:
# wall_time_ns TAB node TAB 原始输出</code></pre>
<table>
<thead><tr><th>命令/字段</th><th>回答的问题</th></tr></thead>
<tbody>
<tr><td><code>mpstat -P ALL</code></td><td>整机是否 CPU 饱和,是否只有少量核心接近 100%,是否存在 I/O Wait</td></tr>
<tr><td><code>docker top</code></td><td>把容器进程映射为宿主 PID、CPU 核 <code>PSR</code> 和进程状态</td></tr>
<tr><td><code>pidstat -u</code></td><td>服务进程的用户态、内核态 CPU 时间</td></tr>
<tr><td><code>pidstat -d</code></td><td>进程块设备 I/O</td></tr>
<tr><td><code>pidstat -r</code></td><td>内存和 Page Fault 行为</td></tr>
<tr><td><code>pidstat -w</code></td><td>主动/被动上下文切换,辅助发现线程阻塞或调度抖动</td></tr>
<tr><td><code>perf cycles/instructions</code></td><td>CPU 周期与指令执行量,可计算近似 IPC</td></tr>
<tr><td><code>cache-misses/migrations</code></td><td>CPU Cache 压力和线程跨核迁移</td></tr>
</tbody>
</table>
<p>
最终实现使用进程级 5 秒采样,避免首轮线程级 1 秒采样产生数百 MB 日志。
<code>case_cpu_summary.csv</code><code>case_process_summary.csv</code>
<code>case_perf_summary.csv</code> 都按正式测量窗口切片;只有先发现异常进程,
才在后续短窗口单独开启线程级采样。
</p>
<h3>5.5 NUMA 与 CPU/内存亲和</h3>
<pre><code class="language-bash"># 静态 NUMA 节点、CPU 和内存布局
numactl --hardware
numastat -m
# 每 5 秒按容器宿主 PID 查看本地/远端 NUMA 内存
numastat -p &lt;host-pid&gt;
# 解析为:
# wall_time_ns,node,node0_mib,node1_mib,total_mib,process_count
# 同时保存 GPU、CPU、NIC 的拓扑关系
nvidia-smi topo -m</code></pre>
<p>
NUMA 是多路 CPU 机器的“本地内存”结构。进程长期从远端 NUMA Node 取内存,
或 GPU/NIC 对应的 CPU 线程被调度到另一侧,可能增加 Host 侧延迟。
最终采集器把 <code>numastat -p</code> 解析为
<code>numa_samples.csv</code>,再按正式测量窗口生成
<code>case_numa_summary.csv</code>。这样可以直接比较 Node0/Node1 MiB
而不是依靠人工阅读不断刷新的文本。
</p>
<h3>5.6 普通网卡统计与 RDMA 数据面</h3>
<pre><code class="language-bash"># Linux netdev 层,每 5 秒采样吞吐与错误
sar -n DEV,EDEV 5
# Case 前后保存物理端口状态和驱动计数器
ethtool eth0
ethtool eth3
ethtool -S eth0
ethtool -S eth3
# RDMA 设备与端口状态
ibdev2netdev
ibstat
rdma link show</code></pre>
<p>
<code>sar</code> 记录 Linux 普通网络栈中的 <code>eth0/eth3</code> 流量;
GDRDMA 数据量由 <code>mlx5_0/mlx5_3</code> HCA 的 sysfs Counter 记录:
</p>
<pre><code class="language-bash">for hca in mlx5_0 mlx5_3; do
base="/sys/class/infiniband/${hca}/ports/1"
cat "${base}/counters/port_xmit_data"
cat "${base}/counters/port_rcv_data"
cat "${base}/counters/port_xmit_wait"
cat "${base}/counters/port_xmit_discards"
cat "${base}/counters/port_rcv_errors"
cat "${base}/hw_counters/req_transport_retries_exceeded"
cat "${base}/hw_counters/req_rnr_retries_exceeded"
done</code></pre>
<table>
<thead><tr><th>Counter</th><th>含义</th></tr></thead>
<tbody>
<tr><td><code>port_xmit_data/port_rcv_data</code></td><td>HCA 发送/接收数据累计量IB Counter 单位是 4 Octets脚本用 <code>delta × 4 × 8 / seconds</code> 换算 Gbit/s</td></tr>
<tr><td><code>port_xmit_wait</code></td><td>端口因缺少发送 Credit 等原因等待的时间,持续增长可能指向拥塞</td></tr>
<tr><td><code>port_xmit_discards/port_rcv_errors</code></td><td>发送丢弃和接收错误增量</td></tr>
<tr><td><code>req_transport_retries_exceeded</code></td><td>RDMA Transport 重试耗尽</td></tr>
<tr><td><code>req_rnr_retries_exceeded</code></td><td>Receiver Not Ready 重试耗尽</td></tr>
<tr><td><code>roce_adp_retrans*</code></td><td>RoCE 自适应重传及超时相关计数</td></tr>
<tr><td><code>np_ecn_marked* / *cnp*</code></td><td>ECN 标记和拥塞通知包,用于辅助判断 RoCE 拥塞</td></tr>
</tbody>
</table>
<p>
原始数据为 <code>head|worker/rdma.csv</code>
<code>case_rdma_summary.csv</code> 按 Case、节点和 HCA 计算吞吐及错误增量。
它说明双 Rail 的实际流量、均衡性和错误增量;
<code>case_netdev_summary.csv</code> 同时保留 Linux netdev 层的
<code>eth0/eth3</code> RX/TX 与错误。Phase 3 再把 NCCL Collective
放到请求 Timeline 中分析持续时间和计算重叠。
</p>
<h3>5.7 机内 PCIe 与 NCCL 通信基线</h3>
<pre><code class="language-bash"># 由 all 入口自动执行;不需要用户手工运行 torchrun
# 每个节点:所有 GPU 源/目标对FP16 256 MiB CUDA P2P copy
python3 communication_baseline.py p2p \
--size 256M --warmup 3 --iterations 10
# 每个节点8 rank NCCL AllReduce
torchrun --standalone --nproc-per-node=8 \
communication_baseline.py all-reduce \
--sizes 1M,64M,1G --repetitions 3 --warmup 5 --iterations 10
# 双节点16 rank分别设置 NCCL_CROSS_NIC=0、1、2
torchrun --nnodes=2 --nproc-per-node=8 \
--master-addr 10.101.0.11 --node-rank &lt;0-or-1&gt; \
communication_baseline.py all-reduce \
--sizes 1M,64M,1G --repetitions 3 --warmup 5 --iterations 10</code></pre>
<p>
P2P 结果按 <code>same_pcie_switch</code>PIX
<code>cross_numa_sys</code>SYS分别汇总不用一个平均值掩盖跨 CPU 路径。
AllReduce 同时报告 P50/P95 latency、<code>algbw</code>
<code>busbw</code>、正确性错误数和实际 NCCL 路径。1 MiB、64 MiB、1 GiB
分别覆盖小消息延迟、中等消息和大消息带宽;双机 A/B 直接给出
<code>NCCL_CROSS_NIC=0/1/2</code> 的数值比较。
</p>
<h3>5.8 静态快照与结果关系</h3>
<pre><code class="language-bash">nvidia-smi
nvidia-smi topo -m
lscpu
numactl --hardware
ip -details link show eth0
ip -details link show eth3
docker inspect &lt;container&gt;
docker top &lt;container&gt; -eo pid,ppid,psr,pcpu,pmem,stat,comm,args</code></pre>
<table>
<thead><tr><th>结果文件</th><th>内容</th><th>主要用途</th></tr></thead>
<tbody>
<tr><td><code>static_before.log / static_after.log</code></td><td>GPU、CPU、NUMA、NIC、RDMA、容器前后快照</td><td>证明运行环境,并比较错误计数和清理状态</td></tr>
<tr><td><code>collector_status.csv</code></td><td>每个采集器的启动、停止或提前退出状态</td><td>防止把缺失采集器当作 0 值</td></tr>
<tr><td><code>case_windows.csv</code></td><td>每个 Benchmark Case 的起止时间</td><td>从连续硬件日志中切片</td></tr>
<tr><td><code>bench_summary.csv</code></td><td>TPS、TTFT、TPOT、ITL、E2E</td><td>把硬件现象与用户侧性能对应</td></tr>
<tr><td><code>case_gpu_summary.csv</code></td><td>每 Case、节点、GPU 的利用率、显存、功耗、频率</td><td>比较负载与节点/GPU 不均衡</td></tr>
<tr><td><code>case_dcgm_summary.csv</code></td><td>每 Case、节点、GPU 的 SM/Tensor/显存接口/PCIe 指标</td><td>区分计算、设备显存和 PCIe 活跃度</td></tr>
<tr><td><code>case_cpu_summary.csv</code></td><td>整机与逐核 CPU 利用率、I/O Wait</td><td>识别整机饱和和少数热点核</td></tr>
<tr><td><code>case_process_summary.csv</code></td><td>服务进程 CPU、I/O、缺页、内存与上下文切换</td><td>定位 Host 进程开销与阻塞</td></tr>
<tr><td><code>case_perf_summary.csv</code></td><td>cycles、instructions、cache miss、迁移与缺页</td><td>计算 IPC 并判断 Cache/调度压力</td></tr>
<tr><td><code>case_numa_summary.csv</code></td><td>Node0/Node1 进程内存分布</td><td>识别跨 NUMA 放置</td></tr>
<tr><td><code>case_netdev_summary.csv</code></td><td><code>eth0/eth3</code> 吞吐与错误</td><td>与 RDMA HCA Counter 做分层核对</td></tr>
<tr><td><code>case_rdma_summary.csv</code></td><td>每 Case、节点、Rail 的吞吐和错误增量</td><td>判断双 Rail 使用、均衡和数据面错误</td></tr>
<tr><td><code>communication_summary.csv</code></td><td>每次 P2P/AllReduce 原始测量</td><td>保留每条 GPU 对、消息尺寸、CROSS_NIC 和重复实验</td></tr>
<tr><td><code>communication_aggregate.csv</code></td><td>PIX/SYS P2P 与单/双机 AllReduce 聚合</td><td>提供 P50/P95、algbw、busbw 和正确性比较</td></tr>
</tbody>
</table>
<h3>5.9 最终结果如何逐项汇报</h3>
<p class="decision">
最终 <code>report.md</code> 的章节顺序与本节一一对应。每一项必须同时给出
<strong>原始文件、有效样本数、Head/Worker 数值、Case 间变化和解释</strong>
不能只写“GPU 较忙”“网络未饱和”这类抽象结论。
</p>
<table>
<thead><tr><th>第 5 节指标</th><th>报告中的数值</th><th>最小分析动作</th></tr></thead>
<tbody>
<tr><td>5.1 时间窗</td><td>窗口来源、开始/结束、duration、采样数</td><td>确认全部为 <code>bench_main_marker_plus_duration</code></td></tr>
<tr><td>5.2 GPU</td><td>利用率/显存/功耗/频率的 Mean、P95、Max</td><td>比较两节点、8 卡离散度和不同 Case</td></tr>
<tr><td>5.3 DCGM</td><td>SM Active/Occupancy、Tensor/DRAM Active、PCIe TX/RX</td><td>比较计算、设备显存和 PCIe 哪一侧随负载上升</td></tr>
<tr><td>5.4 CPU/进程/perf</td><td>整机/热点核、进程 CPU/I/O/缺页/切换、IPC/Cache miss</td><td>区分整机容量、单线程热点和 Host 调度开销</td></tr>
<tr><td>5.5 NUMA</td><td>Node0/Node1 MiB 与比例</td><td>比较服务内存是否偏离 GPU/NIC 所在 NUMA</td></tr>
<tr><td>5.6 Network/RDMA</td><td>eth0/eth3、mlx5_0/mlx5_3 Gbit/s 与错误增量</td><td>计算双 Rail 均衡比例并核对丢弃/重试</td></tr>
<tr><td>5.7 Communication</td><td>PIX/SYS P2P、8/16 rank AllReduce P50/P95、algbw/busbw</td><td>比较跨 NUMA 损失与 CROSS_NIC 0/1/2</td></tr>
</tbody>
</table>
<p>
某个采集器无数据时报告显示 <code>-</code> 并附失败状态,不会把缺失值写成
<code>0</code>。正式 Run 默认 <code>ALLOW_PARTIAL_COLLECTORS=0</code>
因此必需采集器提前退出会让 Run 失败。
</p>
<h2>6. 精简代码设计</h2>
<p>已新增目录:</p>
<pre><code>/data/hzy/sskj/experiments/pro6000/
dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution/</code></pre>
<table>
<thead>
<tr><th>文件</th><th>职责</th><th>当前状态</th></tr>
</thead>
<tbody>
<tr><td><code>run_hardware_contention_attribution.sh</code></td><td>唯一 Shell 入口;按 Run 分发通信代码、通信基线、服务启停、双节点采集器、Case 编排、门禁和 Trap 清理</td><td class="pass">已实现</td></tr>
<tr><td><code>config.env</code></td><td>Phase 1 相对路径、节点、代表 Case、分层采样周期、通信基线与 fail-closed 策略</td><td class="pass">已实现</td></tr>
<tr><td><code>communication_baseline.py</code></td><td>CUDA P2P 全矩阵与 PyTorch/NCCL 8/16-rank AllReduce 微基准</td><td class="pass">已实现</td></tr>
<tr><td><code>hardware_contention_attribution.py</code></td><td>精确窗口、全部采集器解析、逐 Case 汇总、通信聚合和逐指标报告</td><td class="pass">已实现</td></tr>
<tr><td><code>tests/test_hardware_contention_attribution.py</code></td><td>Worker 无仓库依赖、GPU/RDMA、精确窗口、DCGM/CPU 解析、通信聚合和结果生成测试</td><td class="pass">9/9 通过</td></tr>
<tr><td><code>README.md</code></td><td>唯一入口、范围和结果目录说明</td><td class="pass">已实现</td></tr>
</tbody>
</table>
<p class="decision">
Phase 2 不复制双机 Docker 启停实现。唯一入口在内部调用 Phase 1 的
<code>run_quick_map.sh start/fixed/mixed/stop</code>,只新增通信基线、硬件采集、时间对齐和代表负载编排。
顶层仍只保留一个 Shell 文件,不创建额外 tmux、launch、start 或 stop 脚本。
</p>
<h2>7. 结果结构</h2>
<pre><code>results/&lt;RUN_ID&gt;/
manifest.json
run.log
bench/
bench_cmd.txt
bench.log
bench.jsonl
service/
head_server_cmd.txt
worker_server_cmd.txt
head_server.log
worker_server.log
communication/
communication_baseline.py
communication_baseline.sha256
p2p_head.log
p2p_worker.log
allreduce_head_8gpu.log
allreduce_worker_8gpu.log
allreduce_two_node_x0.log
allreduce_two_node_x1.log
allreduce_two_node_x2.log
head/
gpu_samples.csv
dcgm_dmon.log
mpstat.log
pidstat.log
sar_net.log
perf_stat.log
docker_top.log
numa_samples.csv
rdma.csv
static_before.log
static_after.log
collector_commands/
worker/
...
collector_status.csv
markers.csv
bench_summary.csv
gpu_summary.csv
rdma_summary.csv
case_windows.csv
communication_summary.csv
communication_aggregate.csv
case_gpu_summary.csv
case_gpu_node_summary.csv
case_dcgm_summary.csv
case_cpu_summary.csv
case_process_summary.csv
case_perf_summary.csv
case_numa_summary.csv
case_netdev_summary.csv
case_rdma_summary.csv
summary.json
report.md</code></pre>
<h2>8. 验收结果</h2>
<ul>
<li class="pass">最终代码固定到提交 <code>39fc2ba565a3</code>Shell 语法检查和三个 Python 文件编译通过。</li>
<li class="pass">Phase 1 精确窗口 4/4 单元测试通过Phase 2 worker 分发、采集、解析与通信聚合 9/9 单元测试通过。</li>
<li class="pass">完整 Dry-run 不启动服务即可展开全部模型、采集和通信命令;通信子流程生成 2 个 P2P、2 个单机 AllReduce、6 个双机 rank 命令。</li>
<li class="pass">双节点 smoke Run <code>dsv4pro-phase2-stage-smoke-20260731-162326</code> 已通过 Head/Worker P2P、两组 8-rank 与一组 16-rank AllReduce<code>wrong_values=0</code>;暂存文件、容器和 GPU 进程清理完成。</li>
<li class="pass">最终代码默认要求精确测量窗口、两端 DCGM 可用和全部必需采集器存活,缺失时 fail-closed。</li>
<li>首次 Run 的性能数据保留在第 10 节;最终代码尚未在 16 卡上复跑,因此新通信基线和逐指标表暂不填写虚构数值。</li>
</ul>
<h2>9. 实施记录</h2>
<table>
<thead>
<tr><th>时间</th><th>代码或运行</th><th>结果</th></tr>
</thead>
<tbody>
<tr><td>2026-07-30 15:46 CST</td><td>创建 Phase 2 设计与档案</td><td>采用单入口和独立轻量采样,不复制双机服务启动逻辑</td></tr>
<tr><td>2026-07-30 22:55:37 CST</td><td>完成 Phase 1 阶段交接</td><td>双 Rail 门禁和 12/12 正式结果通过;选定纯 Prefill、并发 Prefill、混合干扰三个诊断负载</td></tr>
<tr><td>2026-07-31 12:26:00 CST</td><td>完成 Phase 2 代码</td><td>扩展为五个固定负载和混合 A/B实现双节点 GPU/DCGM/CPU/NUMA/网络/RDMA 采集、时间对齐和异常清理</td></tr>
<tr><td>2026-07-31 12:26:00 CST</td><td>本地验证</td><td><code>bash -n</code>、Python 编译、5 项单元测试与全流程 Dry-run 通过;未占用 GPU</td></tr>
<tr><td>2026-07-31 13:27:51 CST</td><td>完成正式双机 Run</td><td>Run <code>dsv4pro-phase2-20260731-130125</code>8/8 benchmark 成功,总用时 26 分 26 秒,无 OOM</td></tr>
<tr><td>2026-07-31 13:40:03 CST</td><td>完成首轮结果归因</td><td>排除原始双 Rail 带宽饱和、整机 CPU 饱和和频率塌陷作为首要原因;锁定 TP16 Kernel、调度与同步时间线</td></tr>
<tr><td>2026-07-31 15:25:00 CST</td><td>完成最终 Phase 2 代码</td><td>提交 <code>30664faa41f8</code>:精确主测量窗口、双节点 DCGM 门禁、5 秒低开销 Host 采样、PCIe/NCCL 基线和逐指标自动报告均已通过本地验证</td></tr>
<tr><td>2026-07-31 16:18:35 CST</td><td>修复 Worker 通信代码路径</td><td>提交 <code>39fc2ba565a3</code>:通信脚本按 Run 自动分发并校验哈希Worker 不再要求存在同路径 Git 仓库9/9 回归测试通过</td></tr>
<tr><td>2026-07-31 16:27:58 CST</td><td>双节点通信 smoke test</td><td>1 MiB 最小功能验证完整通过 P2P、8-rank 和 16-rank AllReduce仅验证链路不作为正式带宽数据</td></tr>
</tbody>
</table>
<h2>10. 首次真机结果</h2>
<p class="decision">
<strong>Run<code>dsv4pro-phase2-20260731-130125</code>,状态
<code>COMPLETED</code></strong>运行时间为 13:01:25 至 13:27:51 CST
8 个结果全部成功0 个失败。正式入口仅在 <code>174.1.51.5</code> 执行;
Worker 服务和采集器由脚本通过 SSH 自动启动。
</p>
<pre><code class="language-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&gt;&amp;1 | tee /data/hzy/${RUN_ID}.log"</code></pre>
<h3>10.1 代表负载</h3>
<table>
<thead>
<tr><th>Case</th><th>Input TPS</th><th>Output TPS</th><th>TTFT P95</th><th>TPOT P95</th></tr>
</thead>
<tbody>
<tr><td>128K → 1, C=1</td><td>2,618.53</td><td>0.02</td><td>50.036 s</td><td></td></tr>
<tr><td>32K → 1, C=16</td><td>3,116.20</td><td>0.10</td><td>161.899 s</td><td></td></tr>
<tr><td>1K → 1K, C=32</td><td>447.41</td><td>447.41</td><td>10.144 s</td><td>65.63 ms</td></tr>
<tr><td>1K → 4K, C=16</td><td>79.35</td><td>317.41</td><td>1.727 s</td><td>50.01 ms</td></tr>
<tr><td>128K → 1K, C=1</td><td>1,610.89</td><td>12.59</td><td>48.489 s</td><td>32.12 ms</td></tr>
</tbody>
</table>
<h3>10.2 混合 Prefill/Decode</h3>
<table>
<thead>
<tr><th>Decode 指标</th><th>Control</th><th>注入 128K Prefill</th><th>变化</th></tr>
</thead>
<tbody>
<tr><td>Output TPS</td><td>454.39</td><td>345.20</td><td>-24.03%</td></tr>
<tr><td>TTFT P95</td><td>9.437 s</td><td>9.869 s</td><td>+4.58%</td></tr>
<tr><td>TPOT P95</td><td>66.17 ms</td><td>110.36 ms</td><td>+66.79%</td></tr>
<tr><td>E2E P95</td><td>72.225 s</td><td>117.941 s</td><td>+63.30%</td></tr>
</tbody>
</table>
<p>
这再次证明 Prefill 会明显干扰正在进行的 Decode。ITL P95 仍约为
62 ms并不与 TPOT 恶化矛盾:少量同步长停顿可能不足全部 token 间隔的 5%
因而会被全局 token 级 ITL P95 隐藏,而请求级 TPOT 和 E2E 会暴露它。
</p>
<h3>10.3 GPU、CPU 与通信</h3>
<ul>
<li>128K Prefill 注入窗口两节点平均 GPU 利用率为 99.78% / 99.34%,平均功耗约 274 W频率稳定在约 2.382.41 GHz没有频率塌陷证据。</li>
<li>显存稳定在每卡约 83.283.4 GiB / 85,651 MiB只剩约 2.3 GiB 余量。</li>
<li>整机 CPU 平均约 8%11%I/O Wait 为 0但注入窗口仍有 5/4 个 Head/Worker 核平均超过 80%,单线程调度或 NUMA 热点尚未排除。</li>
<li>两条 RDMA Rail 流量几乎对称,所有采集到的错误增量均为 0。最高负载为 32K → 1, C=16Head/Worker 总发送约 140.0/139.3 Gbit/s即每条 400G Rail 约 70 Gbit/s。</li>
<li>因此原始 RoCE 带宽没有饱和;但 TP16 collective 的延迟、调度和 Rank 同步开销仍需 Timeline 才能拆开。</li>
</ul>
<h3>10.4 卡间通信路径</h3>
<table>
<thead>
<tr><th>范围</th><th>实际路径</th><th>本轮是否测量</th></tr>
</thead>
<tbody>
<tr><td>单机 8 卡内部</td><td>无 NVLinkNCCL <code>P2P/IPC</code> 走 PCIe。GPU03、GPU47 各自在 PCIe Switch 内为 <code>PIX</code>,两组之间为 <code>SYS</code></td><td>首次 Run 仅有 DCGM PCIe 指标;最终代码已加入所有 GPU 对的 256 MiB P2P 微基准</td></tr>
<tr><td>两机之间</td><td><code>mlx5_0 + mlx5_3</code> 双 Rail <code>NET/IB + GDRDMA</code></td><td>已测量每 Case HCA 流量、均衡性和错误增量</td></tr>
</tbody>
</table>
<p>
最终代码使用当前 SGLang 镜像内的 PyTorch/CUDA/NCCL 实现等价微基准:
两节点 P2P 全矩阵、两组单机 8-rank AllReduce 和三组双机 16-rank
<code>NCCL_CROSS_NIC</code> A/B。结果统一写入
<code>communication_summary.csv</code><code>communication_aggregate.csv</code>
完成 Phase 2 后,后续阶段不重复跑这些微基准。
</p>
<h3>10.5 首轮结论与最终代码修正</h3>
<p class="decision">
当前证据支持把下一步缩到 TP16 的 Kernel、Scheduler、PCIe/RDMA Collective
和 Rank 同步时间线。Phase 3 只分析真实请求中通信出现的位置、耗时和与计算的
重叠关系,不重复 Phase 2 的平均 GPU/CPU/RDMA 采集。原始双 Rail 带宽、整机
CPU 容量和降频都不像首要瓶颈Phase 3 将继续定位具体 Kernel 和同步根因。
</p>
<ul>
<li>Worker DCGM 缺失已改为双节点启动前门禁;最终 Run 不再接受单边 DCGM 数据。</li>
<li>宽泛 Case 窗口已改为正式 benchmark 起点加 duration 的精确窗口,并由 <code>REQUIRE_PRECISE_WINDOWS=1</code> 强制执行。</li>
<li><code>pidstat/mpstat/perf/sar/numastat</code> 已改为进程级 5 秒采样,保留时间戳并降低诊断扰动。</li>
<li>最终 <code>report.md</code> 已按第 5 节逐项输出数值表;缺失采集显示为 <code>-</code>,不会解释为 0。</li>
<li>完整归因见 <a href="./results/dsv4pro-phase2-20260731-130125/analysis.md"><code>analysis.md</code></a>,原始结构化摘要和两端 NCCL 证据已一并归档。</li>
</ul>
<p><a class="back" href="./phase1_exp.html">返回 Phase 1 实验档案</a></p>
<p><a class="back" href="./推理优化计划.html">返回推理优化主计划</a></p>
</main>
</body>
</html>

View File

@ -443,15 +443,14 @@
<tr> <tr>
<td>DeepSeek-V4-Pro / 双机 Pro6000D / SGLang 硬件与资源竞争归因</td> <td>DeepSeek-V4-Pro / 双机 Pro6000D / SGLang 硬件与资源竞争归因</td>
<td>最终采集代码已完成;首轮 8/8 成功Worker 分发修复与双节点通信 smoke test 已通过,等待最终正式复跑</td> <td>最终采集代码已完成;首轮 8/8 成功Worker 分发修复与双节点通信 smoke test 已通过,等待最终正式复跑</td>
<td> <td>Phase 2 进行中;完成最终复跑与汇报后生成实验档案和代码详解</td>
<a href="./phase2_exp.html">打开 Phase 2 实验档案</a><br>
<a href="./phase2_code.html">打开 Phase 2 代码详解</a>
</td>
</tr> </tr>
</tbody></table> </tbody></table>
<p> <p>
<strong>阶段档案规范:</strong>正文只保留最终成功实验、有效结果和结论; <strong>阶段档案生成门禁:</strong>Phase 在实验结束、结果汇总并完成汇报确认前,
失败尝试压缩到末尾的经验教训。阶段完成时删除“暂不能下结论”等过渡内容。 不创建或维护 <code>phaseN_exp.html</code><code>phaseN_code.html</code>
进行中只维护代码、原始结果和本页状态。阶段确认完成后再一次性生成两份最终 HTML
正文只保留成功实验、有效结果和结论,失败尝试压缩到末尾的经验教训。
</p> </p>
<h2>0. 先看懂双机通信</h2> <h2>0. 先看懂双机通信</h2>
<p> <p>
@ -737,9 +736,8 @@ TPOT P95 增加 66.55%。Phase 2 将围绕这两个现象采集硬件时间序
不伪装成当前已有能力;它们分别由后续硬件指标与 Profiling 阶段补齐。</p> 不伪装成当前已有能力;它们分别由后续硬件指标与 Profiling 阶段补齐。</p>
<h2>6. Phase 2同步采集轻量硬件指标</h2> <h2>6. Phase 2同步采集轻量硬件指标</h2>
<p> <p>
本阶段的设计、代码改动与结果同步维护在 本阶段尚在进行中,按照阶段档案生成门禁,暂不生成实验档案和代码详解 HTML。
<a href="./phase2_exp.html"> 当前代码与原始结果保留在仓库实验目录;本阶段重放长 Prefill、并发 Prefill、
Phase 2硬件与资源竞争归因实验档案</a>。本阶段重放长 Prefill、并发 Prefill、
普通 Decode、长输出 Decode、长上下文 Decode以及 普通 Decode、长输出 Decode、长上下文 Decode以及
<code>1K → 1K, C=32</code> 的混合 A/B。首轮 Run <code>1K → 1K, C=32</code> 的混合 A/B。首轮 Run
<code>dsv4pro-phase2-20260731-130125</code> 在 26 分 26 秒内完成 8/8 个结果; <code>dsv4pro-phase2-20260731-130125</code> 在 26 分 26 秒内完成 8/8 个结果;

View File

@ -212,9 +212,8 @@ C = 16, 32, 48, 64, ...
## 6. Phase 2同步采集硬件指标 ## 6. Phase 2同步采集硬件指标
详细实现与运行命令见 Phase 2 尚在进行中。按照阶段档案生成门禁,在最终正式复跑、结果汇总和汇报确认前,
[Phase 2 实验档案](./phase2_exp.html),实现说明见 不生成 `phase2_exp.html``phase2_code.html`
[Phase 2 代码详解](./phase2_code.html)。
首轮 8/8 benchmark 已完成最终采集代码、Worker 分发修复和双节点通信 首轮 8/8 benchmark 已完成最终采集代码、Worker 分发修复和双节点通信
smoke test 已通过,等待最终正式复跑。 smoke test 已通过,等待最终正式复跑。