Transformers documentation
Bitsandbytes
Bitsandbytes
La biblioteca bitsandbytes ofrece herramientas de cuantización para LLMs a través de un envoltorio ligero de Python alrededor de funciones de aceleradores de hardware. Permite trabajar con modelos grandes utilizando recursos computacionales limitados al reducir su huella de memoria.
En su núcleo, bitsandbytes ofrece:
- Capas lineales cuantizadas: capas
Linear8bitLtyLinear4bitque reemplazan las capas lineales estándar de PyTorch por alternativas cuantizadas eficientes en memoria - Optimized Optimizers: 8-bit versions of common optimizers through its
optimmodule, enabling training of large models with reduced memory requirements - Multiplicación de matrices: Operaciones de multiplicación de matrices optimizadas que aprovechan el formato cuantizado
bitsandbytes ofrece dos funciones principales de cuantización:
LLM.int8() - Un método de cuantización de 8 bits que hace que la inferencia sea más accesible sin una degradación significativa del rendimiento. A diferencia de la cuantización ingenua, LLM.int8() preserva dinámicamente una mayor precisión para los cálculos críticos, evitando la pérdida de información en las partes sensibles del modelo.
QLoRA - Una técnica de cuantización de 4 bits que comprime los modelos aún más manteniendo su capacidad de entrenamiento mediante la inserción de un pequeño conjunto de pesos de adaptación de bajo rango (LoRA) entrenables.
Nota: Para una experiencia de cuantización más amigable, puedes utilizar el espacio de la comunidad de
bitsandbytes.
Ejecute el siguiente comando para instalar bitsandbytes.
pip install --upgrade transformers accelerate bitsandbytes
Para compilar desde el código fuente, siga las instrucciones de la guía de instalación de bitsandbytes.
Compatibilidad con el hardware
bitsandbytes es compatible con GPUs de NVIDIA para versiones de CUDA 11.8 - 13.0, Intel XPU, Intel Gaudi (HPU) y CPU. Existe un esfuerzo en curso para dar soporte a plataformas adicionales. Si te interesa proporcionar comentarios o realizar pruebas, consulta el repositorio de bitsandbytes para obtener más información.
GPUs de NVIDIA (CUDA)
Este backend es compatible con las plataformas Linux x86-64, Linux aarch64 y Windows.
| Característica | Requisito mínimo de hardware |
|---|---|
| Optimizadores de 8 bits | GPUs NVIDIA Pascal (serie GTX 10X0, P100) o más recientes * |
| LLM.int8() | GPUs NVIDIA Turing (serie RTX 20X0, T4) o más recientes |
| Cuantización NF4/FP4 | GPUs NVIDIA Pascal (serie GTX 10X0, P100) o más recientes * |
GPUs de Intel (XPU)
Este backend se admite en las plataformas Linux x86-64 y Windows x86-64.
Intel Gaudi (HPU)
Este backend es compatible con Linux x86-64 para Gaudi2 y Gaudi3.
CPU
Este backend se admite en las plataformas Linux x86-64, Linux aarch64 y Windows x86-64.
Ejemplos de cuantización
Cuantice un modelo pasando una BitsAndBytesConfig a from_pretrained(). Esto funciona para cualquier modelo de cualquier modalidad, siempre que admita Accelerate y contenga capas torch.nn.Linear.
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model_8bit = AutoModelForCausalLM.from_pretrained(
"bigscience/bloom-1b7",
device_map="auto",
quantization_config=quantization_config
)Por defecto, todos los demás módulos, como torch.nn.LayerNorm, se configuran con el dtype de torch predeterminado. Puede cambiar el tipo de datos de estos módulos con el parámetro dtype. Establecer dtype="auto" carga el modelo con el tipo de datos definido en el archivo config.json del modelo.
import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model_8bit = AutoModelForCausalLM.from_pretrained(
"facebook/opt-350m",
device_map="auto",
quantization_config=quantization_config,
dtype="auto"
)
model_8bit.model.decoder.layers[-1].final_layer_norm.weight.dtypeUna vez que un modelo está cuantizado a 8 bits, no se pueden subir los pesos cuantizados al Hub a menos que se esté utilizando la última versión de Transformers y bitsandbytes. Si se tienen las últimas versiones, se puede subir el modelo de 8 bits al Hub con push_to_hub(). Primero se sube el archivo config.json de cuantización, seguido de los pesos del modelo cuantizado.
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(
"bigscience/bloom-560m",
device_map="auto",
quantization_config=quantization_config
)
model.push_to_hub("bloom-560m-8bit")from transformers import AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model_4bit = AutoModelForCausalLM.from_pretrained(
"bigscience/bloom-1b7",
device_map="auto",
quantization_config=quantization_config
)Por defecto, todos los demás módulos, como torch.nn.LayerNorm, se convierten a torch.float16. Puede cambiar el tipo de datos de estos módulos con el parámetro dtype. Establecer dtype="auto" carga el modelo en el tipo de datos definido en el archivo config.json del modelo.
import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model_4bit = AutoModelForCausalLM.from_pretrained(
"facebook/opt-350m",
device_map="auto",
quantization_config=quantization_config,
dtype="auto"
)
model_4bit.model.decoder.layers[-1].final_layer_norm.weight.dtypeAsegúrate de tener la última versión de bitsandbytes para poder serializar modelos de 4 bits y subirlos al Hub con push_to_hub(). Utiliza save_pretrained() para guardar el modelo de 4 bits localmente.
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model = AutoModelForCausalLM.from_pretrained(
"bigscience/bloom-560m",
device_map="auto",
quantization_config=quantization_config
)
model.push_to_hub("bloom-560m-4bit")El entrenamiento en 8 y 4 bits solo se admite para entrenar parámetros extra.
Comprueba tu huella de memoria con get_memory_footprint.
print(model.get_memory_footprint())Cargue modelos cuantizados con from_pretrained() sin un quantization_config.
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("{your_username}/bloom-560m-8bit", device_map="auto")LLM.int8
Esta sección explora algunas de las características específicas de la cuantización de 8 bits, como el offloading, los umbrales de valores atípicos, el omitir la conversión de módulos y el finetuning.
Descarga
Los modelos de 8 bits pueden descargar los pesos entre la CPU y la GPU para que quepan en memoria modelos muy grandes. Los pesos que se envían a la CPU se almacenan en float32 y no se convierten a 8 bits. Por ejemplo, habilite la descarga para bigscience/bloom-1b7 mediante BitsAndBytesConfig.
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(llm_int8_enable_fp32_cpu_offload=True)Diseña un mapa de dispositivos personalizado para que todo quepa en tu GPU, excepto lm_head, que se despacha a la CPU.
device_map = {
"transformer.word_embeddings": 0,
"transformer.word_embeddings_layernorm": 0,
"lm_head": "cpu",
"transformer.h": 0,
"transformer.ln_f": 0,
}Ahora carga tu modelo con el device_map y el quantization_config personalizados.
model_8bit = AutoModelForCausalLM.from_pretrained(
"bigscience/bloom-1b7",
dtype="auto",
device_map=device_map,
quantization_config=quantization_config,
)Umbral de valores atípicos
Un “outlier” es un valor de estado oculto que supera cierto umbral, y estos valores se calculan en fp16. Aunque los valores suelen tener una distribución normal ([-3.5, 3.5]), esta distribución puede ser muy diferente en modelos grandes ([-60, 6] o [6, 60]). La cuantización de 8 bits funciona bien para valores ~5, pero más allá de eso, hay un penalización significativa en el rendimiento. Un valor de umbral por defecto adecuado es 6, pero puede ser necesario un umbral más bajo para modelos más inestables (modelos pequeños o finetuning).
Para encontrar el mejor umbral para tu modelo, experimenta con el parámetro llm_int8_threshold en BitsAndBytesConfig. Por ejemplo, establecer el umbral en 0.0 acelera significativamente la inferencia, a costa de una posible pérdida de precisión.
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
model_id = "bigscience/bloom-1b7"
quantization_config = BitsAndBytesConfig(
llm_int8_threshold=0.0,
llm_int8_enable_fp32_cpu_offload=True
)
model_8bit = AutoModelForCausalLM.from_pretrained(
model_id,
dtype="auto",
device_map=device_map,
quantization_config=quantization_config,
)Omitir la conversión de módulos
Para algunos modelos, como Jukebox, no es necesario cuantizar cada módulo a 8 bits, ya que esto puede provocar inestabilidad. En el caso de Jukebox, hay varios módulos lm_head que deben omitirse mediante el parámetro llm_int8_skip_modules en BitsAndBytesConfig.
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
model_id = "bigscience/bloom-1b7"
quantization_config = BitsAndBytesConfig(
llm_int8_skip_modules=["lm_head"],
)
model_8bit = AutoModelForCausalLM.from_pretrained(
model_id,
dtype="auto",
device_map="auto",
quantization_config=quantization_config,
)Ajuste fino
La biblioteca PEFT permite el ajuste fino de modelos grandes como flan-t5-large y facebook/opt-6.7b con cuantización de 8 bits. No es necesario pasar el parámetro device_map para el entrenamiento, ya que carga automáticamente el modelo en una GPU. Sin embargo, aún puedes personalizar el mapa de dispositivos con el parámetro device_map (device_map="auto" solo debe usarse para inferencia).
QLoRA
Esta sección explora algunas de las características específicas de la cuantización de 4 bits, como el cambio del tipo de datos de cálculo, el tipo de datos Normal Float 4 (NF4) y la cuantización anidada.
Tipo de datos de cálculo
Cambie el tipo de datos de float32 (el valor predeterminado) a bf16 en BitsAndBytesConfig para acelerar el cálculo.
import torch
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16)Float 4 normal (NF4)
NF4 es un tipo de datos de 4 bits del artículo QLoRA, adaptado para pesos inicializados desde una distribución normal. Debe utilizar NF4 para entrenar modelos base de 4 bits.
from transformers import BitsAndBytesConfig
nf4_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
)
model_nf4 = AutoModelForCausalLM.from_pretrained(model_id, dtype="auto", quantization_config=nf4_config)Para la inferencia, el bnb_4bit_quant_type no tiene un gran impacto en el rendimiento. Sin embargo, para mantener la coherencia con los pesos del modelo, debe usar los valores de bnb_4bit_compute_dtype y dtype.
Cuantización anidada
La cuantización anidada puede ahorrar memoria adicional sin un coste de rendimiento extra. Esta característica realiza una segunda cuantización de los pesos ya cuantizados para ahorrar 0,4 bits/parámetro adicionales. Por ejemplo, con cuantización anidada, puedes hacer un ajuste fino de un modelo Llama-13b en una GPU NVIDIA T4 de 16 GB con una longitud de secuencia de 1024, un tamaño de lote de 1 y habilitando la acumulación de gradientes con 4 pasos.
from transformers import BitsAndBytesConfig
double_quant_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
)
model_double_quant = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-13b-chat-hf", dtype="auto", quantization_config=double_quant_config)Descomprimir modelos de bitsandbytes
Una vez cuantizado, puedes dequantize() un modelo a la precisión original, aunque esto puede provocar cierta pérdida de calidad. Asegúrate de tener suficiente memoria de GPU para cargar el modelo decuantizado.
from transformers import AutoModelForCausalLM, BitsAndBytesConfig, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m", BitsAndBytesConfig(load_in_4bit=True))
model.dequantize()Recursos
Obtenga más información sobre los detalles de la cuantización de 8 bits en A Gentle Introduction to 8-bit Matrix Multiplication for transformers at scale using Hugging Face Transformers, Accelerate and bitsandbytes.
Prueba la cuantización de 4 bits en este cuaderno y conoce más detalles en Making LLMs even more accessible with bitsandbytes, 4-bit quantization and QLoRA.
Update on GitHub