813 lines
43 KiB
HTML
813 lines
43 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Phase 2:DeepSeek-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 & Result Record</p>
|
||
<h1>Phase 2:DeepSeek-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 17:22:20 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-163620</code> 在 28 分 44 秒内完成
|
||
8/8 个 benchmark,正式测量窗口 8/8 精确,18/18 个采集器正常启停。
|
||
Head/Worker 的 DCGM、CPU、NUMA、双 Rail RDMA 和通信微基准证据均有效;
|
||
实验结束后两节点容器、服务端口和 16 张 GPU 已清理。
|
||
</p>
|
||
|
||
<h2>1. Phase 1 交接结果</h2>
|
||
<table>
|
||
<thead>
|
||
<tr><th>代表负载</th><th>关键结果</th><th>Phase 2 用途</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td>128K → 1,C=1</td><td>Input TPS 2,710.16;TTFT P95 48.344 s</td><td>纯长 Prefill 的计算、显存与通信归因</td></tr>
|
||
<tr><td>32K → 1,C=16</td><td>Input TPS 3,112.77;TTFT P95 162.087 s</td><td>并发 Prefill 的排队、Chunk 调度与节点均衡</td></tr>
|
||
<tr><td>1K → 1K,C=32</td><td>Output TPS 461.68;TPOT P95 63.31 ms</td><td>普通 Decode 的 GPU、CPU 与通信基线</td></tr>
|
||
<tr><td>1K → 4K,C=16</td><td>Output TPS 310.02;TPOT P95 50.33 ms</td><td>持续 Decode、KV 增长和稳态资源占用</td></tr>
|
||
<tr><td>128K → 1K,C=1</td><td>TTFT P95 49.326 s;TPOT P95 32.24 ms</td><td>分离长 Prefill 与长上下文 Decode 成本</td></tr>
|
||
<tr><td>1K → 1K,C=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>&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/<RUN_ID>/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/<RUN_ID>/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 Counter:DCGM</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 <container> -eo pid,ppid,psr,pcpu,pmem,stat,comm,args
|
||
|
||
# 最终命令:进程级 CPU、I/O、缺页、上下文切换,不展开全部线程
|
||
pidstat -durw -p "<comma-separated-host-pids>" 5
|
||
|
||
# 每 5 秒输出一次硬件/软件计数器增量
|
||
perf stat -p "<comma-separated-host-pids>" -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 <host-pid>
|
||
# 解析为:
|
||
# 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 <0-or-1> \
|
||
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 <container>
|
||
docker top <container> -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/<RUN_ID>/
|
||
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">最终 Run <code>dsv4pro-phase2-20260731-163620</code> 状态为 <code>COMPLETED</code>,8/8 benchmark 成功,0 失败、0 OOM。</li>
|
||
<li class="pass">8/8 Case 使用正式 benchmark 精确时间窗;18 个采集器全部记录 <code>STARTED</code> 与 <code>STOPPED</code>。</li>
|
||
<li class="pass">Head 与 Worker 的 DCGM、GPU、CPU、进程、NUMA、网卡和 HCA Counter 均有有效样本。</li>
|
||
<li class="pass">P2P、8-rank 和 16-rank AllReduce 全部完成,所有正确性检查均为 <code>wrong_values=0</code>。</li>
|
||
<li class="pass">Run 结束后 Head/Worker 无相关容器、无 GPU 计算进程,端口 <code>30002/30003</code> 已释放。</li>
|
||
</ul>
|
||
|
||
<h2>9. 正式运行</h2>
|
||
<p class="decision">
|
||
<strong>Run:<code>dsv4pro-phase2-20260731-163620</code>。</strong>
|
||
运行时间为 16:36:20 至 17:05:04 CST,总用时 28 分 44 秒。
|
||
Manifest 记录代码提交 <code>5f24b7d22f98108f6cc234edba6768d55ea0a962</code>,
|
||
<code>git_dirty=false</code>。
|
||
</p>
|
||
<pre><code class="language-bash"># 仅在 Head 174.1.51.5 执行
|
||
cd /data/hzy/sskj/experiments/pro6000/dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution
|
||
|
||
RUN_ID=dsv4pro-phase2-20260731-163620
|
||
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"</code></pre>
|
||
|
||
<h2>10. 端到端结果</h2>
|
||
<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,641.38</td><td>0.02</td><td>49.610 s</td><td>—</td></tr>
|
||
<tr><td>32K → 1, C=16</td><td>3,115.45</td><td>0.10</td><td>161.938 s</td><td>—</td></tr>
|
||
<tr><td>1K → 1K, C=32</td><td>448.95</td><td>448.95</td><td>10.167 s</td><td>65.36 ms</td></tr>
|
||
<tr><td>1K → 4K, C=16</td><td>79.39</td><td>317.56</td><td>1.724 s</td><td>49.98 ms</td></tr>
|
||
<tr><td>128K → 1K, C=1</td><td>1,614.99</td><td>12.62</td><td>48.279 s</td><td>32.11 ms</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h3>10.2 混合 Prefill/Decode A/B</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>453.55</td><td>344.89</td><td>-23.96%</td></tr>
|
||
<tr><td>TTFT P95</td><td>9.443 s</td><td>9.892 s</td><td>+4.76%</td></tr>
|
||
<tr><td>TPOT P95</td><td>66.24 ms</td><td>110.45 ms</td><td>+66.75%</td></tr>
|
||
<tr><td>E2E P95</td><td>72.270 s</td><td>118.076 s</td><td>+63.38%</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
这是 Phase 2 最关键的现象:长 Prefill 与 Decode 共存时,首 token 延迟只增加
|
||
4.76%,但 Decode 单 token 成本增加 66.75%,最终令 Output TPS 下降 23.96%。
|
||
问题主要发生在持续 Decode 阶段,而不是只表现为 Prefill 请求排队。
|
||
</p>
|
||
|
||
<h2>11. 第 5 节指标逐项结果</h2>
|
||
<h3>11.1 GPU 基础状态与 DCGM</h3>
|
||
<p><strong>服务器证据路径:</strong><br>
|
||
汇总:<code>/data/hzy/sskj/experiments/pro6000/dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution/results/dsv4pro-phase2-20260731-163620/case_gpu_summary.csv</code>、
|
||
<code>case_gpu_node_summary.csv</code>、<code>case_dcgm_summary.csv</code><br>
|
||
原始:同一 Run 目录下的 <code>head/gpu_samples.csv</code>、<code>worker/gpu_samples.csv</code>、
|
||
<code>head/dcgm_dmon.log</code>、<code>worker/dcgm_dmon.log</code>
|
||
</p>
|
||
<ul>
|
||
<li>各 Case GPU Util Mean 大多为 94%–99%,P95 为 100%;SM Clock 约 2.39–2.42 GHz,未见降频。</li>
|
||
<li>每卡显存稳定在约 83,000–83,364 MiB。Decode 功耗约 216–258 W,Prefill 功耗约 293–307 W。</li>
|
||
<li>普通 Decode 的 SM Active 约 0.523–0.525、DRAM Active 约 0.415–0.417;128K Prefill 的 SM Active 升至 0.683–0.686。</li>
|
||
<li>32K C16 Prefill 的 SM Active 约 0.713–0.715、DRAM Active 约 0.440,是本轮最重的并发 Prefill 计算负载。</li>
|
||
<li>混合 Treatment 中,Decode 背景 SM Active 约 0.578–0.581;注入 Prefill 窗口升至 0.720–0.723,证明两类工作确实争用同一 GPU 执行资源。</li>
|
||
</ul>
|
||
|
||
<h3>11.2 CPU、进程与 NUMA</h3>
|
||
<p><strong>服务器证据路径:</strong><br>
|
||
汇总:<code>/data/hzy/sskj/experiments/pro6000/dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution/results/dsv4pro-phase2-20260731-163620/case_cpu_summary.csv</code>、
|
||
<code>case_process_summary.csv</code>、<code>case_perf_summary.csv</code>、<code>case_numa_summary.csv</code><br>
|
||
原始:同一 Run 目录下 Head/Worker 各自的 <code>mpstat.log</code>、<code>pidstat.log</code>、
|
||
<code>perf_stat.log</code>、<code>numa_samples.csv</code> 和 <code>docker_top.log</code>
|
||
</p>
|
||
<ul>
|
||
<li>整机 CPU Active Mean 约 9.6%–10.4%,P95 约 10%–11.4%;没有全机 CPU 饱和。</li>
|
||
<li>服务进程峰值约 1,210%–1,226%,相当于约 12 个 CPU Core;热点 Core 数量最多 12–13 个。</li>
|
||
<li><code>perf</code> 观察到 IPC 约 2.7–3.1,未出现明显 Host 侧停摆。</li>
|
||
<li>Head/Worker 的 NUMA 不均衡约 21.1% / 13.2%,跨 Case 基本稳定;它是拓扑基线,但不像混合性能退化的直接诱因。</li>
|
||
</ul>
|
||
|
||
<h3>11.3 双 Rail RDMA</h3>
|
||
<p><strong>服务器证据路径:</strong><br>
|
||
汇总:<code>/data/hzy/sskj/experiments/pro6000/dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution/results/dsv4pro-phase2-20260731-163620/case_rdma_summary.csv</code>、
|
||
<code>rdma_summary.csv</code>、<code>case_netdev_summary.csv</code><br>
|
||
原始:同一 Run 目录下的 <code>head/rdma.csv</code>、<code>worker/rdma.csv</code>、
|
||
<code>head/sar_net.log</code>、<code>worker/sar_net.log</code>;端口/HCA 静态状态在两端
|
||
<code>static_before.log</code> 与 <code>static_after.log</code>
|
||
</p>
|
||
<ul>
|
||
<li>RoCE 绕过普通 Linux Socket 数据路径,因此 <code>sar</code> 的 <code>eth0/eth3</code> 流量接近 0;实际流量必须看 <code>mlx5_0/mlx5_3</code> HCA Counter。</li>
|
||
<li>普通 Decode 每 Rail 约 36.7–36.8 Gbit/s;128K Prefill 每 Rail约 70.5–71.5 Gbit/s。</li>
|
||
<li>最高点 32K C16 Prefill 每 Rail 约 83.0–83.45 Gbit/s,仅约占单条 400G Rail 的 20.9%。</li>
|
||
<li>两条 Rail 流量对称,<code>port_xmit_wait</code>、丢弃、错误和 Retry Exceeded 增量均为 0。</li>
|
||
</ul>
|
||
|
||
<h3>11.4 PCIe 与 NCCL 通信基线</h3>
|
||
<p><strong>服务器证据路径:</strong><br>
|
||
汇总:<code>/data/hzy/sskj/experiments/pro6000/dsv4pro_pro6000d_2node_sglang_hardware_contention_attribution/results/dsv4pro-phase2-20260731-163620/communication_aggregate.csv</code>、
|
||
<code>communication_summary.csv</code><br>
|
||
原始:同一 Run 目录的 <code>communication/p2p_head.log</code>、<code>p2p_worker.log</code>、
|
||
<code>allreduce_head_8gpu.log</code>、<code>allreduce_worker_8gpu.log</code> 和
|
||
<code>allreduce_16gpu_crossnic{0,1,2}_{head,worker}.log</code>;实际执行命令在 <code>commands/communication_*.cmd.txt</code>
|
||
</p>
|
||
<table>
|
||
<thead><tr><th>测试</th><th>结果</th><th>解释</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>Head PCIe P2P 256 MiB</td><td>同 Switch 53.61 GB/s;跨 NUMA 52.40 GB/s</td><td>跨 NUMA 损失约 2.3%</td></tr>
|
||
<tr><td>Worker PCIe P2P 256 MiB</td><td>同 Switch 53.50 GB/s;跨 NUMA 52.32 GB/s</td><td>两节点表现对称</td></tr>
|
||
<tr><td>Head / Worker 8-GPU AllReduce 1 GiB</td><td>busbw 39.76 / 39.75 GB/s</td><td>节点内基线一致</td></tr>
|
||
<tr><td>16-GPU AllReduce,CROSS_NIC=0</td><td>busbw 39.345 GB/s;51.169 ms</td><td>正确性 0 错误</td></tr>
|
||
<tr><td>16-GPU AllReduce,CROSS_NIC=1</td><td>busbw 39.685 GB/s;50.732 ms</td><td>本轮数值最好</td></tr>
|
||
<tr><td>16-GPU AllReduce,CROSS_NIC=2</td><td>busbw 39.530 GB/s;50.931 ms</td><td>正确性 0 错误</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
<code>NCCL_CROSS_NIC=1</code> 比 0 仅高 0.86%,比 2 仅高 0.39%。
|
||
差异小于 1%,不足以把它当成主要调优旋钮;保留当前值即可,Phase 3 不再重复测试。
|
||
NCCL 日志明确证明跨机路径使用 <code>mlx5_0,mlx5_3</code> 和
|
||
<code>NET/IB/.../GDRDMA</code>。
|
||
</p>
|
||
|
||
<h2>12. 结论与 Phase 3 入口</h2>
|
||
<p class="decision">
|
||
<strong>Phase 2 已把范围明显缩小:</strong>混合 Prefill/Decode 退化真实且稳定,
|
||
但不是由整机 CPU 饱和、GPU 降频、双 Rail 原始带宽饱和、Rail 失衡、
|
||
PCIe 跨 NUMA 带宽崩塌或 <code>NCCL_CROSS_NIC</code> 选择造成。
|
||
Phase 3 应只捕获 Control 与 Treatment 的短时间线,定位 Attention/Indexer、
|
||
MoE、NCCL Collective、Scheduler gap 和慢 Rank 同步之间的串行与重叠关系。
|
||
</p>
|
||
<ul>
|
||
<li>不重复 Phase 2 的长时间 DCGM、CPU、RDMA 和通信微基准。</li>
|
||
<li>优先对比混合 Control 与注入 128K Prefill 的 Treatment。</li>
|
||
<li>再用单独 128K Prefill 作为 Kernel 对照,解释 SM Active 与 Tensor Active 的来源。</li>
|
||
</ul>
|
||
|
||
<h2>13. 证据与清理说明</h2>
|
||
<ul>
|
||
<li><a href="./results/dsv4pro-phase2-20260731-163620/report.md">自动生成逐指标报告</a></li>
|
||
<li><a href="./results/dsv4pro-phase2-20260731-163620/analysis.md">阶段归因摘要</a></li>
|
||
<li><a href="./results/dsv4pro-phase2-20260731-163620/bench_summary.csv">端到端 benchmark 汇总</a></li>
|
||
<li><a href="./results/dsv4pro-phase2-20260731-163620/communication_aggregate.csv">通信微基准汇总</a></li>
|
||
<li><a href="./results/dsv4pro-phase2-20260731-163620/service/head_server_cmd.txt">Head 实际服务命令</a> /
|
||
<a href="./results/dsv4pro-phase2-20260731-163620/service/worker_server_cmd.txt">Worker 实际服务命令</a></li>
|
||
</ul>
|
||
<p>
|
||
Worker 日志在所有 benchmark 完成后的编排关闭阶段出现 Gloo
|
||
<code>Connection closed by peer</code>;时间与 Head 主动退出进程组一致,
|
||
未影响 8/8 结果。NCCL 日志中的可选 mlx5 symbol 探测提示同样未影响
|
||
Collective,全部正确性检查为 0 错误。
|
||
</p>
|
||
|
||
<p><a class="back" href="./phase1_exp.html">返回 Phase 1 实验档案</a></p>
|
||
<p><a class="back" href="./phase2_5_exp.html">继续 Phase 2.5 RDMA 需求建模</a></p>
|
||
<p><a class="back" href="./推理优化计划.html">返回推理优化主计划</a></p>
|
||
</main>
|
||
</body>
|
||
</html>
|