Modelos y plataformas de IA
La única guía que necesitas para afinar Llama 3 o cualquier otro modelo de código abierto
El afinamiento de grandes modelos de lenguaje (LLM) como Llama 3 implica adaptar un modelo preentrenado a tareas específicas utilizando un conjunto de datos específico del dominio. Este proceso aprovecha el conocimiento preexistente del modelo, lo que lo hace eficiente y rentable en comparación con el entrenamiento desde cero. En esta guía, pasaremos por los pasos para afinar Llama 3 utilizando QLoRA (Quantized LoRA), un método eficiente en parámetros que minimiza el uso de memoria y los costos computacionales.
Visión general del afinamiento
El afinamiento implica varios pasos clave:
- Selección de un modelo preentrenado: Elija un modelo base que se alinee con la arquitectura deseada.
- Recopilación de un conjunto de datos relevante: Recopile y preprocese un conjunto de datos específico de la tarea.
- Afinamiento: Ajuste el modelo utilizando el conjunto de datos para mejorar su rendimiento en tareas específicas.
- Evaluación: Evalúe el modelo afinado utilizando métricas cualitativas y cuantitativas.
Conceptos y técnicas
Afinamiento completo
Afinamiento completo actualiza todos los parámetros del modelo, haciéndolo específico de la nueva tarea. Este método requiere recursos computacionales significativos y a menudo es impráctico para modelos muy grandes.
Afinamiento eficiente en parámetros (PEFT)
PEFT actualiza solo un subconjunto de los parámetros del modelo, reduciendo los requisitos de memoria y costo computacional. Esta técnica evita el olvido catastrófico y mantiene el conocimiento general del modelo.
Adaptación de bajo rango (LoRA) y QLoRA
LoRA afina solo unas pocas matrices de bajo rango, mientras que QLoRA cuantiza estas matrices para reducir aún más la huella de memoria.
Métodos de afinamiento
- Afinamiento completo: Esto implica entrenar todos los parámetros del modelo en el conjunto de datos de la tarea. Si bien este método puede ser muy efectivo, también es computacionalmente costoso y requiere mucha memoria.
- Afinamiento eficiente en parámetros (PEFT): PEFT actualiza solo un subconjunto de los parámetros del modelo, lo que lo hace más eficiente en términos de memoria. Técnicas como LoRA y QLoRA caen en esta categoría.
¿Qué es LoRA?

Comparación de métodos de afinamiento: QLORA mejora LoRA con cuantización de precisión de 4 bits y optimizadores de páginas para gestión de picos de memoria
LoRA es un método de afinamiento mejorado en el que, en lugar de afinar todos los pesos del modelo preentrenado, se afinan dos matrices más pequeñas que aproximan la matriz más grande. Estas matrices constituyen el adaptador LoRA. Este adaptador afinado se carga luego en el modelo preentrenado y se utiliza para inferencia.
Ventajas clave de LoRA:
- Eficiencia de memoria: LoRA reduce la huella de memoria al afinar solo matrices pequeñas en lugar de todo el modelo.
- Reutilización: El modelo original permanece sin cambios, y se pueden utilizar varios adaptadores LoRA con él, lo que facilita el manejo de múltiples tareas con requisitos de memoria más bajos.
¿Qué es QLoRA?
QLoRA lleva a LoRA un paso más allá cuantizando los pesos de los adaptadores LoRA a una precisión más baja (por ejemplo, 4 bits en lugar de 8 bits). Esto reduce aún más el uso de memoria y los requisitos de almacenamiento, mientras mantiene un nivel comparable de efectividad.
Ventajas clave de QLoRA:
- Mayor eficiencia de memoria: Al cuantizar los pesos, QLoRA reduce significativamente los requisitos de memoria y almacenamiento del modelo.
- Mantiene el rendimiento: A pesar de la precisión reducida, QLoRA mantiene niveles de rendimiento cercanos a los de los modelos de precisión completa.
Adaptación específica de la tarea
Durante el afinamiento, los parámetros del modelo se ajustan en función del nuevo conjunto de datos, lo que ayuda al modelo a comprender y generar contenido relevante para la tarea específica. Este proceso mantiene el conocimiento general del lenguaje adquirido durante el preentrenamiento, mientras adapta el modelo a las peculiaridades del dominio objetivo.
Afinamiento en la práctica
Afinamiento completo vs. PEFT
- Afinamiento completo: Implica entrenar todo el modelo, lo que puede ser computacionalmente costoso y requiere mucha memoria.
- PEFT (LoRA y QLoRA): Afinar solo un subconjunto de parámetros, reduciendo los requisitos de memoria y previniendo el olvido catastrófico, lo que lo hace una alternativa más eficiente.
Pasos de implementación
- Configuración del entorno: Instalar bibliotecas necesarias y configurar el entorno de cómputo.
- Carga y preprocesamiento del conjunto de datos: Cargar el conjunto de datos y preprocesarlo en un formato adecuado para el modelo.
- Carga del modelo preentrenado: Cargar el modelo base con configuraciones de cuantización si se utiliza QLoRA.
- Tokenización: Tokenizar el conjunto de datos para prepararlo para el entrenamiento.
- Entrenamiento: Afinar el modelo utilizando el conjunto de datos preparado.
- Evaluación: Evaluar el rendimiento del modelo en tareas específicas utilizando métricas cualitativas y cuantitativas.
Guía paso a paso para afinar LLM
Configuración del entorno
Utilizaremos un cuaderno Jupyter para este tutorial. Plataformas como Kaggle, que ofrecen uso gratuito de GPU, o Google Colab son ideales para ejecutar estos experimentos.
1. Instalar bibliotecas requeridas
Primero, asegúrese de tener las bibliotecas necesarias instaladas:
!pip install -qqq -U bitsandbytes transformers peft accelerate datasets scipy einops evaluate trl rouge_score
2. Importar bibliotecas y configurar el entorno
import os import torch from datasets import load_dataset from transformers import ( AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments, pipeline, HfArgumentParser ) from trl import ORPOConfig, ORPOTrainer, setup_chat_format, SFTTrainer from tqdm import tqdm import gc import pandas as pd import numpy as np from huggingface_hub import interpreter_login # Deshabilitar registro de Weights and Biases os.environ['WANDB_DISABLED'] = "true" interpreter_login()
3. Cargar el conjunto de datos
Utilizaremos el conjunto de datos DialogSum para este tutorial:
dataset_name = "neil-code/dialogsum-test" dataset = load_dataset(dataset_name)
4. Crear configuración de BitsAndBytes
Para cargar el modelo en formato de 4 bits:
compute_dtype = getattr(torch, "float16") bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type='nf4', bnb_4bit_compute_dtype=compute_dtype, bnb_4bit_use_double_quant=False, )
5. Cargar el modelo preentrenado
Utilizando el modelo Phi-2 de Microsoft (MSFT ) para este tutorial:
model_name = 'microsoft/phi-2'
device_map = {"": 0}
original_model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map=device_map,
quantization_config=bnb_config,
trust_remote_code=True,
use_auth_token=True
)
6. Tokenización
Configurar el tokenizador:
tokenizer = AutoTokenizer.from_pretrained( model_name, trust_remote_code=True, padding_side="left", add_eos_token=True, add_bos_token=True, use_fast=False ) tokenizer.pad_token = tokenizer.eos_token
Afinar Llama 3 o otros modelos
Al afinar modelos como Llama 3 u otros modelos de código abierto de última generación, hay consideraciones y ajustes específicos que se deben realizar para garantizar un rendimiento óptimo. A continuación, se presentan los pasos detallados y las consideraciones para afinar estos modelos, incluidos Llama 3, GPT-3 y Mistral.
5.1 Utilizando Llama 3
Selección del modelo:
- Asegúrese de tener el identificador de modelo correcto desde el hub de modelos de Hugging Face. Por ejemplo, el modelo Llama 3 podría estar identificado como
meta-llama/Meta-Llama-3-8Ben Hugging Face. - Asegúrese de solicitar acceso y iniciar sesión en su cuenta de Hugging Face si es necesario para modelos como Llama 3.
Tokenización:
- Utilice el tokenizador adecuado para Llama 3, asegurándose de que sea compatible con el modelo y admita las características necesarias como relleno y tokens especiales.
Memoria y cálculo:
- Afinar modelos grandes como Llama 3 requiere recursos computacionales significativos. Asegúrese de que su entorno, como una configuración de GPU potente, pueda manejar los requisitos de memoria y procesamiento.
5.2 Utilizando otros modelos populares (por ejemplo, GPT-3, Mistral)
Selección del modelo:
- Para modelos como GPT-3 y Mistral, asegúrese de utilizar el nombre y el identificador del modelo correctos desde el hub de modelos de Hugging Face o otras fuentes.
7. Probar el modelo con inferencia de disparo cero
Evalúe el modelo base con una entrada de ejemplo:
from transformers import set_seed
set_seed(42)
index = 10
prompt = dataset['test'][index]['dialogue']
formatted_prompt = f"Instruct: Resumir la siguiente conversación.\n{prompt}\nOutput:\n"
# Generar salida
def gen(model, prompt, max_length):
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_length=max_length)
return tokenizer.batch_decode(outputs, skip_special_tokens=True)
res = gen(original_model, formatted_prompt, 100)
output = res[0].split('Output:\n')[1]
print(f'INPUT PROMPT:\n{formatted_prompt}')
print(f'MODELO GENERACIÓN - DISPARO CERO:\n{output}')
8. Preprocesar el conjunto de datos
Convertir pares de diálogo-resumen en prompts:
def create_prompt_formats(sample):
blurb = "A continuación, se describe una tarea. Escriba una respuesta que complete adecuadamente la solicitud."
instruction = "### Instruct: Resumir la conversación a continuación."
input_context = sample['dialogue']
response = f"### Output:\n{sample['summary']}"
end = "### End"
parts = [blurb, instruction, input_context, response, end]
formatted_prompt = "\n\n".join(parts)
sample["text"] = formatted_prompt
return sample
dataset = dataset.map(create_prompt_formats)
Tokenizar el conjunto de datos formateado:
def preprocess_batch(batch, tokenizer, max_length): return tokenizer(batch["text"], max_length=max_length, truncation=True) max_length = 1024 train_dataset = dataset["train"].map(lambda batch: preprocess_batch(batch, tokenizer, max_length), batched=True) eval_dataset = dataset["validation"].map(lambda batch: preprocess_batch(batch, tokenizer, max_length), batched=True)
Parámetros y su impacto
Los hiperparámetros juegan un papel crucial en la optimización del rendimiento del modelo. A continuación, se presentan algunos hiperparámetros clave que se deben considerar:
- Tasa de aprendizaje: Controla la velocidad a la que el modelo actualiza sus parámetros. Una tasa de aprendizaje alta puede llevar a una convergencia más rápida, pero puede pasar por alto la solución óptima. Una tasa de aprendizaje baja garantiza una convergencia estable, pero puede requerir más épocas.
- Tamaño del lote: El número de muestras procesadas antes de que el modelo actualice sus parámetros. Tamaños de lote más grandes pueden mejorar la estabilidad, pero requieren más memoria. Tamaños de lote más pequeños pueden generar más ruido en el proceso de entrenamiento.
- Pasos de acumulación de gradientes: Este parámetro ayuda a simular tamaños de lote más grandes acumulando gradientes durante varios pasos antes de realizar una actualización de parámetros.
- Número de épocas: El número de veces que se pasa el conjunto de datos completo a través del modelo. Más épocas pueden mejorar el rendimiento, pero pueden llevar a sobreajuste si no se gestionan adecuadamente.
- Decaimiento de peso: Técnica de regularización para prevenir el sobreajuste, penalizando los pesos grandes.
- Programador de tasa de aprendizaje: Ajusta la tasa de aprendizaje durante el entrenamiento para mejorar el rendimiento y la convergencia.
Personalice la configuración de entrenamiento ajustando hiperparámetros como la tasa de aprendizaje, el tamaño del lote y los pasos de acumulación de gradientes según los requisitos específicos del modelo y la tarea. Por ejemplo, los modelos Llama 3 pueden requerir diferentes tasas de aprendizaje en comparación con modelos más pequeños.
Ejemplo de configuración de entrenamiento
orpo_args = ORPOConfig( learning_rate=8e-6, lr_scheduler_type="linear", max_length=1024, max_prompt_length=512, beta=0.1, per_device_train_batch_size=2, per_device_eval_batch_size=2, gradient_accumulation_steps=4, optim="paged_adamw_8bit", num_train_epochs=1, evaluation_strategy="steps", eval_steps=0.2, logging_steps=1, warmup_steps=10, report_to="wandb", output_dir="./results/", )
10. Entrenar el modelo
Configure el entrenador y comience el entrenamiento:
trainer = ORPOTrainer(
model=original_model,
args=orpo_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
tokenizer=tokenizer,
)
trainer.train()
trainer.save_model("fine-tuned-llama-3")
Evaluación del modelo afinado
Después del entrenamiento, evalúe el rendimiento del modelo utilizando métodos cualitativos y cuantitativos.
1. Evaluación humana
Compare las resúmenes generados con los escritos por humanos para evaluar la calidad.
2. Evaluación cuantitativa
Utilice métricas como ROUGE para evaluar el rendimiento:
from rouge_score import rouge_scorer scorer = rouge_scorer.RougeScorer(['rouge1', 'rouge2', 'rougeL'], use_stemmer=True) scores = scorer.score(reference_summary, generated_summary) print(scores)
Desafíos comunes y soluciones
1. Limitaciones de memoria
Utilizar QLoRA ayuda a mitigar los problemas de memoria al cuantizar los pesos del modelo a 4 bits. Asegúrese de tener suficiente memoria de GPU para manejar el tamaño del lote y el tamaño del modelo.
2. Sobreajuste
Monitoree las métricas de validación para prevenir el sobreajuste. Utilice técnicas como detención temprana y decaimiento de peso.
3. Entrenamiento lento
Optimice la velocidad de entrenamiento ajustando el tamaño del lote, la tasa de aprendizaje y utilizando la acumulación de gradientes.
4. Calidad de los datos
Asegúrese de que su conjunto de datos esté limpio y bien preprocesado. La mala calidad de los datos puede afectar significativamente el rendimiento del modelo.
Conclusión
Afinar LLM utilizando QLoRA es una forma eficiente de adaptar modelos preentrenados grandes a tareas específicas con costos computacionales reducidos. Siguiendo esta guía, puede afinar PHI, Llama 3 o cualquier otro modelo de código abierto para lograr un alto rendimiento en sus tareas específicas.













