跳至内容

推测式解码

警告

请注意,vLLM中的推测解码功能尚未优化,通常不会对所有提示数据集或采样参数带来token间延迟降低。优化工作正在进行中,可在此处跟踪进展: Issue #4630

警告

目前,vLLM中的推测解码暂不支持流水线并行。

本文档展示如何在vLLM中使用推测解码技术。推测解码是一种能够改善内存受限LLM推理中令牌间延迟的方法。

使用草稿模型进行推测

以下代码将vLLM配置为离线模式,使用草稿模型进行推测解码,每次推测5个token。

警告

在vllm v0.10.0版本中,不支持使用草稿模型进行推测解码。如果使用以下代码,将会收到NotImplementedError错误。

Code
from vllm import LLM, SamplingParams

prompts = [
    "The future of AI is",
]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)

llm = LLM(
    model="facebook/opt-6.7b",
    tensor_parallel_size=1,
    speculative_config={
        "model": "facebook/opt-125m",
        "num_speculative_tokens": 5,
    },
)
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}")

要在在线模式下执行相同操作,请启动服务器:

python -m vllm.entrypoints.openai.api_server \
    --host 0.0.0.0 \
    --port 8000 \
    --model facebook/opt-6.7b \
    --seed 42 \
    -tp 1 \
    --gpu_memory_utilization 0.8 \
    --speculative_config '{"model": "facebook/opt-125m", "num_speculative_tokens": 5}'

警告

注意:请使用--speculative_config来设置所有与推测解码相关的配置。之前通过--speculative_model指定模型并单独添加相关参数(例如--num_speculative_tokens)的方法现已弃用。

然后使用客户端:

Code
from openai import OpenAI

# Modify OpenAI's API key and API base to use vLLM's API server.
openai_api_key = "EMPTY"
openai_api_base = "http://localhost:8000/v1"

client = OpenAI(
    # defaults to os.environ.get("OPENAI_API_KEY")
    api_key=openai_api_key,
    base_url=openai_api_base,
)

models = client.models.list()
model = models.data[0].id

# Completion API
stream = False
completion = client.completions.create(
    model=model,
    prompt="The future of AI is",
    echo=False,
    n=1,
    stream=stream,
)

print("Completion results:")
if stream:
    for c in completion:
        print(c)
else:
    print(completion)

通过匹配提示中的n-gram进行推测

以下代码配置vLLM使用推测解码,其中提案通过匹配提示中的n-gram生成。更多信息请阅读此讨论

Code
from vllm import LLM, SamplingParams

prompts = [
    "The future of AI is",
]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)

llm = LLM(
    model="facebook/opt-6.7b",
    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}")

使用MLP推测器进行推测

以下代码配置vLLM使用推测解码技术,其中提案由草稿模型生成,这些模型基于上下文向量和采样标记来条件化草稿预测。更多信息请参阅此博客此技术报告

Code
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-70B-Instruct",
    tensor_parallel_size=4,
    speculative_config={
        "model": "ibm-ai-platform/llama3-70b-accelerator",
        "draft_tensor_parallel_size": 1,
    },
)
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}")

请注意,这些推测模型目前需要在不使用张量并行的情况下运行,尽管主模型可以使用张量并行运行(参见上面的示例)。由于推测模型相对较小,我们仍然能看到显著的加速效果。不过,这一限制将在未来的版本中修复。

HF hub上提供了多种此类推测模型:

使用基于EAGLE的草稿模型进行推测

以下代码配置vLLM使用推测解码技术,其中提案由基于EAGLE(提升语言模型效率的外推算法)的草稿模型生成。关于离线模式的更详细示例(包括如何提取请求级别接受率),请参阅此处

Code
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-8B-Instruct",
    tensor_parallel_size=4,
    speculative_config={
        "model": "yuhuili/EAGLE-LLaMA3-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的草稿模型时需要考虑的几个重要事项:

  1. HF仓库中的EAGLE模型提供的EAGLE草稿模型,在 Pull Request #12304之后应该能够直接被vLLM加载和使用。如果您使用的vllm版本早于 Pull Request #12304,请使用脚本转换推测模型,并在speculative_config中指定"model": "path/to/modified/eagle/model"。如果使用最新版本的vLLM时仍然出现权重加载问题,请留言或提交issue。

  2. 基于EAGLE的草稿模型需要在没有张量并行的情况下运行(即在speculative_config中将draft_tensor_parallel_size设置为1),尽管主模型可以使用张量并行运行(参见上面的示例)。

  3. 当在vLLM中使用基于EAGLE的推测器时,观察到的加速效果低于参考实现此处所报告的数据。该问题正在调查中,跟踪链接: Issue #9565

Hugging Face 中心提供了多种 EAGLE 草稿模型:

基础模型 Hugging Face上的EAGLE EAGLE参数数量
Vicuna-7B-v1.3 yuhuili/EAGLE-Vicuna-7B-v1.3 0.24B
Vicuna-13B-v1.3 yuhuili/EAGLE-Vicuna-13B-v1.3 0.37B
Vicuna-33B-v1.3 yuhuili/EAGLE-Vicuna-33B-v1.3 0.56B
LLaMA2-Chat 7B yuhuili/EAGLE-llama2-chat-7B 0.24B
LLaMA2-Chat 13B yuhuili/EAGLE-llama2-chat-13B 0.37B
LLaMA2-Chat 70B yuhuili/EAGLE-llama2-chat-70B 0.99B
Mixtral-8x7B-Instruct-v0.1 yuhuili/EAGLE-mixtral-instruct-8x7B 0.28B
LLaMA3-Instruct 8B yuhuili/EAGLE-LLaMA3-Instruct-8B 0.25B
LLaMA3-Instruct 70B yuhuili/EAGLE-LLaMA3-Instruct-70B 0.99B
Qwen2-7B-Instruct yuhuili/EAGLE-Qwen2-7B-Instruct 0.26B
Qwen2-72B-Instruct yuhuili/EAGLE-Qwen2-72B-Instruct 1.05B

推测解码的无损保证

在vLLM中,推测解码旨在提高推理效率的同时保持准确性。本节将探讨推测解码的无损保证,并将这些保证分解为三个关键领域:

  1. 理论无损性 - 推测性解码采样在硬件数值精度范围内理论上是无损的。如Accelerating Large Language Model Decoding with Speculative Sampling中所述,浮点误差可能导致输出分布出现轻微变化。

  2. 算法无损性 - vLLM实现的推测解码算法经过验证是无损的。关键验证测试包括:

    • 拒绝采样器收敛性: 确保vLLM拒绝采样器生成的样本符合目标分布。查看测试代码
    • 贪婪采样等价性:验证使用推测解码的贪婪采样与不使用时的结果一致。这确认了vLLM的推测解码框架在与vLLM前向传递和vLLM拒绝采样器集成时,能提供无损保证。 tests/spec_decode/e2e中的几乎所有测试都使用此断言实现来验证这一特性
  3. vLLM 对数概率稳定性 - vLLM 目前不保证token对数概率(logprobs)的稳定性。这可能导致相同请求在不同运行中得到不同的输出。更多详情,请参阅常见问题中标题为vLLM中同一提示的输出在不同运行中会变化吗?的FAQ部分。

虽然vLLM致力于确保推测性解码的无损性,但由于以下因素,使用和不使用推测性解码时生成的输出可能会出现差异:

  • 浮点精度:硬件数值精度的差异可能导致输出分布出现轻微差异。
  • 批次大小与数值稳定性: 批次大小的变化可能导致对数概率和输出概率的波动,这可能是由于批处理操作中的非确定性行为或数值不稳定性造成的。

有关缓解策略,请参考常见问题中的条目vLLM中提示的输出在不同运行中会变化吗?

vLLM贡献者资源

优云智算