后缀推测解码#

简介#

后缀解码是一种基于模式匹配的推测解码优化技术。它同时从提示词和已生成内容中检索重复序列,利用频率统计来预测最可能的后续标记。与传统的推测解码方法不同,后缀解码完全在CPU上运行,无需额外的GPU资源或草稿模型,从而在AI智能体和代码生成等重复性任务上实现卓越的加速效果。

本文档提供了在Atlas A2硬件上部署和基准测试vllm-ascend支持的后缀解码推测推理技术的分步指南。该设置使用单个Atlas 800T A2节点,部署了4卡的Qwen3-32B模型实例。基准测试使用涵盖以下类别的真实开源数据集进行:

数据集类别

数据集名称

代码生成

HumanEval

常识推理

ARC

数学推理

gsm8k

自然语言理解

SuperGLUE_BoolQ

综合评测

AGIEval

多轮对话

ShareGPT

本教程使用的基准测试工具是AISBench,它支持对上述所有数据集进行性能测试。本教程最后一节展示了在不同数据集和并发级别下,满足SLO TPOT < 50ms条件时,启用与禁用后缀解码的性能对比。验证表明,启用后缀解码后,Qwen3-32B模型在各种真实数据集上实现了约20%至80%的吞吐量提升。

下载 vllm-ascend 镜像#

本教程使用官方镜像,版本为v0.13.0rc1。使用以下命令下载:

docker pull quay.io/ascend/vllm-ascend:v0.13.0rc1

使用 Docker 运行#

容器启动命令:

# Update the vllm-ascend image
export IMAGE=quay.io/ascend/vllm-ascend:v0.13.0rc1
export NAME=vllm-ascend

# Run the container using the defined variables
# This test uses four Atlas A2 NPU cards to create the container.
# Mount the hccn.conf file from the host node into the container.

docker run --rm \
--name $NAME \
--net=host \
--shm-size=1g \
--device /dev/davinci0 \
--device /dev/davinci1 \
--device /dev/davinci2 \
--device /dev/davinci3 \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/Ascend/driver/tools/hccn_tool:\
/usr/local/Ascend/driver/tools/hccn_tool \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v /etc/hccn.conf:/etc/hccn.conf \
-v /root/.cache:/root/.cache \
-it $IMAGE bash

安装 arctic-inference#

在Ascend上启用后缀解码推测推理之前,必须安装Arctic Inference插件。Arctic Inference是Snowflake推出的一个开源插件,专门用于优化LLM推理速度。详细技术原理请参考以下文章:Fastest Speculative Decoding in vLLM with Arctic Inference and Arctic Training。在容器内使用以下命令安装:

pip install arctic-inference

vLLM 实例部署#

使用以下命令启动容器服务实例。通过--speculative-config参数启用推测推理,其中method设置为suffix。本次测试中,num_speculative_tokens统一设置为3

# set the NPU device number:
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3
# Set the operator dispatch pipeline level to 1 and disable manual memory control in ACLGraph
export TASK_QUEUE_ENABLE=1
# Enable the AIVector core to directly schedule ROCE communication.
export HCCL_OP_EXPANSION_MODE="AIV"
# Enable FlashComm_v1 optimization when tensor parallel is enabled.
export VLLM_ASCEND_ENABLE_FLASHCOMM1=1

vllm serve /data/Qwen3-32B \
  --served-model-name qwen3 \
  --trust-remote-code \
  --distributed-executor-backend mp \
  --tensor-parallel-size 4 \
  --max-model-len 5500 \
  --max-num-batched-tokens 40960 \
  --speculative-config '{"method": "suffix", "num_speculative_tokens": 3}' \
  --gpu-memory-utilization 0.9 \
  --additional-config '{"pa_shape_list":[48,64,72,80], "weight_prefetch_config":{"enable":true}}' \
  --port 8011

AISbench 基准测试#

所有开源数据集的性能均使用AISbench进行测试。具体操作说明请参考使用AISBench进行性能评估

模型配置

# "ignore_eos" must be set to "False", and "max_out_len" should be set to a large value to allow the model to output completely and naturally.

from ais_bench.benchmark.models import VLLMCustomAPIChatStream

models = [
    dict(
        attr="service",
        type=VLLMCustomAPIChatStream,
        abbr='vllm-api-stream-chat',
        path="<path_to_your_model>/Qwen3-32B",
        model="qwen3",
        request_rate = 0,
        retry = 2,
        host_ip = "<your_server_ip>",
        host_port = 8011,
        max_out_len = 4000,
        batch_size= 16,
        trust_remote_code=False,
        generation_kwargs = dict(
            temperature = 0,
            ignore_eos = False
        )
    )
]

性能基准测试命令

# Example command to test gsm8k dataset performance using the first 100 prompts. Commands for other datasets are similar.
ais_bench --models vllm-api-stream-chat \
  --datasets gsm8k_gen_0_shot_cot_str_perf \
  --debug --summarizer default_perf --mode perf --num-prompts 100

测试结果#

以下是本次评估中六个开源数据集的详细测试结果。与基线性能相比,启用后缀解码后,不同并发级别下的TPOT和吞吐量性能提升程度因数据集而异。启用后缀解码后的提升幅度在不同数据集间存在差异。以下是结果总结:

数据集类别

典型代表

吞吐量提升 (BS=1-10)

SLO TPOT

高增益

AGIEval, GSM8K

> 50%

< 50ms

中低增益

ARC, ShareGPT

20% ~ 30%

< 50ms

以下是原始详细测试结果:

并发数

平均输入长度

平均输出长度

请求数

基线 TPOT(ms)

基线吞吐量(TPS)

后缀解码 TPOT(ms)

后缀解码吞吐量(TPS)

接受率

TPOT 增益

TPS 增益

Humaneval

1

150

2700

100

55.1

18.1

37.9

26.3

27.0%

45.2%

45.1%

15

150

2700

100

61.6

233.8

45.8

318.2

27.0%

34.6%

36.1%

26

150

2700

100

64.7

403.8

50.9

519.2

27.0%

27.2%

28.6%

ARC

1

76

960

100

52.8

18.9

39.5

25.4

23.9%

33.7%

34.6%

8

76

960

100

59.1

125.4

47.0

163.1

23.9%

25.7%

30.0%

15

76

960

100

59.8

245.8

48.9

311.7

23.9%

22.3%

26.8%

GSM8K

1

67

1570

100

55.5

18.0

35.7

28.5

31.1%

55.6%

58.4%

17

67

1570

100

61.5

279.8

45.4

403.0

31.1%

35.6%

44.0%

26

67

1570

100

63.9

396.4

50.0

527.6

31.1%

27.8%

33.1%

ShareGPT

1

666

231

327

54.1

18.3

39.2

24.1

23.9%

37.9%

31.5%

8

666

231

327

58.8

125.0

46.2

153.2

23.9%

27.1%

22.5%

14

666

231

327

61.8

227.0

49.9

273.9

23.9%

23.8%

20.7%

SuperGLUE_BoolQ

1

207

314

100

54.1

18.4

36.1

26.8

33.4%

49.8%

45.6%

16

207

314

100

60.0

229.7

43.5

303.9

33.4%

38.0%

32.3%

32

207

314

100

62.7

396.4

47.8

507.5

33.4%

31.3%

28.0%

AGIEval

1

735

1880

100

53.1

18.7

31.8

34.1

50.3%

66.8%

81.9%

24

735

1880

100

64.0

381.2

43.3

629.0

50.3%

47.8%

65.0%

34

735

1880

100

70.0

494.6

50.2

768.4

50.3%

39.4%

55.3%