intel / intel/llm-scaler

[Performance] MTP speculative decoding degrades at long context: 50K input (Qwen3.8-27B, Arc Pro B60 x2, Core)

Open
#657 8 comments 0 reactions 1 assignee Claimed by @liu-shaojun View on GitHub
Dominant language
C++
Stars
529
Forks
80
Avg merge
9h 7m
Merged PRs (30d)
38

Description

## Summary

We benchmarked MTP (`num_speculative_tokens=4`) on **Qwen3.8-27B / 2x Intel Arc Pro B60 CORE
(TP=2)** at both 1K and 50K input length, under fp8 and int4 weights.

MTP works well at short context (up to **+131%** output throughput at 1K), but at
**50K input the benefit largely disappears and the downside becomes severe**:

- **Decode speedup collapses from ~2.3x to ~1.1-1.26x even at unchanged acceptance
length (~4.8 of 5).**
- With low acceptance, 50K throughput drops **below the non-MTP baseline** (-16% fp8,
**-37% int4**).

For our target workload (**50K in / 1K out, > 50 tok/s**), MTP as currently implemented
is not usable: the best measured 50K result is 25.88 tok/s, about **2x short of target**.

## Environment

- GPU: Intel Arc Pro B60 x 2, Re-sizable BAR enabled
- CPU: 12th Gen Intel(R) Core(TM) i9-12900K
- mem: 16*4 DDR4 2666 MT/s

## Setup

| Item | Value |
|---|---|
| Model | Qwen3.8-27B |
| GPU | Intel Arc Pro B60 x 2, `--tensor-parallel-size 2` |
| Spec decode | MTP, `num_speculative_tokens = 4` |
| Weights | fp8 / int4 |
| Image | `[intel/llm-scaler-vllm:0.21.0-b3]` |

[docker-compose.yaml](https://github.com/user-attachments/files/31637249/docker-compose.yaml)

benchmark:
https://github.com/intel/llm-scaler/blob/main/vllm/README.md#15-benchmarking-the-service

## Measured data

### 50K input

| Precision | Config | TTFT (ms) | Output tok/s | vs. baseline |
|---|---|---|---|---|
| fp8 | baseline (no MTP) | 1380.8 | 19.13 | - |
| fp8 | MTP4, high acceptance (94.9% / 4.79) | 2820.8 | 24.06 | **+25.8%** |
| fp8 | MTP4, low acceptance (53.8% / 3.15) | 2827.6 | 16.13 | **-15.7%** |
| int4 | baseline (no MTP) | 1384.6 | 24.04 | - |
| int4 | MTP4, high acceptance (93.6% / 4.75) | 2800.6 | 25.88 | **+7.7%** |
| int4 | MTP4, low acceptance (42.4% / 2.69) | 2802.2 | 15.17 | **-36.9%** |

### 1K input

| Precision | Config | TTFT (ms) | Output tok/s | vs. baseline |
|---|---|---|---|---|
| fp8 | baseline (no MTP) | 1181.1 | 23.24 | - |
| fp8 | MTP4, high acceptance (97.3% / 4.89) | 1240.6 | 53.78 | **+131.4%** |
| fp8 | MTP4, low acceptance (28.0% / 2.12) | 1254.5 | 24.28 | +4.5% |
| int4 | baseline (no MTP) | 1202.0 | 31.03 | - |
| int4 | MTP4, high acceptance (93.5% / 4.74) | 1240.4 | 63.13 | **+103.4%** |
| int4 | MTP4, low acceptance (28.7% / 2.15) | 1240.3 | 29.87 | -3.7% |

## Gap to our target

Target: **50K in / 1K out, > 50 tok/s.**

---

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.