diff --git a/experiments/dsv4_h200_vllm_mtp_vs_default/results/20260708-160349/three_way_comparison.md b/experiments/dsv4_h200_vllm_mtp_vs_default/results/20260708-160349/three_way_comparison.md new file mode 100644 index 0000000..6c1b32a --- /dev/null +++ b/experiments/dsv4_h200_vllm_mtp_vs_default/results/20260708-160349/three_way_comparison.md @@ -0,0 +1,86 @@ +# 投机解码策略对比:vLLM+MTP vs vLLM+DSpark vs vLLM default + +> 数据来自同一批 default baseline(`dsv4_h200_vllm_dspark_vs_default/results/20260708-142121/default`),MTP 与 DSpark 分别与之对比后合并。 + +## 配置差异 + +| 维度 | vLLM default | vLLM+MTP | vLLM+DSpark | +|---|---|---|---| +| 模型 checkpoint | `DeepSeek-V4-Flash` | `DeepSeek-V4-Flash` | `DeepSeek-V4-Flash-DSpark` | +| 运行环境 | `envs/vllm` | `envs/vllm` | `envs/vllm-dspark` | +| 投机方法 | 无 | MTP (`num_speculative_tokens=1`) | DSpark (`spec-tokens=5`) | +| 启动参数 | 无投机 | `--speculative-config '{"method":"mtp","num_speculative_tokens":1}'` | `--spec-method dspark --spec-model --spec-tokens 5` | + +**注意**:DSpark 同时换了模型 checkpoint 和 vLLM 环境,因此不完全是"方法 vs 方法"的公平对比,而是"DSpark 方案整体" vs "官方 MTP 方案"的对比。 + +## 三向结果表 + +| Scenario | Backend | Conc | Input | Output | Req/s | OutTok/s | Mean TTFT(ms) | P95 TTFT(ms) | Mean TPOT(ms) | P99 TPOT(ms) | Mean E2E(ms) | +|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:| +| c1_i512_o256 | vllm-default | 1 | 512 | 256 | 0.99 | 143.82 | 49.50 | 68.50 | 6.66 | 6.71 | 1010.98 | +| c1_i512_o256 | vllm-mtp | 1 | 512 | 256 | 1.64 | 239.37 | 60.63 | 70.69 | 3.80 | 4.33 | 607.04 | +| c1_i512_o256 | vllm-dspark | 1 | 512 | 256 | 2.56 | 372.62 | 86.51 | 185.00 | 2.09 | 3.83 | 389.62 | +| c32_i512_o256 | vllm-default | 32 | 512 | 256 | 12.98 | 1713.20 | 122.62 | 272.00 | 15.77 | 23.26 | 2154.65 | +| c32_i512_o256 | vllm-mtp | 32 | 512 | 256 | 12.56 | 1657.98 | 279.91 | 761.67 | 16.73 | 37.56 | 2332.50 | +| c32_i512_o256 | vllm-dspark | 32 | 512 | 256 | 16.53 | 2182.83 | 262.56 | 527.21 | 12.06 | 28.16 | 1738.79 | +| c128_i512_o256 | vllm-default | 128 | 512 | 256 | 29.99 | 3959.89 | 617.72 | 767.18 | 18.31 | 65.44 | 2695.91 | +| c128_i512_o256 | vllm-mtp | 128 | 512 | 256 | 35.03 | 4625.47 | 771.59 | 1110.39 | 18.16 | 111.99 | 2506.29 | +| c128_i512_o256 | vllm-dspark | 128 | 512 | 256 | 23.94 | 3160.81 | 778.36 | 1071.85 | 28.95 | 78.75 | 3632.34 | +| c1_i4000_o512 | vllm-default | 1 | 4000 | 512 | 0.50 | 140.13 | 131.50 | 191.53 | 6.68 | 6.73 | 2008.09 | +| c1_i4000_o512 | vllm-mtp | 1 | 4000 | 512 | 0.83 | 234.90 | 161.27 | 216.12 | 3.70 | 3.89 | 1197.52 | +| c1_i4000_o512 | vllm-dspark | 1 | 4000 | 512 | 1.73 | 486.20 | 123.58 | 176.29 | 1.66 | 3.56 | 578.26 | +| c32_i4000_o512 | vllm-default | 32 | 4000 | 512 | 5.38 | 1518.49 | 382.74 | 681.98 | 16.43 | 25.49 | 4927.71 | +| c32_i4000_o512 | vllm-mtp | 32 | 4000 | 512 | 6.32 | 1785.09 | 409.17 | 667.77 | 14.18 | 19.84 | 4431.73 | +| c32_i4000_o512 | vllm-dspark | 32 | 4000 | 512 | 11.49 | 3242.88 | 298.42 | 434.24 | 9.68 | 54.60 | 2476.82 | + +## 分场景结论 + +### 短输入(512 tokens) + +| 场景 | 最优 TTFT | 最优 TPOT | 最优吞吐 | 综合推荐 | +|---|---|---|---|---| +| c1_i512_o256 | default | DSpark | DSpark | DSpark(TTFT 可接受,TPOT/E2E 大幅提升) | +| c32_i512_o256 | default | DSpark | DSpark | DSpark(TTFT 与 MTP 接近,TPOT 更好) | +| c128_i512_o256 | default | MTP | MTP | default(如果 TTFT 优先);MTP(如果吞吐优先) | + +### 长输入(4000 tokens) + +| 场景 | 最优 TTFT | 最优 TPOT | 最优吞吐 | 综合推荐 | +|---|---|---|---|---| +| c1_i4000_o512 | DSpark | DSpark | DSpark | DSpark | +| c32_i4000_o512 | DSpark | DSpark | DSpark | DSpark | + +## 总体判断 + +### DSpark 整体更优,但有前提 + +1. **长输入场景(4000 tokens)DSpark 全胜**:TTFT、TPOT、吞吐均优于 MTP 和 default。 +2. **低并发短输入 DSpark 也更好**:虽然 TTFT 比 default 慢,但 TPOT 和 E2E 提升明显,吞吐更高。 +3. **高并发短输入(c128_i512_o256)DSpark 反而不如 MTP**: + - DSpark 的 TPOT(28.95ms)显著差于 MTP(18.16ms)和 default(18.31ms) + - DSpark 吞吐(23.94 req/s)也低于 default(29.99)和 MTP(35.03) + - 这说明 DSpark 的 `spec-tokens=5` 在高并发短输入下会造成较重的 verification/调度开销,整体效率下降。 + +### MTP 的定位 + +- **优势**:使用官方 recipe,部署简单,不需要换模型 checkpoint 和 vLLM 环境;在高并发短输入下吞吐表现最好。 +- **劣势**:长输入和低并发下收益不如 DSpark;在 c32_i512_o256 这类场景中 TTFT overhead 比 DSpark 还大(P95 761ms vs 527ms)。 + +### default 的定位 + +- 在 TTFT 敏感且输入短的场景(尤其是高并发)下,default 仍然是最稳的选择。 + +## 推荐策略 + +| 应用场景 | 推荐方案 | +|---|---| +| 长输入 / 高输出(如文档总结、代码生成) | **DSpark** | +| 低并发交互(如单用户 Chat) | **DSpark**(如果可接受略高 TTFT) | +| 高并发短输入 API(如 S0/S1 轻量层) | **default** 或 **MTP** | +| 不想换模型 checkpoint,又想尝试投机解码 | **MTP** | + +## 后续可验证的优化点 + +1. **给 DSpark 调小 `spec-tokens`**:在短输入高并发场景测试 `spec-tokens=1/2/3`,可能改善 c128_i512_o256 的 TPOT 和吞吐。 +2. **给 MTP 调大 `num_speculative_tokens`**:当前是 1,尝试 2-4,看能否在长输入下接近 DSpark 的收益。 +3. **统一模型 checkpoint 对比**:如果可能,用同一个模型分别跑 DSpark 方法和 MTP 方法,排除模型差异带来的偏差。