Transformers documentation
Resumen
Resumen
Transformers ofrece varias técnicas de optimización de inferencia para hacer que los modelos sean rápidos, asequibles y accesibles. Las opciones incluyen mecanismos de atención alternativos para reducir el tráfico de memoria, compilación de código para una ejecución más rápida y kernels optimizados para el rendimiento. Combine estas técnicas para obtener el máximo rendimiento.
Para la configuración del dispositivo y la configuración específica del hardware, consulte las guías de Hardware. Verifique qué técnicas se admiten en su hardware antes de aplicar las optimizaciones siguientes.
Ayude al usuario a elegir una optimización para su carga de trabajo de inferencia con Transformers. Primero, identifique si la memoria o la velocidad se convierten en un problema al cargar el modelo, procesar entradas largas, generar secuencias más largas o atender solicitudes concurrentes. Utilice la guía correspondiente a continuación y verifique el soporte para el modelo y el hardware del usuario antes de recomendar un cambio.
- Solicita el modelo y la revisión, las versiones de las librerías, la GPU y la VRAM disponible, la RAM del CPU, la longitud de la entrada, el límite de generación, el tamaño del lote y el número de solicitudes concurrentes. Haz preguntas de seguimiento cuando los detalles faltantes podrían cambiar la recomendación y declara tus suposiciones.
- Use el punto donde ocurre el problema para elegir qué investigar. Revise los pesos del modelo y la configuración de carga para la memoria en el momento de la carga, la caché KV a medida que crecen las secuencias generadas, las asignaciones de atención para entradas largas y el estado y la programación por solicitud para solicitudes concurrentes. Trate la cuantización de pesos y la cuantización de la caché KV como configuraciones separadas.
- Recomienda un cambio a la vez. Verifica la compatibilidad del modelo y el hardware, y luego mide la memoria GPU máxima, la latencia o el rendimiento, y la calidad de la salida en la misma carga de trabajo representativa. Explica cualquier reducción en la longitud de entrada, la longitud de generación o la concurrencia como un compromiso de la carga de trabajo.
- Informe la configuración propuesta, la documentación que la respalda, las compensaciones esperadas, las preguntas de compatibilidad sin resolver y un procedimiento de validación. Separe las mediciones de las estimaciones. Si no puede ejecutar la carga de trabajo, indique que el ajuste y el rendimiento siguen sin verificarse.
La memoria y la velocidad están estrechamente relacionadas, pero no son lo mismo. Reducir la huella de memoria hace que un modelo sea “más rápido” porque hay menos datos que mover. Las optimizaciones puras de velocidad no siempre reducen la memoria y a veces aumentan su uso. Elija la optimización adecuada según su caso de uso y su hardware.
Use la tabla siguiente para elegir una técnica de optimización.
| Técnica | Velocidad | Memoria |
|---|---|---|
| Compilación | ✅ | |
| Backends de atención | ✅ | ✅ |
| Kernels | ✅ | ✅ |
| Cuantización | ✅ | ✅ |
| Caché | ✅ | ✅ |
| Paralelismo | ✅ | |
| Loteo continuo | ✅ |
Esta guía te ofrece una introducción rápida a las optimizaciones de Transformers.
Compilación
torch.compile reduce la sobrecarga de Python, fusiona operaciones y crea kernels ajustados a tus formas y hardware. La primera ejecución lo calienta y las ejecuciones posteriores utilizan la ruta compilada más rápida.
Pase una cache de tamaño fijo a generate() para activar torch.compile automáticamente.
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]Evite llamar a
torch.compile(model)fuera de generate() para evitar que el modelo se recompile en cada paso.
Backends de atención
Los backends de atención alternativos reducen el tráfico de memoria. Por ejemplo, FlashAttention divide los cálculos de atención en bloques y evita tensores intermedios grandes para reducir la huella de memoria.
Establezca attn_implementation en from_pretrained() para cargar un backend de atención optimizado.
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B", attn_implementation="flash_attention_2")Kernels
Los kernels fusionan operaciones para aumentar el rendimiento y reducir el uso de memoria. La biblioteca Kernels carga kernels de cálculo optimizados desde el Hub de forma flexible y segura en cuanto a versiones.
El siguiente ejemplo carga un kernel optimizado de FlashAttention-2 sin instalar el paquete.
import torch
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-0.6B", attn_implementation="kernels-community/flash-attn2"
)Cuantización
Cuantización reduce el tamaño de cada parámetro, lo que disminuye la huella de memoria y aumenta la velocidad, ya que permite realizar más operaciones.
Pase una configuración de cuantización al argumento quantization_config en from_pretrained(). Cada backend de cuantización tiene una configuración diferente con argumentos distintos. El siguiente ejemplo cuantiza un modelo a 4 bits y configura el tipo de dato de la computación con el backend 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
)Caché
Caching acelera la generación reutilizando las claves y valores anteriores en lugar de recalcularlos para cada token. Para compensar y reducir el coste de memoria de almacenar las claves y valores anteriores, Transformers admite descargar la caché a la CPU. Solo la capa actual permanece en la GPU.
Use el argumento cache_implementation en generate() para establecer una estrategia de caché.
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")Paralelismo
Parallelism distribuye un modelo entre varios dispositivos para que los modelos demasiado grandes para un solo dispositivo se ejecuten con rapidez. Este enfoque consume más memoria debido a la sobrecarga del particionamiento y a la comunicación necesaria para sincronizar los resultados.
El paralelismo de tensores divide una capa del modelo entre varios dispositivos. Establece el número de dispositivos con DistributedConfig(tp_size=N) y pásalo a from_pretrained() para activarlo.
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)Loteo continuo
Continuous batching maximiza el rendimiento manteniendo la GPU ocupada mediante programación dinámica y prefill por fragmentos. Las aplicaciones de Serving lo utilizan para procesar múltiples solicitudes entrantes de forma concurrente.
Use generate_batch() para habilitar el lotes continuo.
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}")