Transformers documentation
Обзор
Обзор
Transformers предлагает несколько методов оптимизации инференса, чтобы сделать модели быстрыми, доступными по цене и простыми в использовании. Среди вариантов — альтернативные механизмы внимания для снижения нагрузки на память, компиляция кода для ускорения выполнения и оптимизированные ядра для повышения пропускной способности. Комбинируйте эти методы для достижения максимальной производительности.
Для настройки устройства и конфигурации, специфичной для конкретного оборудования, см. руководства по аппаратному обеспечению. Перед применением оптимизаций, описанных ниже, убедитесь, что ваши аппаратные средства поддерживают соответствующие методы.
Память и скорость тесно связаны, но не тождественны. Сокращение объёма используемой памяти делает модель «быстрее», поскольку уменьшается количество данных, которые необходимо перемещать. Чистые оптимизации скорости не всегда снижают потребление памяти, а иногда даже увеличивают его. Выбирайте подходящий тип оптимизации в зависимости от вашей задачи и аппаратного обеспечения.
Используйте таблицу ниже, чтобы выбрать метод оптимизации.
| Техника | Скорость | Память |
|---|---|---|
| Компиляция | ✅ | |
| Бэкенды внимания | ✅ | ✅ |
| Ядра | ✅ | ✅ |
| Квантование | ✅ | ✅ |
| Кэширование | ✅ | ✅ |
| Параллелизм | ✅ | |
| Непрерывная пакетная обработка | ✅ |
В этом руководстве кратко описаны оптимизации Transformers.
Компиляция
torch.compile снижает накладные расходы Python, объединяет операции и создаёт ядра, оптимизированные под ваши размеры тензоров и оборудование. Первый запуск выполняет прогрев, а последующие используют более быстрый скомпилированный путь.
Передайте кэш фиксированного размера в generate(), чтобы автоматически запустить torch.compile.
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B", dtype=torch.float16, device_map="auto")
input = tokenizer("The French Bread Law states", return_tensors="pt").to(model.device)
output = model.generate(**input, do_sample=False, max_new_tokens=20, cache_implementation="static")
tokenizer.batch_decode(output, skip_special_tokens=True)[0]Избегайте вызова
torch.compile(model)вне generate(), чтобы модель не перекомпилировалась на каждом шаге.
Бэкенды внимания
Альтернативные бэкенды внимания снижают объём трафика памяти. Например, FlashAttention разбивает вычисления внимания на блоки и избегает создания крупных промежуточных тензоров, что уменьшает потребление памяти.
Укажите attn_implementation в from_pretrained(), чтобы загрузить оптимизированный бэкенд внимания.
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B", attn_implementation="flash_attention_2")Ядра
Kernels объединяют операции, чтобы повысить пропускную способность и снизить потребление памяти. Библиотека Kernels загружает оптимизированные вычислительные ядра из Hub гибким и безопасным с точки зрения версий способом.
Приведённый ниже пример загружает оптимизированное ядро FlashAttention-2 без установки пакета.
import torch
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-0.6B", attn_implementation="kernels-community/flash-attn2"
)Квантование
Квантование уменьшает размер каждого параметра, что снижает потребление памяти и повышает скорость, поскольку позволяет выполнять больше операций.
Передайте конфигурацию квантования в аргумент quantization_config в from_pretrained(). У каждого бэкенда квантования своя конфигурация с различными аргументами. В примере ниже модель квантуется до 4 бит, а тип данных для вычислений настраивается с помощью бэкенда bitsandbytes.
import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16)
model = AutoModelForCausalLM.from_pretrained(
"allenai/Olmo-3-7B-Think", quantization_config=bnb_config
)Кэширование
Кэширование ускоряет генерацию за счёт повторного использования прошлых ключей и значений вместо их пересчёта для каждого токена. Для компенсации и снижения затрат памяти на хранение прошлых ключей и значений Transformers поддерживает выгрузку кэша на CPU. На GPU остаётся только текущий слой.
Используйте аргумент cache_implementation в generate(), чтобы задать стратегию кэширования.
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-0.6B", attn_implementation="kernels-community/flash-attn2"
)
inputs = tokenizer("The Le Décret Pain states that a baguette must,", return_tensors="pt")
outputs = model.generate(**inputs, do_sample=False, max_new_tokens=50, cache_implementation="offloaded")Параллелизм
Parallelism распределяет модель по устройствам, чтобы модели, слишком большие для одного устройства, работали быстро. Этот подход потребляет больше памяти из-за накладных расходов на шардирование и коммуникацию для синхронизации результатов.
Параллелизм тензоров распределяет слой модели между устройствами. Укажите количество устройств с помощью DistributedConfig(tp_size=N) и передайте его в from_pretrained(), чтобы включить этот режим.
from transformers import AutoModelForCausalLM, DistributedConfig
distributed_config = DistributedConfig(tp_size=4)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Meta-Llama-3-8B-Instruct",
distributed_config=distributed_config,
)
print(model._tp_plan)Непрерывная пакетная обработка
Continuous batching максимизирует пропускную способность, поддерживая загрузку GPU за счёт динамического планирования и chunked prefill. Приложения для Serving используют его для одновременной обработки нескольких входящих запросов.
Используйте generate_batch() для включения непрерывного батчинга.
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.generation import ContinuousBatchingConfig, GenerationConfig
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-0.6B",
attn_implementation="sdpa",
device_map="auto",
torch_dtype=torch.bfloat16,
)
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
prompts = [
"The Le Décret Pain states that a baguette must",
"Explain gravity in one sentence.",
"Name the capital of France.",
]
inputs = [tokenizer.encode(p) for p in prompts]
generation_config = GenerationConfig(
max_new_tokens=32,
eos_token_id=tokenizer.eos_token_id,
pad_token_id=tokenizer.pad_token_id,
do_sample=False,
)
continuous_batching_config = ContinuousBatchingConfig(max_batch_tokens=512)
outputs = model.generate_batch(
inputs=inputs,
generation_config=generation_config,
continuous_batching_config=continuous_batching_config,
)
for request_id, output in outputs.items():
text = tokenizer.decode(output.generated_tokens, skip_special_tokens=True)
print(f"[{request_id}] {text}")