Transformers documentation
Декодирование с помощью
Декодирование с помощью
Ассистированное декодирование ускоряет генерацию текста, позволяя вспомогательной модели предлагать кандидаты токенов до того, как основная модель примет их. Основная модель проверяет кандидаты токенов за один прямой проход. Вспомогательная модель работает быстро и дёшево и может заменить десятки более дорогих прямых проходов основной модели.
В этом руководстве рассматриваются методы ассистированного декодирования в Transformers.
Спекулятивное декодирование
Speculative decoding использует более маленькую вспомогательную модель для генерации кандидатов токенов. Основная модель проверяет эти токены за один проход. Валидированные токены попадают в итоговый вывод, а отклонённые токены запускают стандартную выборку. Генерация становится быстрее, так как основная модель выполняет меньше дорогостоящих прямых проходов.
Метод работает лучше всего, когда модель ассистента значительно меньше основной модели и использует тот же токенизатор. Спекулятивное декодирование поддерживает жадный поиск и выборку, но не поддерживает пакетные входные данные.
Передайте assistant_model в generate(). Установите do_sample=True, чтобы выполнить повторную выборку, если проверка токена не пройдена.
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 также доступен в API Pipeline.
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-граммы в промпте, чтобы предложить кандидаты на токены. Если совпадение не найдено, используется стандартное авторегрессионное декодирование. Этот подход подходит для задач, основанных на входных данных, таких как суммаризация и перевод, поскольку кандидаты на токены часто повторяют локальные паттерны исходного текста.
Передайте prompt_lookup_num_tokens в generate(). Это определяет, сколько токенов алгоритм пытается скопировать из предыдущей части промпта при обнаружении повторяющегося паттерна.
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'Самоспекулятивное декодирование
Self-speculative decoding использует промежуточные слои модели в качестве ассистента для предложения кандидатов токенов. Если предложение совпадает, модель завершает работу досрочно, а оставшиеся слои проверяют или корректируют токены.
Поскольку это единая модель, веса и кэши разделяются, что повышает скорость без дополнительного расхода памяти. Этот метод работает только для моделей, обученных с поддержкой раннего выхода логитов из промежуточных слоёв.
Передайте 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)
Слой много-токенового предсказания (MTP) генерирует кандидаты токенов с помощью дополнительных слоёв предсказания, взятых из собственного чекпоинта основной модели. Слои MTP переиспользуют эмбеддинги и выходную голову основной модели. Каждый слой MTP генерирует один токен, поэтому количество кандидатов на каждом шаге соответствует числу слоёв MTP в чекпоинте. Основная модель проверяет сгенерированные токены за один прямой проход.
MTP работает только с контрольными точками, обученными с использованием слоёв MTP, такими как DeepSeek-V3 и GLM-4.5. Эти контрольные точки содержат веса MTP и задают num_mtp_layers в своей конфигурации, которая в config.json указана как num_nextn_predict_layers.
Передайте use_mtp=True в generate(), что вызовет ошибку, если у модели нет слоёв MTP. Как и спекулятивное декодирование, MTP поддерживает жадный поиск и сэмплирование, но не батчи входных данных.
Здесь MTP означает слои предсказания, включённые в целевой чекпоинт, как в DeepSeek-V3 и GLM-4.5. Gemma 4 использует отдельный чекпоинт ассистента для декодирования MTP. Передайте его как assistant_model (см. Драфтер многозначкового предсказания).
Пайплайн 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)Драфтер с предсказанием нескольких токенов
MTP-драфтер — это легковесная вспомогательная модель, загружаемая из отдельного чекпоинта. Она предлагает кандидаты токенов для проверки целевой моделью. Драфтер использует входные эмбеддинги целевой модели и обращается к её KV-кэшу. Он начинает с скрытых состояний целевой модели, а затем генерирует токены авто регрессивно. Для каждого следующего токена он подает свое проекционное скрытое состояние обратно в драфтер. Целевая модель проверяет сгенерированные токены за один прямой проход, как в случае с спекулятивным декодированием.
В отличие от слоёв MTP, которые являются частью целевого чекпоинта и разделяют с ним выходную голову, MTP-драфтер представляет собой отдельную вспомогательную модель. Он использует входные эмбеддинги и KV-кэш целевой модели для предложения токенов.
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) позволяет использовать спекулятивное декодирование даже в том случае, если у основной модели и модели-ассистента разные токенизаторы. Это даёт возможность связать любую небольшую модель-ассистент с основной моделью. Кандидатские токены перекодируются, а алгоритм вычисляет самую длинную общую подпоследовательность, чтобы продолжение оставалось согласованным.
Передайте 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)Для этого требуются логиты кандидатов от модели ассистента, и это не поддерживается при использовании prompt lookup decoding.
Ресурсы
- Ознакомьтесь с блогом Assisted Generation: a new direction toward low-latency text generation, чтобы получить больше контекста о задержках генерации текста и ассистированной генерации.