feat: add P800 vs H20 diagnosis plan for performance gap analysis
This commit is contained in:
parent
a7e2037471
commit
0afd552ad3
236
experiments/p800/P800_vs_H20_DIAGNOSIS_PLAN.md
Normal file
236
experiments/p800/P800_vs_H20_DIAGNOSIS_PLAN.md
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
# P800 vs H20 性能差距根因诊断方案
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
**已知差距**: DeepSeek-V4-Flash-INT8 模型在 TP8/DP1, ISL=4k, OSL=1k, C=16 下,P800 比 H20 慢 **~3x**(TPS: 1,634 vs 4,866)。
|
||||||
|
|
||||||
|
且 C=1 无竞争时 TPOT 差距仍有 2.9x(26.5ms vs 9.1ms),说明**瓶颈不在调度层,而在单次推理的硬件/算子层**。
|
||||||
|
|
||||||
|
**核心问题**: P800 纸面参数不弱(96GB/卡, 400W, 1450MHz, KL3 架构),但实际推理慢 3 倍。需要系统拆解这 3x 差距来自哪里。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 分析框架
|
||||||
|
|
||||||
|
一次 Decode 推理的总时间 ≈ 三层叠加:
|
||||||
|
|
||||||
|
| 层次 | 决定因素 | 测量方法 |
|
||||||
|
|:----|:---------|:---------|
|
||||||
|
| **计算层** | HBM 带宽、矩阵算力 (TFLOPS) | 内存带宽微基准测试、单算子基准 |
|
||||||
|
| **通信层** | XPULINK 带宽、All-reduce 效率 | BKCL 带宽测试、TP 扩展性实验 |
|
||||||
|
| **引擎层** | SGLang 框架开销、Kernel 调度效率 | 空跑开销分析、框架对比实验 |
|
||||||
|
|
||||||
|
差距 3x = 带宽差距 × 通信开销差距 × 算子效率差距
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 实验方案
|
||||||
|
|
||||||
|
### 实验 0: 内存带宽实测(验证硬件理论值)
|
||||||
|
|
||||||
|
这是最关键的第一步。P800 的 HBM 带宽没有公开文档,需要实际测出来。
|
||||||
|
|
||||||
|
**方法1: 用容器内的 PyTorch 测试**
|
||||||
|
```bash
|
||||||
|
# 在 SGLang 容器内运行
|
||||||
|
python -c "
|
||||||
|
import torch
|
||||||
|
import time
|
||||||
|
x = torch.randn(1024, 4096, dtype=torch.float16).cuda()
|
||||||
|
y = torch.randn(4096, 4096, dtype=torch.float16).cuda()
|
||||||
|
# warmup
|
||||||
|
for _ in range(100): z = x @ y
|
||||||
|
torch.cuda.synchronize()
|
||||||
|
# measure
|
||||||
|
t0 = time.time()
|
||||||
|
for _ in range(1000): z = x @ y
|
||||||
|
torch.cuda.synchronize()
|
||||||
|
t1 = time.time()
|
||||||
|
# 计算带宽
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
**方法2: 用现有 benchmark 工具**
|
||||||
|
- 检查 `/root/tools/` 下是否有带宽测试工具
|
||||||
|
- 检查容器内是否有 `stream` 或 `bandwidthTest` 类似工具
|
||||||
|
|
||||||
|
**关键结论**:
|
||||||
|
- 实测带宽 vs H20 4.0 TB/s
|
||||||
|
- 如果 P800 带宽只有 ~1.3 TB/s,说明 3x 差距基本来自内存带宽
|
||||||
|
- 如果带宽差距 < 2x,说明还有别的因素
|
||||||
|
|
||||||
|
### 实验 1: All-reduce 通信带宽基准
|
||||||
|
|
||||||
|
TP=8 要求每步做 All-reduce,通信开销占比很大。需要实测 XPULINK 带宽。
|
||||||
|
|
||||||
|
**方法1: BKCL bandwidth test**
|
||||||
|
```bash
|
||||||
|
# 在 8 卡容器内
|
||||||
|
# 检查 /root/miniconda/envs/python310_torch25_cuda/bin 下是否有 bkcl 相关工具
|
||||||
|
```
|
||||||
|
|
||||||
|
**方法2: 通过 TP 扩展性反推**
|
||||||
|
```bash
|
||||||
|
# 分别跑 TP=1, TP=2, TP=4, TP=8
|
||||||
|
# 如果 TP=1→TP=2 的加速比接近 2x → 通信开销很小
|
||||||
|
# 如果加速比远低于线性 → 通信是瓶颈
|
||||||
|
```
|
||||||
|
|
||||||
|
**关键结论**:
|
||||||
|
- XPULINK 实测带宽 vs NVLink 900GB/s
|
||||||
|
- 如果 P800 卡间带宽远低于 NVLink,TP=8 的通信开销会占很大比例
|
||||||
|
|
||||||
|
### 实验 2: TP 扩展性曲线(直接在 P800 上测)
|
||||||
|
|
||||||
|
在 P800 上跑 **TP=1, TP=2, TP=4, TP=8** 的 benchmark,固定总 batch size。
|
||||||
|
|
||||||
|
**为什么重要**:
|
||||||
|
- 如果 TP=1→TP=2 加速比接近 2x:通信效率高,差距在单卡能力
|
||||||
|
- 如果 TP=1→TP=2 加速比仅 1.2x:通信/同步开销极大
|
||||||
|
- C=1 时 TP=1 的 TPOT 是纯单卡 decode 延迟(无通信干扰)
|
||||||
|
|
||||||
|
**执行方式**:
|
||||||
|
- 使用已有的 `dsv4_p800_sglang_tp_dp_matrix` 实验框架
|
||||||
|
- 修改 `start_sglang_docker.sh` 的 TP 参数
|
||||||
|
- C=1, ISL=4k, OSL=1k
|
||||||
|
|
||||||
|
### 实验 3: Decode 耗时分解(手动分段计时)
|
||||||
|
|
||||||
|
绕过 PyTorch Profiler 的崩溃问题,用**手动插桩计时**替代。
|
||||||
|
|
||||||
|
**在 SGLang 源码中的关键埋点**(通过 patch 文件实现,而非直接改容器内代码):
|
||||||
|
|
||||||
|
```
|
||||||
|
schedule():
|
||||||
|
├── wait_for_available_slots [调度等待]
|
||||||
|
├── prepare_inputs [输入准备]
|
||||||
|
├── forward():
|
||||||
|
│ ├── attention (NSA) [注意力计算]
|
||||||
|
│ ├── MoE gating [路由]
|
||||||
|
│ ├── MoE expert forward [专家计算 + all-reduce]
|
||||||
|
│ ├── attention (decode) [解码注意力]
|
||||||
|
│ └── lm_head [输出头]
|
||||||
|
├── all-reduce sync [同步]
|
||||||
|
└── stream output [输出]
|
||||||
|
```
|
||||||
|
|
||||||
|
**方法**:
|
||||||
|
- 在 `/data1/yy/sskj/platforms/patches/kunlun_p800/` 中创建 `manual_timing_patch.py`
|
||||||
|
- 在每个阶段前后用 `torch.cuda.Event` 记录时间
|
||||||
|
- 输出每个阶段的时间占比
|
||||||
|
|
||||||
|
**参考理论预期**:
|
||||||
|
- 理想 Decode 中约 70-80% 时间在矩阵乘法(memory-bound)
|
||||||
|
- 约 10-20% 时间在通信(all-reduce)
|
||||||
|
- 约 5-10% 在其余操作
|
||||||
|
|
||||||
|
### 实验 4: Isolate 通信开销 - C=1 vs C=16 下不同 TP/DP 组合
|
||||||
|
|
||||||
|
| TP | DP | 每卡负载 | 通信量 | 预期效果 |
|
||||||
|
|:--:|:--:|:--------|:-------|:--------|
|
||||||
|
| 8 | 1 | 1/8 参数 | all-reduce 8卡 | 当前配置 |
|
||||||
|
| 4 | 2 | 1/4 参数 | all-reduce 4卡 | 通信减半 |
|
||||||
|
| 2 | 4 | 1/2 参数 | all-reduce 2卡 | 通信最少 |
|
||||||
|
| 1 | 8 | 全部参数 | 无 all-reduce | 无通信开销 |
|
||||||
|
|
||||||
|
**分析**:
|
||||||
|
- 如果 TP=4/DP=2 比 TP=8/DP=1 快 → 通信开销过大
|
||||||
|
- 如果 TP=1/DP=8 的 TPS > TP=8/DP=1 × 8 → 说明通信是主要瓶颈
|
||||||
|
- 如果 TP 扩展性接近线性 → 通信不是瓶颈
|
||||||
|
|
||||||
|
### 实验 5: 对比分析 P800 vs H20 的算子实现差异
|
||||||
|
|
||||||
|
P800 使用 NSA attention + XPU 定制 kernel,H20 使用同一个 SGLang 框架的 CUDA 版本。
|
||||||
|
|
||||||
|
**需要检查的算子**:
|
||||||
|
|
||||||
|
| 算子 | P800 实现 | H20 实现 | 可能的差距 |
|
||||||
|
|:----|:---------|:---------|:----------|
|
||||||
|
| NSA Attention (klxdsa) | XPU custom kernel | CUDA custom kernel | 优化程度差异 |
|
||||||
|
| MoE (experts) | XPU GEMM | CUDA GEMM (cuBLAS) | cuBLAS vs XPU BLAS |
|
||||||
|
| FP8/INT8 Quant | XPU custom | CUDA (CUTLASS) | 量化kernel效率 |
|
||||||
|
| All-reduce | BKCL (XPU) | NCCL (NVIDIA) | 通信库效率 |
|
||||||
|
|
||||||
|
**方法**:
|
||||||
|
- 在容器内找到 `sglang/srt/layers/` 下的自定义算子实现
|
||||||
|
- 对比 XPU 和 CUDA 的算子实现差异
|
||||||
|
- 关注是否有明显未优化的 kernel(如用纯 PyTorch 而非融合 kernel)
|
||||||
|
|
||||||
|
### 实验 6: 算子级微基准测试
|
||||||
|
|
||||||
|
编写独立的 micro-benchmark,测试关键操作的单次耗时:
|
||||||
|
|
||||||
|
```python
|
||||||
|
for op in ['matmul', 'attention', 'rms_norm', 'all_reduce', 'silu_mul']:
|
||||||
|
for size in [1024, 2048, 4096, 8192]:
|
||||||
|
time_op(op, size, dtype=torch.float16)
|
||||||
|
```
|
||||||
|
|
||||||
|
**核心关注**:
|
||||||
|
- `matmul(M=1, N=4096, K=4096)` — Decode 的典型矩阵形状(batch=1)
|
||||||
|
- `all_reduce(8*4096)` — 单层通信量
|
||||||
|
- `attention(Q=1, KV=model_dim)` — decode attention
|
||||||
|
|
||||||
|
### 实验 7: SGLang 框架开销纯测
|
||||||
|
|
||||||
|
启动一个小模型(如 Llama-1B),在同样 TP 配置下跑同样的 benchmark。
|
||||||
|
|
||||||
|
**方法**:
|
||||||
|
- 在容器内用一个小模型跑同样的 bench_serving
|
||||||
|
- 对比 P800 和 H20 的框架调度延迟(如果能拿到 H20 数据)
|
||||||
|
- 如果小模型差距也 ~3x → 框架差异
|
||||||
|
- 如果小模型差距 < 1.5x → 差距在算子/带宽
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 实验优先级和执行顺序
|
||||||
|
|
||||||
|
| 优先级 | 实验 | 耗时 | 最大信息价值 |
|
||||||
|
|:-----|:----|:----|:-----------|
|
||||||
|
| **P0** | 实验 0: 内存带宽实测 | 30min | 验证是否 3x 差距全来自 HBM 带宽 |
|
||||||
|
| **P0** | 实验 2: TP 扩展性 (TP=1,2,4,8) | 2h | 判断通信 vs 计算瓶颈 |
|
||||||
|
| **P1** | 实验 3: 手动分段计时 | 4h | 定位哪段算子最慢 |
|
||||||
|
| **P1** | 实验 4: 不同 TP/DP 组合对比 | 4h | 找到最优配置 |
|
||||||
|
| **P2** | 实验 5: 算子实现对比 | 2h | 确认是否有低效 kernel |
|
||||||
|
| **P2** | 实验 6: 算子微基准 | 3h | 精确量化每个算子的差距 |
|
||||||
|
| **P3** | 实验 7: 框架开销纯测 | 1h | 排除/确认框架影响 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数据归因分析
|
||||||
|
|
||||||
|
当所有实验完成后,3x 总差距可以归因到:
|
||||||
|
|
||||||
|
```
|
||||||
|
3.0x = A × B × C × D × E
|
||||||
|
|
||||||
|
A = 内存带宽差距(HBM BW_P800 vs BW_H20)
|
||||||
|
B = 通信开销差距(XPULINK vs NVLink + BKCL vs NCCL)
|
||||||
|
C = 算子效率差距(XPU kernel vs CUDA kernel)
|
||||||
|
D = 量化效率差距(INT8 实现差异)
|
||||||
|
E = 框架调度差距(SGLang XPU vs CUDA 版本)
|
||||||
|
```
|
||||||
|
|
||||||
|
**预期判断**:
|
||||||
|
- 如果 A > 2.5x:根因是 P800 HBM 带宽不足(硬件天花板),优化空间有限
|
||||||
|
- 如果 A < 1.5x 但 B + C > 2x:根因在通信/算子,有机会通过优化 kernel 缩小差距
|
||||||
|
- 如果 C=1 和 C=16 差距一致:引擎调度不是问题
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 现有脚本复用
|
||||||
|
|
||||||
|
- **容器启动**: 复用 `dsv4_p800_sglang_tp_dp_matrix/start_sglang_docker.sh`(支持 TP/DP 参数)
|
||||||
|
- **Benchmark**: 复用 `run_bench.sh` 和已 patched 的 `bench_serving.py`
|
||||||
|
- **Patch 机制**: 通过 `/data1/yy/sskj/platforms/patches/kunlun_p800/` 挂载
|
||||||
|
- **结果解析**: 复用 `scripts/common/compare.py` 和 `parse_backend.py`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 验证方式
|
||||||
|
|
||||||
|
每个实验的输出是**数值数据**(带宽 GB/s、延迟 ms、加速比):
|
||||||
|
1. 带宽测试跑 3 次取平均值,确认波动 < 5%
|
||||||
|
2. TP 扩展性实验检查 log 确认无异常(OOM、超时)
|
||||||
|
3. 手动分段计时的各阶段时间占比合理(总和 ≈ TPOT)
|
||||||
|
4. 与已知硬件理论值对比(H20 4.0 TB/s 作为标杆)
|
||||||
Loading…
x
Reference in New Issue
Block a user