推测解码指南#
本指南介绍如何在 vLLM Ascend 中使用推测解码。推测解码是一种技术,用于改善受内存带宽限制的 LLM 推理中的 token 间延迟。
通过匹配提示词中的 n-gram 进行推测#
以下代码配置 vLLM Ascend 使用推测解码,其中候选 token 通过匹配提示词中的 n-gram 生成。
离线推理
from vllm import LLM, SamplingParams prompts = [ "The future of AI is", ] sampling_params = SamplingParams(temperature=0.8, top_p=0.95) llm = LLM( model="meta-llama/Meta-Llama-3.1-8B-Instruct", tensor_parallel_size=1, speculative_config={ "method": "ngram", "num_speculative_tokens": 5, "prompt_lookup_max": 4, }, ) outputs = llm.generate(prompts, sampling_params) for output in outputs: prompt = output.prompt generated_text = output.outputs[0].text print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
使用基于 EAGLE 的草稿模型进行推测#
以下代码配置 vLLM Ascend 使用推测解码,其中候选 token 由基于 EAGLE (Extrapolation Algorithm for Greater Language-model Efficiency) 的草稿模型生成。
在 vLLM Ascend v0.12.0rc1 中,异步调度器更加稳定并已准备就绪。我们已对其进行适配以支持 EAGLE,您可以通过如下设置 async_scheduling=True 来使用它。如果遇到任何问题,请随时在 GitHub 上提交 issue。作为一种变通方法,您可以在初始化模型时取消设置 async_scheduling=True 来禁用此功能。
离线推理
from vllm import LLM, SamplingParams prompts = [ "The future of AI is", ] sampling_params = SamplingParams(temperature=0.8, top_p=0.95) llm = LLM( model="meta-llama/Meta-Llama-3.1-8B-Instruct", tensor_parallel_size=4, distributed_executor_backend="mp", enforce_eager=True, async_scheduling=True, speculative_config={ "method": "eagle", "model": "yuhuili/EAGLE-LLaMA3.1-Instruct-8B", "draft_tensor_parallel_size": 1, "num_speculative_tokens": 2, }, ) outputs = llm.generate(prompts, sampling_params) for output in outputs: prompt = output.prompt generated_text = output.outputs[0].text print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
使用基于 EAGLE 的草稿模型时需要考虑的几个重要事项:
EAGLE 模型的 HF 仓库 中可用的 EAGLE 草稿模型应由 vLLM 直接加载和使用。此功能已在 PR #4893 中添加。如果您使用的 vLLM 版本早于该拉取请求合并的时间,请更新到较新的版本。
基于 EAGLE 的草稿模型需要在不使用张量并行的情况下运行(即
speculative_config中的draft_tensor_parallel_size设置为 1),尽管主模型可以使用张量并行运行(参见上面的示例)。当使用基于 EAGLE-3 的草稿模型时,选项 "method" 必须设置为 "eagle3"。也就是说,在
speculative_config中指定"method": "eagle3"。启用 EAGLE 后,主模型需要在一个解码过程中验证由主模型和草稿模型生成的
(1 + K)个 token。而全图模式将在验证阶段固定 token 的数量,因此cudagraph_capture_sizes必须是一个捕获大小的列表,其中每个大小计算为n * (K + 1),n是您希望支持的每个批次大小。例如,要支持批次大小从 1 到 4 且num_speculative_tokens = 4,cudagraph_capture_sizes应设置为[5, 10, 15, 20]。
使用 MTP 推测器进行推测#
以下代码配置 vLLM Ascend 使用推测解码,其中候选 token 由 MTP(多 Token 预测)生成,通过并行化多个 token 的预测来提升推理性能。有关 MTP 的更多信息,请参阅 Multi_Token_Prediction
在线推理
vllm serve /deepseek-ai/DeepSeek-V3.2-Exp-W8A8 \ --port 20004 \ --data-parallel-size 1 \ --tensor-parallel-size 16 \ --enable-expert-parallel \ --seed 1024 \ --served-model-name dsv3 \ --max-model-len 36768 \ --max-num-batched-tokens 5000 \ --max-num-seqs 10 \ --quantization ascend \ --trust-remote-code \ --gpu-memory-utilization 0.9 \ --compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \ --speculative-config '{"num_speculative_tokens": 2, "method":"deepseek_mtp", "disable_padded_drafter_batch": false}'
使用后缀解码进行推测#
以下代码配置 vLLM 使用推测解码,其中候选 token 使用后缀解码生成 (SuffixDecoding: Extreme Speculative Decoding for Emerging AI Applications)。
与 n-gram 类似,后缀解码可以通过使用最后 n 个生成的 token 进行模式匹配来生成草稿 token。与 n-gram 不同,后缀解码 (1) 可以针对提示词和之前的生成内容进行模式匹配,(2) 使用频率计数来提议最可能的后续内容,(3) 为每个请求在每次迭代中推测自适应数量的 token,以获得更好的接受率。
后缀解码可以在高重复性任务中实现更好的性能,例如代码编辑、智能体循环(例如自我反思、自洽性)和强化学习(RL)的 rollout。
[!注意] 后缀解码需要 Arctic Inference。您可以通过
pip install arctic-inference安装它。
离线推理
from vllm import LLM, SamplingParams prompts = [ "The future of AI is", ] sampling_params = SamplingParams(temperature=0.8, top_p=0.95) llm = LLM( model="meta-llama/Meta-Llama-3.1-8B-Instruct", tensor_parallel_size=1, enforce_eager=True, speculative_config={ "method": "suffix", "num_speculative_tokens": 15, }, ) outputs = llm.generate(prompts, sampling_params) for output in outputs: prompt = output.prompt generated_text = output.outputs[0].text print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
块验证与熵验证#
vLLM Ascend 为推测解码中的拒绝采样器提供了两种可选优化:块验证和熵验证。这些功能以少量输出精度为代价,换取推理吞吐量的提升。
[!警告] 块验证和熵验证都会修改 token 接受标准,可能导致轻微的精度下降(例如,与标准拒绝采样器相比,输出 token 略有不同)。在生产环境中启用它们之前,请评估对您特定工作负载的质量影响。
块验证#
块验证使用累积概率乘积将所有草稿 token 作为一个整体进行评估,而不是独立检查每个 token。这可以提高接受率并减少拒绝采样的开销,尤其是在 num_speculative_tokens >= 3 时。
熵验证#
熵验证根据目标分布的熵调整接受阈值:
高熵(不确定分布)→ 较低的有效阈值 → 接受更多 token
低熵(确定分布)→ 较高的有效阈值 → 更严格的拒绝
这种熵感知阈值由两个参数控制:
posterior_threshold(默认值:0.95):修改后阈值的上限。即使熵非常低,有效阈值也不会超过此值。posterior_alpha(默认值:0.4):控制熵影响阈值的强度。较高的 alpha 使阈值对熵变化更敏感,导致推测 token 的接受率更高,但精度损失也更大。您需要根据具体的模型和数据集调整此值。
用法#
在线推理
vllm serve <model> --additional-config \ '{"rejection_sampler_config": {"enable_block_verify": true, \ "enable_entropy_verify": true, "posterior_threshold": 0.95, \ "posterior_alpha": 0.4}}'
离线推理
llm = LLM( model, additional_config={ "rejection_sampler_config": { "enable_block_verify": True, "enable_entropy_verify": True, "posterior_threshold": 0.95, "posterior_alpha": 0.4, } }, )
这两个功能可以独立启用,也可以同时启用。同时使用时,块验证的累积接受率将与熵验证的熵调整阈值相结合。