168 lines
7.7 KiB
Markdown
168 lines
7.7 KiB
Markdown
# vllm-dspark Benchmark 结果评估
|
||
|
||
> 对应结果:`/data/user1/yy/bench_results/dspark_grid_20260707-132641`
|
||
> 运行时间:2026-07-07
|
||
> 硬件:8× NVIDIA H200 143GB
|
||
> 模型:`/data/models/DeepSeek-V4-Flash-DSpark`
|
||
> 服务配置:TP=8,FP8 KV cache,`--spec-method dspark --spec-tokens 5`,block-size=256,max-num-seqs=256
|
||
> 压测工具:`sglang.bench_serving --backend vllm`
|
||
|
||
---
|
||
|
||
## 1. 总体结论
|
||
|
||
本次 grid 测试覆盖了从轻量 chat 到超长上下文、从重 decode 到高并发压测的多种场景。整体上看:
|
||
|
||
- **DSpark 在短输入、中高并发场景下表现优秀**,`chat_short` 在并发 64 时达到约 9580 tok/s,`stress_standard` 在并发 128 时达到约 17465 tok/s。
|
||
- **低并发下 DSpark 的 draft 开销明显**,部分场景单并发延迟和吞吐都不如预期。
|
||
- **超长上下文场景存在明显的吞吐拐点**,`long_rag`(32K 输入)在并发 4 达到峰值后,并发 8 吞吐腰斩。
|
||
- **延迟长尾(P95/P99)普遍较重**,提示调度、内存或投机解码验证阶段存在抖动。
|
||
|
||
---
|
||
|
||
## 2. 异常点分析
|
||
|
||
### 2.1 低并发(c=1)下 DSpark 收益被开销吃掉
|
||
|
||
以 `chat_standard`(input=1000, output=256)为例:
|
||
|
||
| 并发 | req/s | mean E2E(ms) | P99 E2E(ms) | mean TTFT(ms) | P99 TTFT(ms) |
|
||
|---|---:|---:|---:|---:|---:|
|
||
| 1 | 0.49 | 2040.65 | 10715.53 | 1412.48 | 8430.71 |
|
||
| 8 | 4.35 | 1819.35 | 15165.63 | 327.62 | 4404.92 |
|
||
| 16 | 8.32 | 1885.15 | 10491.31 | 443.50 | 8567.07 |
|
||
| 32 | 10.00 | 3156.73 | 12936.08 | 560.77 | 7129.66 |
|
||
|
||
- **单并发吞吐仅 0.49 req/s**,远低于无投机基线可预期的水平。
|
||
- **P99 TTFT 高达 8.4s**,说明单请求首次预填充极不稳定,可能是 draft 验证/编译缓存未命中或 warmup 不充分导致。
|
||
- 并发提升到 8 后,TTFT 均值下降到 327ms,说明 DSpark 的 draft 计算需要 batch 才能摊薄。
|
||
|
||
**判断**:这是 DSpark 的典型特征——低并发下 draft 固定开销无法被摊薄,导致延迟尾和单请求吞吐都较差。
|
||
|
||
### 2.2 超长上下文出现吞吐断崖
|
||
|
||
`long_rag`(input=32000, output=512):
|
||
|
||
| 并发 | Total tok/s | mean TTFT(ms) | P99 TTFT(ms) |
|
||
|---|---:|---:|---:|
|
||
| 1 | 16104.98 | 549.72 | 1163.96 |
|
||
| 2 | 43215.62 | 192.57 | 409.32 |
|
||
| 4 | **70040.54** | 191.57 | 427.69 |
|
||
| 8 | 34141.70(↓51%) | 930.98 | 2742.48 |
|
||
|
||
`long_context_probe`(input=16000, output=512)也有类似模式:
|
||
|
||
| 并发 | Total tok/s | mean TTFT(ms) |
|
||
|---|---:|---:|
|
||
| 1 | 11051.09 | 316.59 |
|
||
| 2 | 26862.06 | 110.65 |
|
||
| 4 | 43042.77 | 127.38 |
|
||
| 8 | 29255.46(↓32%) | 453.93 |
|
||
| 16 | 43292.68 | 444.14 |
|
||
|
||
**判断**:
|
||
- 32K/16K 长 prefill 在并发 4 时达到最佳,继续加并发反而下降,可能与 **KV cache 显存带宽瓶颈**、**prefill 阶段 scheduling 阻塞** 或 **hybrid KV cache manager 的换入换出** 有关。
|
||
- `long_rag` 在 c=8 时 P99 TTFT 暴涨到 2.7s,进一步印证内存/调度压力。
|
||
|
||
### 2.3 延迟长尾普遍偏重
|
||
|
||
几乎所有场景的 P99 E2E 都是 mean E2E 的 2~4 倍:
|
||
|
||
| 场景 | 并发 | mean E2E | P99 E2E | 倍数 |
|
||
|---|---:|---:|---:|---:|
|
||
| chat_standard | 32 | 3156.73 | 12936.08 | 4.1× |
|
||
| generation_standard | 32 | 2908.89 | 6938.03 | 2.4× |
|
||
| summarization | 32 | 5587.21 | 14541.75 | 2.6× |
|
||
| decode_heavy | 32 | 5562.57 | 12822.35 | 2.3× |
|
||
| stress_standard | 128 | 4417.43 | 14850.43 | 3.4× |
|
||
|
||
**判断**:投机解码的 draft 验证失败会导致 fall back 到逐个 target 前向,造成明显的延迟毛刺;另外 vLLM v1 引擎的 scheduling 在高并发下也可能产生队列等待。
|
||
|
||
### 2.4 高并发下 TPOT/ITL 增长较快
|
||
|
||
`stress_standard`(input=1000, output=256):
|
||
|
||
| 并发 | mean TPOT | P95 TPOT | P99 TPOT | mean ITL |
|
||
|---|---:|---:|---:|---:|
|
||
| 96 | 29.46 | 67.30 | 123.42 | 113.64 |
|
||
| 128 | 35.20 | 76.85 | 141.17 | 136.57 |
|
||
|
||
TPOT 从 29ms 升到 35ms,P99 超过 140ms,说明 decode 阶段在极限并发下已经接近饱和。
|
||
|
||
---
|
||
|
||
## 3. 可重点优化的方向
|
||
|
||
### 3.1 按并发动态调整 `--spec-tokens`
|
||
|
||
参考历史对比数据(`dsv4_inference_comparison_report.md`):
|
||
|
||
| spec-tokens | 低并发(c=1) | 高并发(c=64) |
|
||
|---|---|---|
|
||
| 3 | 1.03 req/s, 254 tok/s | **14.53 req/s, 3507 tok/s** |
|
||
| 5 | **1.07 req/s, 257 tok/s** | 9.36 req/s, 2210 tok/s |
|
||
| 7 | 1.03 req/s, 251 tok/s | 9.13 req/s, 2218 tok/s |
|
||
|
||
当前部署固定使用 `--spec-tokens 5`:
|
||
- 对低并发(c=1~16)相对友好;
|
||
- 对高并发(c≥64)不是最优,st=3 在高并发下接受率更高、验证开销更小。
|
||
|
||
**建议**:
|
||
- 高并发服务场景:改用 `--spec-tokens 3`。
|
||
- 若负载混合,可考虑不同 endpoint/队列按并发分桶,或测试 st=3/st=5 在本 grid 下的完整表现。
|
||
|
||
### 3.2 长上下文场景优化
|
||
|
||
针对 `long_rag`(32K)和 `long_context_probe`(16K)的吞吐断崖:
|
||
|
||
1. **KV cache dtype 对比测试**:当前是 FP8,可测试 BF16 是否改善长上下文稳定性和吞吐。
|
||
2. **block-size 调整**:当前 256,可尝试 128 或 64 看是否减少内存碎片。
|
||
3. **hybrid KV cache manager**:当前 `--no-disable-hybrid-kv-cache-manager`,可对比关闭后的表现。
|
||
4. **限制长上下文并发**:若业务允许,对 32K 输入设置更低的 `max-num-seqs` 或独立队列,避免 c=8 后的内存带宽瓶颈。
|
||
5. **attention backend**:可测试 `FLASHINFER_MLA_SPARSE_DSV4`(脚本 `start_dsv4_dspark_8card_flashinfer.sh`)在长上下文下的表现。
|
||
|
||
### 3.3 降低延迟长尾
|
||
|
||
1. **增加 warmup**:当前仅 10 条 warmup。DSpark 的 JIT 编译/算子 warmup 在首次运行时较重,建议增加到 50~100 条或先跑一轮 discard。
|
||
2. **compilation cache 持久化**:确认 `TORCH_EXTENSIONS_DIR`、`VLLM_CACHE_ROOT` 等环境变量已设置并复用,避免每次重启重新编译 deep_gemm/tilelang。
|
||
3. **调度参数**:尝试调整 `--max-num-batched-tokens`、`--max-num-seqs`、chunked prefill 相关参数,减少队列等待。
|
||
4. **P99 TTFT 抖动**:高并发下 P99 TTFT 高通常与 prefill batching 有关,可尝试限制 prefill 阶段 batch 大小或启用 prompt chunked prefill。
|
||
|
||
### 3.4 低并发场景是否需要 DSpark
|
||
|
||
对于 `chat_standard` c=1:
|
||
- 当前 0.49 req/s、P99 E2E 10.7s 的服务质量较差。
|
||
- 若业务存在大量单用户/低并发请求,可考虑:
|
||
- 部署无投机基线 vLLM 专门服务低并发流量;
|
||
- 或设置最小 batch 阈值,累积少量请求后再用 DSpark 处理。
|
||
|
||
### 3.5 对比 baseline 与 SGLang
|
||
|
||
本次测试只有 DSpark 单一配置,建议补充:
|
||
1. **vLLM-dspark 无投机基线**:用同样的 `sglang.bench_serving --backend vllm` 测一遍相同 grid,计算真实加速比。
|
||
2. **SGLang EAGLE**:在相同 grid 下复测,验证 DSpark 在不同场景下的相对优势。
|
||
3. **不同 `--spec-tokens` 的完整 grid**:st=3 和 st=5 各跑一遍,绘制并发-吞吐曲线。
|
||
|
||
---
|
||
|
||
## 4. 推荐下一步实验
|
||
|
||
| 优先级 | 实验 | 预期收益 |
|
||
|---|---|---|
|
||
| P0 | 高并发改用 `--spec-tokens 3` | 提升 c≥64 场景吞吐 20~50% |
|
||
| P0 | 长上下文(16K/32K)对比 BF16 KV cache | 改善吞吐断崖和 P99 TTFT |
|
||
| P1 | 增加 warmup / 预热缓存 | 降低 P99 TTFT 和首请求延迟 |
|
||
| P1 | 测试 `FLASHINFER_MLA_SPARSE_DSV4` backend | 可能提升长上下文吞吐 |
|
||
| P2 | 跑无投机基线 grid | 获得真实加速比 |
|
||
| P2 | 对比 st=3/st=5 完整曲线 | 找到最佳投机长度配置 |
|
||
|
||
---
|
||
|
||
## 5. 结论
|
||
|
||
当前 DSpark 部署在 **短输入、中高并发** 场景下已经展现出明显优势,但在 **低并发** 和 **超长上下文** 场景下存在明显短板。最优先的优化是:
|
||
|
||
1. 高并发服务改用 `--spec-tokens 3`;
|
||
2. 针对 16K/32K 长上下文做 KV cache dtype 和 attention backend 的调优;
|
||
3. 补充 baseline 测试,量化 DSpark 的真实收益。
|