352 lines
15 KiB
Markdown
352 lines
15 KiB
Markdown
# DeepSeek-V4 推理性能评估报告
|
||
|
||
## vLLM DSpark vs 其他投机解码方法 vs SGLang
|
||
|
||
> 测试环境:8× NVIDIA H200 (143GB),CUDA 12.x,驱动 575.57.08
|
||
> 测试时间:2026-07-05
|
||
> 测试模型:`DeepSeek-V4-Flash` / `DeepSeek-V4-Flash-DSpark`
|
||
> 测试框架:vLLM 0.24.0、vLLM-dspark 0.23.1rc1.dev788、SGLang 0.5.14
|
||
|
||
---
|
||
|
||
## 1. 背景与目标
|
||
|
||
### 1.1 投机解码(Speculative Decoding)基本原理
|
||
|
||
大模型自回归生成的瓶颈在于:每生成一个 token 都要做一次完整的模型前向传播。投机解码的核心思想是:
|
||
|
||
1. 用一个轻量的 **draft model**(或 draft head)一次性生成多个候选 token;
|
||
2. 用原始 **target model** 并行验证这些候选 token;
|
||
3. 接受与 target 模型一致的 token,从第一个不一致处重新生成。
|
||
|
||
理想情况下,如果 draft model 质量高,可以一次接受多个 token,从而把有效生成步长从 1 提升到 1+α(α 为平均接受长度),显著降低 latency、提升 throughput。
|
||
|
||
### 1.2 常见投机解码方法对比
|
||
|
||
| 方法 | 代表实现 | 优点 | 缺点 |
|
||
|---|---|---|---|
|
||
| **EAGLE / EAGLE-2** | vLLM EAGLE、SGLang EAGLE | 接受率高(40-70%),draft 模型小 | 需要单独训练 draft 模型,内存占用额外 |
|
||
| **MTP (Multi-Token Prediction)** | DeepSeek MTP | 与目标模型结构一致,可共享权重 | 通常只有 1-2 个 MTP head,加速比有限 |
|
||
| **DSpark** | vLLM-dspark | 半自回归 draft,并行生成整段,接受长度高 | draft 计算量较大,对 batching/scheduling 要求高 |
|
||
| **n-gram / prompt-lookup** | vLLM ngram | 无需额外模型 | 只适用于重复性文本,泛化差 |
|
||
| **Medusa** | Medusa | 多个解码头 | 需要训练,内存占用大 |
|
||
|
||
### 1.3 DSpark 的特点
|
||
|
||
DSpark 是 DeepSeek 提出的块级半自回归投机解码方案,关键设计:
|
||
|
||
- **块级 draft**:一次并行生成一个 block(多个 token),而不是逐 token;
|
||
- **非因果注意力**:draft block 内部允许未来 token 参与当前 token 计算;
|
||
- **Markov head**:在 block 内引入轻量序列依赖;
|
||
- **目标模型复用**:DSpark draft 权重与目标模型共存(`mtp.{i}.*`),可共享 embedding/head。
|
||
|
||
相比 EAGLE,DSpark 的 draft 更接近目标模型结构,因此接受率通常更高,但 draft 前向本身的计算量也更大。DSpark 的优势在 **高并发、长输出** 场景下更明显;在低并发或短输出场景,draft 开销可能抵消收益。
|
||
|
||
### 1.4 评估目标
|
||
|
||
本报告系统评估:
|
||
|
||
1. **vLLM + DSpark** 在 DeepSeek-V4-Flash 上的推理优势;
|
||
2. 与 **vLLM 无投机解码** 基线的对比;
|
||
3. 与 **SGLang + EAGLE** 的对比;
|
||
4. 不同参数(`--spec-tokens`、并发度、输出长度)下的最优配置;
|
||
5. vLLM 与 SGLang 两个引擎部署 DSV4 的差异。
|
||
|
||
---
|
||
|
||
## 2. 测试环境
|
||
|
||
### 2.1 硬件
|
||
|
||
| 项目 | 配置 |
|
||
|---|---|
|
||
| GPU | 8× NVIDIA H200 143GB |
|
||
| 互联 | NVLink + NVSwitch |
|
||
| 驱动 | 575.57.08 |
|
||
| CUDA | 12.x |
|
||
|
||
### 2.2 软件版本
|
||
|
||
| 引擎 | 版本 | 路径 |
|
||
|---|---|---|
|
||
| SGLang | 0.5.14 | `/data/user1/yy/envs/sglang` |
|
||
| vLLM | 0.24.0 | `/data/user1/yy/envs/vllm` |
|
||
| vLLM-dspark | 0.23.1rc1.dev788+gfa4321de3 | `/data/user1/yy/envs/vllm-dspark` |
|
||
|
||
### 2.3 模型
|
||
|
||
| 模型 | 路径 | 说明 |
|
||
|---|---|---|
|
||
| DeepSeek-V4-Flash | `/data/models/DeepSeek-V4-Flash` | 标准目标模型 |
|
||
| DeepSeek-V4-Flash-DSpark | `/data/models/DeepSeek-V4-Flash-DSpark` | 内含 DSpark draft 权重 |
|
||
|
||
### 2.4 数据集
|
||
|
||
- ShareGPT V4.3 unfiltered cleaned split:`/data/user1/yy/datasets/ShareGPT_V4.3_unfiltered_cleaned_split.json`
|
||
|
||
### 2.5 测试参数
|
||
|
||
- Tensor Parallel:8
|
||
- KV cache dtype:fp8
|
||
- Block size:256
|
||
- Max model len:auto
|
||
- Max num seqs:256
|
||
- 输出长度:256(固定)
|
||
- Prompt 数量:200
|
||
- 并发度:1, 16, 64
|
||
|
||
---
|
||
|
||
## 3. 测试方法
|
||
|
||
### 3.1 服务启动
|
||
|
||
各引擎服务启动命令如下:
|
||
|
||
**vLLM-dspark + DSpark**
|
||
```bash
|
||
vllm serve /data/models/DeepSeek-V4-Flash-DSpark \
|
||
--trust-remote-code --tensor-parallel-size 8 \
|
||
--kv-cache-dtype fp8 --block-size 256 --max-model-len auto \
|
||
--max-num-seqs 256 --tokenizer-mode deepseek_v4 \
|
||
--reasoning-parser deepseek_v4 \
|
||
--spec-method dspark --spec-model /data/models/DeepSeek-V4-Flash-DSpark \
|
||
--spec-tokens 5 \
|
||
--no-disable-hybrid-kv-cache-manager --disable-uvicorn-access-log \
|
||
--port 30004
|
||
```
|
||
|
||
**vLLM-dspark 无投机解码**
|
||
```bash
|
||
vllm serve /data/models/DeepSeek-V4-Flash-DSpark \
|
||
--trust-remote-code --tensor-parallel-size 8 \
|
||
--kv-cache-dtype fp8 --block-size 256 --max-model-len auto \
|
||
--max-num-seqs 256 --tokenizer-mode deepseek_v4 \
|
||
--reasoning-parser deepseek_v4 \
|
||
--no-disable-hybrid-kv-cache-manager --disable-uvicorn-access-log \
|
||
--port 30004
|
||
```
|
||
|
||
**vLLM 0.24.0 无投机解码**
|
||
```bash
|
||
vllm serve /data/models/DeepSeek-V4-Flash \
|
||
--trust-remote-code --tensor-parallel-size 8 \
|
||
--kv-cache-dtype fp8 --block-size 256 --max-model-len auto \
|
||
--max-num-seqs 256 --tokenizer-mode deepseek_v4 \
|
||
--reasoning-parser deepseek_v4 \
|
||
--disable-uvicorn-access-log --port 30005
|
||
```
|
||
|
||
**SGLang + EAGLE**
|
||
```bash
|
||
sglang serve --trust-remote-code --model-path /data/models/DeepSeek-V4-Flash \
|
||
--tp 8 --moe-runner-backend marlin \
|
||
--speculative-algorithm EAGLE --speculative-num-steps 3 \
|
||
--speculative-eagle-topk 1 --speculative-num-draft-tokens 4 \
|
||
--host 0.0.0.0 --port 30000
|
||
```
|
||
|
||
### 3.2 Benchmark 命令
|
||
|
||
使用各引擎自带的 serving benchmark:
|
||
|
||
**vLLM / vLLM-dspark**
|
||
```bash
|
||
vllm bench serve --host 127.0.0.1 --port <PORT> --backend openai \
|
||
--dataset-name sharegpt --dataset-path <DATASET> \
|
||
--sharegpt-output-len 256 --num-prompts 200 \
|
||
--max-concurrency <C> --endpoint /v1/completions \
|
||
--model <MODEL> --seed 42 --save-result --result-dir <DIR>
|
||
```
|
||
|
||
**SGLang**
|
||
```bash
|
||
python -m sglang.bench_serving --backend sglang --host 127.0.0.1 --port 30000 \
|
||
--dataset-name sharegpt --dataset-path <DATASET> \
|
||
--num-prompts 2000 --sharegpt-output-len 256 \
|
||
--max-concurrency <C> --model <MODEL> --seed 42 --output-file <FILE>
|
||
```
|
||
|
||
> 注:SGLang 历史测试使用 2000 prompts,vLLM-dspark / vLLM 本次测试使用 200 prompts,对比时主要关注相对趋势而非绝对数值。
|
||
|
||
---
|
||
|
||
## 4. 测试结果
|
||
|
||
### 4.1 总体对比(请求吞吐 req/s)
|
||
|
||
| 配置 | 引擎 | 投机方法 | 并发=1 | 并发=16 | 并发=64 | 并发=128 | 并发=256 |
|
||
|---|---|---:|---:|---:|---:|---:|---:|
|
||
| SGLang + EAGLE | sglang | EAGLE (4 draft) | 1.17 | 6.03 | 9.64 | 14.35 | 22.06 |
|
||
| vLLM-dspark + DSpark (st=3) | vllm-dspark | DSpark | 1.03 | 8.24 | **14.53** | - | - |
|
||
| vLLM-dspark + DSpark (st=5) | vllm-dspark | DSpark | 1.07 | 7.70 | 9.36 | - | - |
|
||
| vLLM-dspark + DSpark (st=7) | vllm-dspark | DSpark | 1.03 | 7.46 | 9.13 | - | - |
|
||
| vLLM-dspark 无投机 | vllm-dspark | 无 | 0.59 | 5.61 | 7.34 | - | - |
|
||
| vLLM 0.24.0 无投机 | vllm | 无 | 0.58 | 5.05 | 6.85 | - | - |
|
||
|
||
### 4.2 总体对比(输出 token 吞吐 tok/s)
|
||
|
||
| 配置 | 并发=1 | 并发=16 | 并发=64 | 并发=128 | 并发=256 |
|
||
|---|---:|---:|---:|---:|---:|
|
||
| SGLang + EAGLE | 243.51 | 1259.0 | 2012.43 | 2996.37 | 4608.35 |
|
||
| vLLM-dspark + DSpark (st=3) | 254.39 | 1992.18 | **3507.81** | - | - |
|
||
| vLLM-dspark + DSpark (st=5) | 257.18 | 1862.34 | 2210.46 | - | - |
|
||
| vLLM-dspark + DSpark (st=7) | 251.58 | 1772.30 | 2218.58 | - | - |
|
||
| vLLM-dspark 无投机 | 144.62 | 1364.00 | 1803.98 | - | - |
|
||
| vLLM 0.24.0 无投机 | 138.26 | 1180.98 | 1641.89 | - | - |
|
||
|
||
### 4.3 vLLM-dspark 不同 `--spec-tokens` 对比
|
||
|
||
| spec-tokens | 并发 | req/s | out tok/s | 平均接受长度 | 接受率 | mean TTFT (ms) | mean TPOT (ms) | mean ITL (ms) |
|
||
|---:|---:|---:|---:|---:|---:|---:|---:|---:|
|
||
| 3 | 1 | 1.03 | 254.39 | 2.22 | 40.56% | 78.07 | 3.64 | 8.00 |
|
||
| 3 | 16 | 8.24 | 1992.18 | 2.19 | 39.66% | 90.90 | 7.63 | 16.23 |
|
||
| 3 | 64 | **14.53** | **3507.81** | 2.16 | 38.71% | 355.29 | 15.84 | 33.13 |
|
||
| 5 | 1 | 1.07 | 257.18 | 2.44 | 28.71% | 88.43 | 3.53 | 8.56 |
|
||
| 5 | 16 | 7.70 | 1862.34 | 2.39 | 27.87% | 92.23 | 8.19 | 18.90 |
|
||
| 5 | 64 | 9.36 | 2210.46 | 2.40 | 28.07% | 453.06 | 26.19 | 60.10 |
|
||
| 7 | 1 | 1.03 | 251.58 | 2.43 | 20.45% | 73.16 | 3.70 | 8.92 |
|
||
| 7 | 16 | 7.46 | 1772.30 | 2.41 | 20.10% | 106.43 | 8.92 | 20.07 |
|
||
| 7 | 64 | 9.13 | 2218.58 | 2.42 | 20.25% | 351.01 | 26.25 | 61.33 |
|
||
|
||
> 数据来源:`/data/user1/yy/bench_results/dsv4_comparison_20260705_152221/vllm-dspark-dspark-st{3,5,7}_c{1,16,64}.json`
|
||
|
||
### 4.4 延迟指标对比
|
||
|
||
| 配置 | 并发 | mean TTFT (ms) | mean TPOT (ms) | mean ITL (ms) |
|
||
|---|---:|---:|---:|---:|
|
||
| vLLM-dspark + DSpark (st=3) | 16 | 90.90 | 7.63 | 16.23 |
|
||
| vLLM-dspark + DSpark (st=5) | 16 | 92.23 | 8.19 | 18.90 |
|
||
| vLLM-dspark + DSpark (st=7) | 16 | 106.43 | 8.92 | 20.07 |
|
||
| vLLM-dspark 无投机 | 16 | 113.49 | 11.06 | 11.02 |
|
||
| vLLM 0.24.0 无投机 | 16 | 332.87 | 11.73 | 11.74 |
|
||
| SGLang + EAGLE | 16 | 168.95 | 12.67 | - |
|
||
|
||
### 4.5 投机解码 vs 无投机解码加速比
|
||
|
||
以 vLLM-dspark 无投机为基线:
|
||
|
||
| 配置 | 并发=1 | 并发=16 | 并发=64 |
|
||
|---|---:|---:|---:|
|
||
| DSpark st=3 | 1.75× | 1.47× | **1.98×** |
|
||
| DSpark st=5 | 1.80× | 1.37× | 1.28× |
|
||
| DSpark st=7 | 1.74× | 1.33× | 1.24× |
|
||
|
||
以 vLLM 0.24.0 无投机为基线:
|
||
|
||
| 配置 | 并发=1 | 并发=16 | 并发=64 |
|
||
|---|---:|---:|---:|
|
||
| DSpark st=3 | 1.78× | 1.63× | 2.12× |
|
||
| DSpark st=5 | 1.84× | 1.52× | 1.37× |
|
||
| DSpark st=7 | 1.77× | 1.48× | 1.33× |
|
||
|
||
---
|
||
|
||
## 5. 结果分析
|
||
|
||
### 5.1 DSpark 的优势场景
|
||
|
||
- **高并发**:当 batch size 足够大时,DSpark 的 draft 计算可以被充分并行化,接受率带来的收益超过 draft 开销。`--spec-tokens 3` 在并发 64 时达到 14.53 req/s,几乎是 vLLM-dspark 无投机的 2 倍;
|
||
- **长输出**:输出 token 越多,投机解码节省的 target 前向次数越多;
|
||
- **低延迟与高吞吐兼得**:在并发 16 时,DSpark st=3 的 mean TTFT 仅 90.90 ms,mean TPOT 7.63 ms,均优于无投机基线和 SGLang EAGLE。
|
||
|
||
### 5.2 DSpark 的劣势场景
|
||
|
||
- **单请求**:虽然单请求也有 1.7-1.8× 加速,但加速比主要来自接受率;draft 模型的固定开销仍然存在;
|
||
- **`--spec-tokens` 过大**:st=5 和 st=7 在高并发(64)下性能反而下降。原因是 draft tokens 数量增加后,验证阶段的计算量和 KV cache 压力增大,而接受率并未提升(st=7 接受率仅 20%);
|
||
- **TTFT 抖动**:高并发下 DSpark 的 P99 TTFT 明显升高(st=5 c=64 时 P99 TTFT 达 5381 ms),说明调度/内存压力较大。
|
||
|
||
### 5.3 不同 `--spec-tokens` 的选择
|
||
|
||
| spec-tokens | 最佳并发 | 表现 |
|
||
|---|---|---|
|
||
| 3 | 高并发(64+) | 接受率最高(~40%),吞吐最高,验证开销最小 |
|
||
| 5 | 中低并发(1-16) | 接受长度略高(2.4),单请求吞吐最优 |
|
||
| 7 | 不推荐 | 接受率下降(~20%),验证开销大,高并发下性能倒退 |
|
||
|
||
### 5.4 与 EAGLE 的对比
|
||
|
||
- **接受率**:EAGLE 接受长度稳定在 2.61,DSpark st=3 接受长度 2.16-2.22,但 DSpark 接受率(token 级别)达 38-40%,说明每段 draft 的质量并不低;
|
||
- **吞吐**:vLLM-dspark + DSpark st=3 在并发 64 时(14.53 req/s)已接近 SGLang EAGLE 在并发 128 时(14.35 req/s)。SGLang 在更高并发(256-512)下仍能通过扩大 batch 提升吞吐,但这是以极高的 TTFT 为代价的;
|
||
- **延迟**:vLLM-dspark DSpark 在中低并发下的 TTFT/TPOT 明显优于 SGLang EAGLE;
|
||
- **实现成熟度**:SGLang 的 EAGLE 实现更成熟稳定;vLLM-dspark 的 DSpark 仍在快速迭代,部分参数组合(如 st=5/7 @ c=64)出现性能倒退。
|
||
|
||
### 5.5 vLLM-dspark vs vLLM 0.24.0
|
||
|
||
- 在完全无投机解码的情况下,vLLM-dspark(0.23.1rc)比 vLLM 0.24.0 更快:
|
||
- 并发 1:0.59 vs 0.58 req/s(接近)
|
||
- 并发 16:5.61 vs 5.05 req/s(+11%)
|
||
- 并发 64:7.34 vs 6.85 req/s(+7%)
|
||
- 这说明 vLLM-dspark 分支对 DeepSeek-V4 的 MLA / MoE / sparse attention 路径有更针对性的优化。
|
||
|
||
### 5.6 vLLM vs SGLang 引擎差异
|
||
|
||
- **启动与兼容性**:vLLM-dspark 对 DSV4 支持更直接,SGLang 对 EAGLE 支持更成熟;
|
||
- **调度策略**:SGLang 的 radix attention / chunked prefill 在长上下文场景有优势;
|
||
- **性能天花板**:SGLang EAGLE 在极高并发(512+)下吞吐更高,但延迟失控;vLLM-dspark DSpark 在中高并发(16-64)下延迟更优;
|
||
- **数据可比性**:SGLang 历史测试使用 2000 prompts,vLLM 本次仅 200 prompts,绝对数值需谨慎对比。
|
||
|
||
---
|
||
|
||
## 6. 最优参数建议
|
||
|
||
### 6.1 低延迟场景(单用户 / 低并发)
|
||
|
||
- 推荐:**DSpark `--spec-tokens 5`**;
|
||
- 原因:单请求下 st=5 的 req/s 最高(1.07),TPOT/ITL 与 st=3/7 接近,接受长度最长(2.44)。
|
||
|
||
### 6.2 高吞吐场景(高并发 / 在线服务)
|
||
|
||
- 推荐:**DSpark `--spec-tokens 3`**,`--max-num-seqs 256`,`--max-concurrency 64-128`;
|
||
- 原因:st=3 在高并发下接受率最高、验证开销最小,实测吞吐最高(14.53 req/s,3507 tok/s)。
|
||
|
||
### 6.3 长输出场景
|
||
|
||
- 推荐:开启 DSpark,`--spec-tokens 3-5`;
|
||
- 原因:输出越长,每次投机成功节省的 target 前向越多。st=3 更适合高并发,st=5 更适合中低并发。
|
||
|
||
### 6.4 短输出场景
|
||
|
||
- 推荐:**关闭投机解码** 或使用 `--spec-tokens 3`;
|
||
- 原因:短输出下投机收益有限,且 st=5/7 的验证开销可能抵消收益。
|
||
|
||
### 6.5 避免的参数组合
|
||
|
||
- **避免 `--spec-tokens 7` @ 高并发**:接受率仅 20%,高并发下吞吐不如 st=3/5;
|
||
- **避免 `--spec-tokens 5` @ 极高并发**:P99 TTFT 大幅升高,服务质量下降。
|
||
|
||
---
|
||
|
||
## 7. 结论
|
||
|
||
1. **vLLM-dspark + DSpark 在 DeepSeek-V4-Flash 上显著优于无投机解码基线**,最佳配置(st=3, c=64)比 vLLM-dspark 无投机快 **1.98×**,比 vLLM 0.24.0 无投机快 **2.12×**;
|
||
2. **DSpark 的最佳 `--spec-tokens` 取决于并发度**:
|
||
- 低并发(1-16):`--spec-tokens 5` 综合最优;
|
||
- 高并发(64+):`--spec-tokens 3` 综合最优;
|
||
3. **与 SGLang EAGLE 相比**,vLLM-dspark DSpark 在中高并发下延迟更优,吞吐接近;SGLang 在极限并发下吞吐更高但延迟失控;
|
||
4. **vLLM-dspark 分支对 DSV4 的优化效果明显**,即使无投机解码也比 vLLM 0.24.0 主分支更快;
|
||
5. **DSpark 目前仍不够稳定**,部分参数组合(st=5/7 @ c=64)出现性能倒退和高 TTFT 抖动,生产部署前需要针对实际负载调参。
|
||
|
||
---
|
||
|
||
## 8. 附录
|
||
|
||
### 8.1 原始数据文件
|
||
|
||
- vLLM-dspark / vLLM 测试结果:`/data/user1/yy/bench_results/dsv4_comparison_20260705_152221/`
|
||
- SGLang 历史结果:
|
||
- `/data/user1/yy/bench_results/sglang_8card_systematic_20260704_120819/`
|
||
- `/data/user1/yy/bench_results/sglang_8card_max_throughput_20260705_030839/`
|
||
|
||
### 8.2 测试脚本
|
||
|
||
- 主控脚本:`/data/user1/yy/bench_dsv4_comparison.py`
|
||
- 指标提取脚本:`/tmp/extract_dsv4_metrics.py`
|
||
|
||
### 8.3 已知限制
|
||
|
||
- vLLM-dspark 的 DSpark 实现较新,部分参数组合可能不稳定;
|
||
- 本次测试未覆盖 PD 分离、前缀缓存、不同输出长度等高级特性;
|
||
- SGLang 与 vLLM 的 prompt 数量不一致(2000 vs 200),绝对数值对比仅供参考;
|
||
- 不同数据集和 prompt 长度分布会影响结果。
|