QLoRA: Entrenamiento de un modelo de LLM en una GPU de 16 GB

QLoRA Entrenamiento de un modelo de LLM en una GPU de 16 GB

¿Te interesa entrenar un modelo de lenguaje de gran escala (LLM) en una GPU de 16 GB, pero no tienes mucha experiencia técnica? ¡No te preocupes! Con técnicas como QLoRA es posible reducir la memoria que usan estos modelos y hacerlos funcionar en equipos con menos recursos, todo sin perder precisión ni rendimiento.

En esta guía, te explico paso a paso y con ejemplos sencillos cómo lograrlo.

Índice
  1. ¿Qué es QLoRA y por qué es Útil?
  2. Herramientas Necesarias
    1. Instalación de Herramientas
  3. Paso 1: Configurar QLoRA para reducir el tamaño del Modelo
    1. Ejemplo: Cargar un Modelo en 4 Bits
  4. Paso 2: Aplicar Adaptación de Baja Dimensión (LoRA)
    1. Ejemplo de Configuración LoRA en el Modelo
  5. Paso 3: Preparación de los Datos
    1. Ejemplo de Preparación de Datos
  6. Paso 4: Entrenamiento del Modelo
    1. Ejemplo de Configuración de Entrenamiento
    2. Explicación de los Parámetros
  7. Paso 5: Evaluar el Modelo

¿Qué es QLoRA y por qué es Útil?

Entrenar modelos grandes de lenguaje (LLMs) requiere de mucha memoria, algo que normalmente solo está disponible en equipos muy potentes.

Sin embargo, con QLoRA podemos reducir ese consumo de memoria, haciéndolo posible en GPUs de menor capacidad, como una de 16 GB.

QLoRA combina dos técnicas clave:

  1. Cuantización (Quantization): Reduce el tamaño del modelo convirtiendo los datos a un formato más pequeño (como de 4 bits en lugar de los 32 bits habituales).
  2. Adaptación de Baja Dimensión (LoRA): Ajusta solo una parte específica del modelo (en lugar de todo), lo cual reduce mucho el uso de memoria durante el entrenamiento.

Herramientas Necesarias

Antes de comenzar, asegúrate de tener lo siguiente:

  1. CUDA: Un sistema que permite que tu GPU haga cálculos complejos. Si tienes una GPU compatible, normalmente ya viene con CUDA.
  2. PyTorch o TensorFlow: Estos son marcos para manejar los modelos de IA. Usaremos PyTorch en los ejemplos.
  3. BitsAndBytes (bnb): Una herramienta que permite aplicar la técnica de cuantización.
  4. Transformers y Accelerate de Hugging Face: Bibliotecas para descargar y gestionar modelos, optimizándolos para funcionar en múltiples dispositivos.

Instalación de Herramientas

Abre tu terminal y ejecuta los siguientes comandos para instalar lo necesario:

pip install torch transformers accelerate bitsandbytes

También es recomendable instalar DeepSpeed, una biblioteca que ayuda a reducir el uso de memoria en tareas más complejas:

pip install deepspeed

Paso 1: Configurar QLoRA para reducir el tamaño del Modelo

Configurar QLoRA para Reducir el Tamaño del Modelo

El primer paso es descargar un modelo LLM preentrenado y prepararlo para que use menos memoria. Usaremos un modelo conocido (como GPT-2 de OpenAI) para simplificar.

Ejemplo: Cargar un Modelo en 4 Bits

from transformers import AutoModelForCausalLM, AutoTokenizer
import bitsandbytes as bnb

# Seleccionar el modelo y cargar el tokenizador
modelo_nombre = "gpt2"  # Puedes probar con otros modelos de Transformers
tokenizer = AutoTokenizer.from_pretrained(modelo_nombre)

# Cargar el modelo en 4 bits para ahorrar memoria
modelo = AutoModelForCausalLM.from_pretrained(
    modelo_nombre,
    load_in_4bit=True,  # Indicamos que queremos cargar el modelo en 4 bits
    device_map="auto",  # Distribuye el modelo de forma automática
    quantization_config=bnb.nn.QuantizationConfig(quant_type="nf4")  # Configuración de cuantización
)

Con load_in_4bit=True, el modelo solo usa 4 bits para cada parámetro, reduciendo significativamente el uso de memoria. Esto significa que podemos trabajar con modelos más grandes en una GPU de 16 GB.

Paso 2: Aplicar Adaptación de Baja Dimensión (LoRA)

Aplicar Adaptación de Baja Dimensión (LoRA)

La técnica LoRA permite ajustar solo una parte del modelo, lo que significa que solo entrenamos los parámetros esenciales, ahorrando mucha memoria y tiempo.

Primero, instalemos peft, una biblioteca de Hugging Face que ayuda a aplicar LoRA fácilmente:

pip install peft

Ejemplo de Configuración LoRA en el Modelo

from peft import LoraConfig, get_peft_model

# Configuración básica de LoRA
config_lora = LoraConfig(
    r=8,                # Tamaño reducido para la parte que vamos a entrenar
    lora_alpha=32,      # Tasa de aprendizaje (controla qué tan rápido aprende el modelo)
    target_modules=["q_proj", "v_proj"],  # Las capas específicas a entrenar
    lora_dropout=0.1,   # Probabilidad de ignorar algunos valores (evita el sobreajuste)
    bias="none"         # No entrenamos el parámetro "bias" (para reducir más la memoria)
)

# Aplicamos LoRA al modelo ya cargado en 4 bits
modelo_lora = get_peft_model(modelo, config_lora)
modelo_lora.print_trainable_parameters()  # Ver los parámetros que estamos entrenando

LoRA nos permite entrenar solo las capas más importantes del modelo, las que realmente influencian el resultado final.

Google está desarrollando una IA que tomará el control del navegador web para completar tareas Google desarrolla una IA que tomará el control del navegador web

Esto significa que podemos entrenar sin que la GPU se quede sin memoria.

Paso 3: Preparación de los Datos

Preparación de los Datos

Necesitamos un conjunto de datos para entrenar el modelo. Imaginemos que vamos a usar el modelo para responder preguntas en un estilo de conversación similar al de Wikipedia.

Para esto, cargamos y preparamos datos de ejemplo.

Ejemplo de Preparación de Datos

from transformers import DataCollatorForLanguageModeling
from datasets import load_dataset

# Cargar un conjunto de datos de texto como Wikipedia
dataset = load_dataset("wikitext", "wikitext-2-raw-v1", split="train")

# Tokenización: Convertimos el texto a un formato que el modelo pueda entender
dataset = dataset.map(lambda e: tokenizer(e['text'], truncation=True, padding="max_length"), batched=True)

# Crear un "colacionador" que organiza los datos de entrada
data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)

Este ejemplo usa Wikitext, un conjunto de datos similar a la Wikipedia.

Lo tokenizamos para que el modelo pueda procesarlo más fácilmente.

Paso 4: Entrenamiento del Modelo

Entrenamiento del Modelo

Para entrenar el modelo, usamos un optimizador (AdamW) y configuramos algunos parámetros clave como el tamaño del lote (batch size) y el número de épocas (epochs).

Estos determinan cuántas veces el modelo verá cada dato para aprender mejor.

Ejemplo de Configuración de Entrenamiento

from transformers import Trainer, TrainingArguments

# Configuración del entrenamiento
args_entrenamiento = TrainingArguments(
    output_dir="./resultado_lora",
    per_device_train_batch_size=1,  # Tamaño de lote pequeño para no sobrecargar la memoria
    gradient_accumulation_steps=8,  # Acumular gradientes para reducir la memoria
    learning_rate=2e-4,
    num_train_epochs=3,  # Entrenar por 3 épocas
    logging_steps=10,
    fp16=True,  # Activar precisión en FP16 para reducir aún más la memoria
    optim="paged_adamw_32bit"  # Optimizador adaptado para modelos grandes
)

# Crear el objeto de entrenamiento con el modelo y los datos
trainer = Trainer(
    model=modelo_lora,
    args=args_entrenamiento,
    train_dataset=dataset,
    data_collator=data_collator
)

# Iniciar el entrenamiento
trainer.train()

En este paso, estamos entrenando el modelo en "modo FP16", una técnica que también reduce la cantidad de memoria utilizada al almacenar los datos en formato de 16 bits en lugar de 32 bits.

Explicación de los Parámetros

  • per_device_train_batch_size=1: Indica que el modelo verá un dato a la vez. Aunque es más lento, ayuda a que el modelo no ocupe toda la memoria de la GPU.
  • gradient_accumulation_steps=8: Acumula gradientes para procesarlos cada 8 pasos, reduciendo el uso de memoria.
  • num_train_epochs=3: Define cuántas veces el modelo revisará los datos completos para aprender de ellos.

Paso 5: Evaluar el Modelo

Para verificar que el modelo realmente aprendió, es importante evaluarlo y ver cómo responde en comparación con los datos de prueba.

resultados = trainer.evaluate()
print(resultados)

En definitiva, entrenar un LLM en una GPU de 16 GB puede ser complicado, pero con técnicas como QLoRA, que usa la cuantización en 4 bits y adaptación de baja dimensión (LoRA), es totalmente posible.

Estas técnicas reducen el consumo de memoria sin sacrificar el rendimiento del modelo, permitiéndonos entrenar y usar grandes modelos en equipos más modestos.

Ahora tienes una guía sencilla para empezar a entrenar modelos grandes de lenguaje en una GPU pequeña.

Con un poco de práctica, puedes aplicar estos conocimientos en otros proyectos de IA y personalizar modelos para aplicaciones específicas.

Una IA revela misterioso detalle oculto en una obra maestra de Rafael Una IA revela misterioso detalle oculto en una obra maestra de Rafael

¡Manos a la obra y descubre el potencial de los LLMs en tu proyecto!

Entradas Relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Tu puntuación: Útil

Subir