# 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 长度分布会影响结果。
