Si quieres hacer fine tuning a un modelo de lenguaje sin depender de la nube cerrada de OpenAI ni alquilar cientos de GPUs, LoRA es la técnica que necesitas conocer. Permite reentrenar modelos open source grandes con recursos modestos, incluso desde una cuenta gratuita de Google Colab.
¿Qué es LoRA y qué problema resuelve en el fine tuning?
LoRA significa Low Rank Adaptation y nace para resolver un dolor concreto: los modelos modernos crecen en decenas de miles de millones de parámetros y reentrenarlos completos es inviable [3:30].
En un fine tuning supervisado clásico tendrías que tocar todos los pesos del modelo. En GPT-4, por ejemplo, eso significa cerca de un trillón de parámetros y miles de GPUs trabajando. LoRA propone reentrenar solo partes pequeñas del modelo, congelando la matriz de pesos original y añadiendo matrices reducidas que sí se entrenan [4:30].
¿Qué hace LoRA exactamente? Congela la matriz de pesos original del modelo y entrena una matriz nueva mucho más pequeña basada en un rank bajo. Al final combina ambas para que el modelo aprenda con tus datos sin tocar los billones de parámetros originales.
¿Cómo funciona la hipótesis del rango intrínseco?
La idea central detrás de LoRA es la intrinsic rank hypothesis: no necesitas reentrenar el modelo completo para que capte cambios significativos a partir de tus datos [5:25].
La matriz de pesos típica de un LLM tiene tamaño D x D, por ejemplo 100 mil por 100 mil, lo que da 10 billones de parámetros. LoRA reemplaza ese entrenamiento por una matriz R x D, donde R es un rango bajo que tú eliges. Si pones R en 3, pasas de 10 billones a 300 mil parámetros entrenables [7:30].
Eso reduce dos cosas a la vez:
- La memoria de GPU necesaria para entrenar.
- El tiempo de cómputo por cada operación.
- El tamaño final del modelo entrenado, que pasa de gigas a megabytes.
¿Por qué los adaptadores LoRA pesan tan poco?
Porque cada adaptador es básicamente un par de matrices reducidas que se enchufan al modelo base. Puedes tener un modelo preentrenado y varios adaptadores entrenados con datasets distintos, cargando el que necesites según el caso de uso [8:35].
¿Cómo aplicar LoRA con PEFT y Hugging Face en Colab?
Para el ejercicio práctico se usa la librería Parameter Efficient Fine Tuning (PEFT) de Hugging Face, que ahorra mucho código repetitivo [9:30].
El modelo base elegido es Microsoft Phi-3 Mini 4K Instruct, con 3,82 billones de parámetros. Los modelos con la etiqueta Instruct funcionan mejor como base de fine tuning porque ya están preparados para recibir entrenamiento adicional [10:30].
La instancia recomendada en Colab gratuito es la T4 con 15 GB de GPU, suficiente para este modelo si lo cargas cuantizado [11:35].
¿Qué librerías necesitas instalar?
- transformers y peft de Hugging Face.
- torch para mover tensores al device.
- bitsandbytes para cargar el modelo cuantizado en 4 bits.
- Librerías de CUDA que aprovechan la GPU automáticamente.
La configuración de cuantización se hace con BitsAndBytesConfig indicando carga en 4 bits, doble cuantización y bfloat16 como tipo de dato base, valor que sale del model card de Hugging Face [13:50].
¿Qué hiperparámetros importan al configurar LoRA?
Después de cargar el modelo y prepararlo con prepare_model_for_kbit_training, configuras LoRA con la clase LoraConfig [17:40]. Los hiperparámetros se eligen por prueba y error, no hay fórmula mágica.
- r: el rango de la matriz reducida. En el ejemplo se usa 8.
- lora_alpha: multiplicador similar a un learning rate de adaptación. La regla práctica es 2 por R, así que queda en 16.
- lora_dropout: porcentaje de neuronas que se apagan aleatoriamente para evitar memorización. Aquí, 5%.
- bias: configurado en none, aunque puedes experimentar.
- task_type:
CAUSAL_LM porque la mayoría de LLMs son causales.
- target_modules: las capas donde se inyecta LoRA, como o_proj, qkv_proj, gate_proj, up_proj y down_proj.
Al aplicar get_peft_model, el modelo crece unos 400 MB, pasando de 2200 MB a 2600 MB [20:30]. De los 3833 millones de parámetros totales, solo se entrenan 12 millones, equivalentes al 0,33% [21:00]. El 99,7% restante queda congelado.
¿Cuántos parámetros entrena LoRA en este ejemplo? 12 millones de un total de 3.833 millones. Eso es el 0,33% del modelo, lo que confirma por qué LoRA es tan eficiente en memoria y tiempo.
¿Cómo preparar el dataset y entrenar el modelo?
El dataset usado se llama Yoda Sentences, de DV Godoy, con 720 ejemplos que traducen frases en inglés al estilo de Yoda de Star Wars [22:30].
Las columnas se renombran a prompt y completion, formato que PEFT espera, similar al de la API de OpenAI. Después se mapea cada registro a una lista de mensajes con roles user y assistant [23:40].
Cada modelo tiene su propio tokenizer y su chat template. Se carga con AutoTokenizer.from_pretrained y se aplica al dataset para que el LLM reciba las etiquetas que entiende internamente [24:45].
¿Qué configuración de SFT funciona en Colab gratuito?
La clase SFTConfig reúne los parámetros de entrenamiento. Estos son los más relevantes para que entre en una T4:
gradient_checkpointing=True para guardar gradientes en RAM y no en GPU.
gradient_accumulation_steps para controlar cada cuánto se ejecuta backpropagation.
per_device_train_batch_size=16, el doble que en OpenAI por estrategia local.
auto_find_batch_size=True para que el sistema ajuste si la GPU no aguanta.
max_seq_length=64 tokens, suficiente para frases cortas tipo Yoda.
num_train_epochs=10 y learning_rate=0.00043.
optim="paged_adamw_8bit", optimizador eficiente en memoria.
El entrenamiento real toma 25 minutos y 47 segundos en Colab gratuito [29:50]. El training loss arranca en 2,98 y baja hasta 0,58 en la iteración 110, señal clara de que el modelo está aprendiendo.
¿Cómo hacer inferencia con tu modelo LoRA entrenado?
La función encode_prompt envuelve la frase en el template del modelo. La función de inferencia tokeniza el prompt, mueve los tensores al device cuda:0, pone el modelo en modo eval y llama a model.generate con el ID de fin de sentencia [31:30].
Los tokens de salida se convierten a texto con tokenizer.batch_decode. Probando con The force is strong in you, el modelo responde Strong in you the force is, justo como hablaría Yoda [33:30].
Finalmente guardas el resultado como adaptador con trainer.save_model("phi3-mini-yoda-adapter"). Ese archivo es lo que en Hugging Face aparece bajo la categoría adapters, y pesa muchísimo menos que el modelo completo.
¿Con qué dataset propio probarías tu primer adaptador LoRA? Cuéntame en los comentarios qué caso de uso te gustaría entrenar.