辅助解码
辅助解码通过让辅助模型在主模型确认之前提出候选 token,从而加速文本生成。主模型在一次前向传播中验证这些候选 token。辅助模型速度快、成本低,可以替代主模型数十次更昂贵的前向传播。
本指南介绍了 Transformers 中的辅助解码方法。
推测解码
投机解码使用较小的辅助模型来起草候选 token。主模型在一次前向传播中验证这些 token。通过验证的 token 进入最终输出,而被拒绝的 token 则触发标准采样。由于主模型需要执行的昂贵前向传播次数更少,因此生成速度更快。
当辅助模型明显小于主模型且使用相同的分词器时,该方法效果最佳。推测解码支持贪心搜索和采样,但不支持批量输入。
将 assistant_model 传递给 generate()。设置 do_sample=True,以便在 token 验证失败时重新采样。
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM-1.7B")
model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM-1.7B", dtype="auto")
assistant_model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM-135M", dtype="auto")
inputs = tokenizer("Hugging Face is an open-source company", return_tensors="pt")
outputs = model.generate(**inputs, assistant_model=assistant_model)
tokenizer.batch_decode(outputs, skip_special_tokens=True)
'Hugging Face is an open-source company that provides a platform for developers to build and deploy machine'assistant_model 参数也可在 Pipeline API 中使用。
import torch
from transformers import pipeline
pipeline = pipeline(
"text-generation",
model="meta-llama/Llama-3.1-8B",
assistant_model="meta-llama/Llama-3.2-1B",
dtype="auto"
)
pipeline("Hugging Face is an open-source company, ", max_new_tokens=50, do_sample=False)将 temperature 设置为控制随机性。较低的温度通常能改善延迟。
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM-1.7B")
model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM-1.7B", dtype="auto")
assistant_model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM-135M", dtype="auto")
inputs = tokenizer("Hugging Face is an open-source company", return_tensors="pt")
outputs = model.generate(**inputs, assistant_model=assistant_model, do_sample=True, temperature=0.5)
tokenizer.batch_decode(outputs, skip_special_tokens=True)
'Hugging Face is an open-source company that is dedicated to creating a better world through technology.'提示词查找解码
Prompt lookup decoding 不需要助手模型。它通过在提示中查找重叠的 n-gram 来提出候选 token。如果不存在匹配项,则回退到正常的自回归解码。这适用于摘要和翻译等基于输入的任务,因为候选 token 通常会反映源文本中的局部模式。
将 prompt_lookup_num_tokens 传递给 generate()。这用于设置当算法检测到重复模式时,尝试从提示词前文复制的 token 数量。
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM-1.7B")
model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM-1.7B", dtype="auto")
inputs = tokenizer("Hugging Face is an open-source company", return_tensors="pt")
outputs = model.generate(**inputs, prompt_lookup_num_tokens=5)
tokenizer.batch_decode(outputs, skip_special_tokens=True)
'Hugging Face is an open-source company that provides a platform for developers to build and deploy machine learning models. It offers a variety of tools'import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM-1.7B")
model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM-1.7B", dtype="auto")
inputs = tokenizer("Hugging Face is an open-source company", return_tensors="pt")
outputs = model.generate(**inputs, prompt_lookup_num_tokens=5, do_sample=True, temperature=0.5)
tokenizer.batch_decode(outputs, skip_special_tokens=True)
'Hugging Face is an open-source company that provides a platform for developers to build and deploy machine learning models. It offers a variety of tools'自推测解码
自推测解码利用模型的中间层作为助手来提出候选 token。如果提议匹配,模型将提前退出,由剩余层对 token 进行验证或纠正。
由于所有层共用同一个模型,权重和缓存得以共享,从而在不增加额外内存开销的情况下提升速度。该技术仅适用于经过训练以支持从中间层输出提前退出 logits 的模型。
将 assistant_early_exit 传递给 generate() 以设置退出层。
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("facebook/layerskip-llama3.2-1B")
model = AutoModelForCausalLM.from_pretrained("facebook/layerskip-llama3.2-1B", dtype="auto")
inputs = tokenizer("Hugging Face is an open-source company", return_tensors="pt")
outputs = model.generate(**inputs, assistant_early_exit=4, do_sample=False, max_new_tokens=20)
tokenizer.batch_decode(outputs, skip_special_tokens=True)多令牌预测(MTP)层
多 token 预测(MTP)层使用来自主模型自身检查点的额外预测层来起草候选 token。MTP 层复用主模型的嵌入和输出头。每个 MTP 层起草一个 token,因此每步的候选数量与检查点中的 MTP 层数一致。主模型在一次前向传播中验证这些草稿。
MTP 仅支持与使用 MTP 层训练的 checkpoint 配合使用,例如 DeepSeek-V3 和 GLM-4.5。这些 checkpoint 包含 MTP 权重,并在其配置中设置了 num_mtp_layers,在 config.json 中列为 num_nextn_predict_layers。
将 use_mtp=True 传递给 generate(),如果模型没有 MTP 层,则会引发错误。与推测解码类似,MTP 支持贪心搜索和采样,但不支持批量输入。
在此,MTP 指的是目标检查点中包含的预测层,例如 DeepSeek-V3 和 GLM-4.5。Gemma 4 使用单独的 assistant 检查点进行 MTP 解码。请将其作为 assistant_model 传入(参见 多 token 预测 drafter)。
text-generation 流水线与 generate() 均接受 use_mtp=True。
from transformers import pipeline
pipe = pipeline(
"text-generation",
model="zai-org/GLM-4.5-Air",
device_map="auto",
)
outputs = pipe(
"Hugging Face is an open-source company",
use_mtp=True,
do_sample=False,
max_new_tokens=50,
add_special_tokens=True,
return_full_text=True,
)
[output["generated_text"] for output in outputs]或者,您可以按以下方式执行推理。
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("zai-org/GLM-4.5-Air")
model = AutoModelForCausalLM.from_pretrained("zai-org/GLM-4.5-Air", device_map="auto")
inputs = tokenizer("Hugging Face is an open-source company", return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, use_mtp=True, do_sample=False, max_new_tokens=50)
tokenizer.batch_decode(outputs, skip_special_tokens=True)多 token 预测草稿器
MTP 草稿器是一个从独立检查点加载的轻量级辅助模型。它为目标模型提出候选 token 以供验证。草稿器使用目标模型的输入嵌入,并关注其 KV 缓存。它从目标模型的隐藏状态开始,然后以自回归方式起草 token。对于每个下一个 token,它将其投影后的隐藏状态反馈回草稿器。目标模型在一次前向传播中验证起草的 token,这与推测解码(speculative decoding)中的做法相同。
与 MTP 层不同,MTP 层是目标检查点的一部分,并共享其输出头;而 MTP drafter 是一个独立的辅助模型。它利用目标的输入嵌入和 KV cache 来提议 token。
from transformers import AutoProcessor, AutoModelForCausalLM
processor = AutoProcessor.from_pretrained("google/gemma-4-E4B-it")
target_model = AutoModelForCausalLM.from_pretrained(
"google/gemma-4-E4B-it",
dtype="auto",
device_map="auto",
)
assistant_model = AutoModelForCausalLM.from_pretrained(
"google/gemma-4-E4B-it-assistant",
dtype="auto",
device_map="auto",
)
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Write a short joke about saving RAM."},
]
inputs = processor.apply_chat_template(
messages,
tokenize=True,
return_dict=True,
return_tensors="pt",
add_generation_prompt=True,
enable_thinking=False
).to(target_model.device)
input_len = inputs["input_ids"].shape[-1]
outputs = target_model.generate(
**inputs,
assistant_model=assistant_model,
max_new_tokens=256,
)
response = processor.decode(outputs[0][input_len:], skip_special_tokens=False)
processor.parse_response(response)通用辅助解码
通用辅助解码(UAD)使得即使主模型和辅助模型使用不同的分词器,也能实现推测解码。它允许您将任意小型辅助模型与主模型配对使用。候选 token 会被重新编码,算法会计算最长公共子序列,从而确保后续生成内容保持对齐。
将 tokenizer、assistant_tokenizer 和 assistant_model 传递给 generate() 以启用 UAD。
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
assistant_tokenizer = AutoTokenizer.from_pretrained("double7/vicuna-68m")
tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-9b")
model = AutoModelForCausalLM.from_pretrained("google/gemma-2-9b", dtype="auto")
assistant_model = AutoModelForCausalLM.from_pretrained("double7/vicuna-68m", dtype="auto")
inputs = tokenizer("Hugging Face is an open-source company", return_tensors="pt")
outputs = model.generate(**inputs, assistant_model=assistant_model, tokenizer=tokenizer, assistant_tokenizer=assistant_tokenizer)
tokenizer.batch_decode(outputs, skip_special_tokens=True)
'Hugging Face is an open-source company that is dedicated to creating a better world through technology.'静态集成验证
标准推测解码是无损的——它保证输出分布与目标模型完全一致。静态集成验证放宽了这一要求,通过针对目标分布与草稿分布的混合分布进行验证,从而提高了接受率(加快推理速度),代价是使输出分布变为混合分布,而非精确的目标分布。建议的起始值为0.7。
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM-1.7B")
model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM-1.7B", dtype="auto")
assistant_model = AutoModelForCausalLM.from_pretrained("HuggingFaceTB/SmolLM-135M", dtype="auto")
inputs = tokenizer("Hugging Face is an open-source company", return_tensors="pt")
outputs = model.generate(**inputs, assistant_model=assistant_model, assistant_ensemble_weight=0.7, do_sample=True)
tokenizer.batch_decode(outputs, skip_special_tokens=True)这需要来自助手模型的候选 logits,并且不支持提示查找解码。
资源
- 阅读辅助生成:迈向低延迟文本生成的新方向博客文章,以了解更多关于文本生成延迟和辅助生成的背景信息。