Los LLM han abierto innumerables nuevas oportunidades para aplicaciones de IA. Si alguna vez has querido ajustar tu propio modelo, esta guía te mostrará cómo hacerlo fácilmente y sin necesidad de escribir código. Utilizando herramientas como Axolotl y DPO, recorreremos el proceso paso a paso.
¿Qué es un LLM?
Un Modelo de Lenguaje Grande (LLM) es un potente modelo de IA entrenado en vastas cantidades de datos de texto, con decenas de billones de caracteres, para predecir el siguiente conjunto de palabras en una secuencia. Esto solo ha sido posible en los últimos 2-3 años gracias a los avances en la computación GPU, que han permitido entrenar modelos tan grandes en cuestión de unas pocas semanas.
Probablemente hayas interactuado con LLMs a través de productos como ChatGPT o Claude antes y hayas experimentado de primera mano su capacidad para entender y generar respuestas humanas.
¿Por qué ajustar un LLM?
¿No podemos simplemente usar GPT-4o para todo? Bueno, aunque es el modelo más potente que tenemos en el momento de escribir este artículo, no siempre es la elección más práctica. Ajustar un modelo más pequeño, que va desde 3 a 14 mil millones de parámetros, puede ofrecer resultados comparables a una fracción del costo. Además, el ajuste permite que seas dueño de tu propiedad intelectual y reduce tu dependencia de terceros.
Entendiendo los Modelos Base, Instruct y Chat
Antes de adentrarnos en el ajuste fino, es esencial entender los diferentes tipos de LLMs que existen:
- Modelos Base: Estos son preentrenados en grandes cantidades de texto no estructurado, como libros o datos de internet. Aunque tienen un entendimiento intrínseco del lenguaje, no están optimizados para inferencia y producirán resultados incoherentes. Los modelos base se desarrollan para servir como punto de partida para desarrollar modelos más especializados.
- Modelos Instructivos: Construidos sobre los modelos base, los modelos instructivos se ajustan usando datos estructurados como pares de instrucciones-respuestas. Están diseñados para seguir instrucciones específicas o responder preguntas.
- Modelos de Chat: También construidos sobre los modelos base, pero a diferencia de los modelos instructivos, los modelos de chat se entrenan con datos conversacionales, lo que les permite participar en diálogos de ida y vuelta.
¿Qué es el Aprendizaje por Refuerzo y DPO?
El Aprendizaje por Refuerzo (RL) es una técnica donde los modelos aprenden al recibir retroalimentación sobre sus acciones. Se aplica a modelos instructivos o de chat para refinar aún más la calidad de sus resultados. Típicamente, el RL no se realiza sobre modelos base, ya que utiliza una tasa de aprendizaje mucho más baja que no moverá la aguja lo suficiente.
DPO es una forma de RL donde el modelo se entrena usando pares de respuestas buenas y malas para el mismo prompt/conversación. Al presentar estos pares, el modelo aprende a favorecer los buenos ejemplos y evitar los malos.
Cuándo usar DPO
DPO es particularmente útil cuando deseas ajustar el estilo o comportamiento de tu modelo, por ejemplo:
- Ajustes de Estilo: Modificar la longitud de las respuestas, el nivel de detalle o el grado de confianza expresado por el modelo.
- Medidas de Seguridad: Entrenar el modelo para rechazar respuestas a solicitudes potencialmente inseguras o inapropiadas.
Sin embargo, DPO no es adecuado para enseñar al modelo nuevos conocimientos o hechos. Para ese propósito, las técnicas de Ajuste Fino Supervisado (SFT) o Generación Aumentada por Recuperación (RAG) son más apropiadas.
Creando un Conjunto de Datos DPO
En un entorno de producción, generalmente generarías un conjunto de datos DPO utilizando la retroalimentación de tus usuarios, por ejemplo:
- Retroalimentación del Usuario: Implementar un mecanismo de pulgar arriba/pulgar abajo en las respuestas.
- Elecciones Comparativas: Presentar a los usuarios con dos salidas diferentes y pedirles que elijan la mejor.
Si careces de datos de usuarios, también puedes crear un conjunto de datos sintético aprovechando modelos de lenguaje más grandes y capaces. Por ejemplo, puedes generar malas respuestas utilizando un modelo más pequeño y luego usar GPT-4 para corregirlas.
Para simplificar, utilizaremos un conjunto de datos ya preparado de HuggingFace: olivermolenschot/alpaca_messages_dpo_test. Si inspeccionas el conjunto de datos, notarás que contiene solicitudes con respuestas elegidas y rechazadas—estos son los buenos y malos ejemplos. Estos datos fueron creados sintéticamente utilizando GPT-3.5-turbo y GPT-4.
Generalmente necesitarás entre 500 y 1,000 pares de datos como mínimo para tener un entrenamiento efectivo sin sobreajuste. Los conjuntos de datos DPO más grandes contienen hasta 15,000–20,000 pares.
Ajuste Fino de Qwen2.5 3B Instruct con Axolotl
Usaremos Axolotl para ajustar el modelo Instruct Qwen2.5 3B, que actualmente ocupa el primer lugar en el OpenLLM Leaderboard para su clase de tamaño. Con Axolotl, puedes ajustar un modelo sin escribir una sola línea de código, solo un archivo de configuración YAML. A continuación se muestra el config.yml que utilizaremos:
base_model: Qwen/Qwen2.5-3B-Instruct
strict: false
# Axolotl will automatically map the dataset from HuggingFace to the prompt template of Qwen 2.5
chat_template: qwen_25
rl: dpo
datasets:
- path: olivermolenschot/alpaca_messages_dpo_test
type: chat_template.default
field_messages: conversation
field_chosen: chosen
field_rejected: rejected
message_field_role: role
message_field_content: content
# We pick a directory inside /workspace since that's typically where cloud hosts mount the volume
output_dir: /workspace/dpo-output
# Qwen 2.5 supports up to 32,768 tokens with a max generation of 8,192 tokens
sequence_len: 8192
# Sample packing does not currently work with DPO. Pad to sequence length is added to avoid a Torch bug
sample_packing: false
pad_to_sequence_len: true
# Add your WanDB account if you want to get nice reporting on your training performance
wandb_project:
wandb_entity:
wandb_watch:
wandb_name:
wandb_log_model:
# Can make training more efficient by batching multiple rows together
gradient_accumulation_steps: 1
micro_batch_size: 1
# Do one pass on the dataset. Can set to a higher number like 2 or 3 to do multiple
num_epochs: 1
# Optimizers don't make much of a difference when training LLMs. Adam is the standard
optimizer: adamw_torch
# DPO requires a smaller learning rate than regular SFT
lr_scheduler: constant
learning_rate: 0.00005
# Train in bf16 precision since the base model is also bf16
bf16: auto
# Reduces memory requirements
gradient_checkpointing: true
# Makes training faster (only suported on Ampere, Ada, or Hopper GPUs)
flash_attention: true
# Can save multiple times per epoch to get multiple checkpoint candidates to compare
saves_per_epoch: 1
logging_steps: 1
warmup_steps: 0
Configurando el Entorno en la Nube
Para ejecutar el entrenamiento, utilizaremos un servicio de alojamiento en la nube como Runpod o Vultr. Esto es lo que necesitarás:
- Imagen de Docker: Clona la imagen de Docker winglian/axolotl-cloud:main proporcionada por el equipo de Axolotl.
- *Requisitos de Hardware: Una GPU de 80GB de VRAM (como un nodo 1×A100 PCIe) será más que suficiente para este tamaño de modelo.
- Almacenamiento: 200GB de almacenamiento en volumen para acomodar todos los archivos que necesitamos.
- Versión de CUDA: Tu versión de CUDA debe ser al menos 12.1.
*Este tipo de entrenamiento se considera un ajuste completo del LLM, y por lo tanto es muy intensivo en VRAM. Si deseas ejecutar un entrenamiento localmente, sin depender de hosts en la nube, podrías intentar usar QLoRA, que es una forma de ajuste fino supervisado. Aunque es teóricamente posible combinar DPO y QLoRA, esto se hace muy raramente.
Pasos para Comenzar el Entrenamiento
- Configurar el Directorio de Caché de HuggingFace:
export HF_HOME=/workspace/hf
Esto asegura que el modelo original se descargue en nuestro almacenamiento en volumen que es persistente.
- Crear Archivo de Configuración: Guarda el archivo config.yml que creamos anteriormente en /workspace/config.yml.
- Comenzar Entrenamiento:
python -m axolotl.cli.train /workspace/config.yml
¡Y voilà! Tu entrenamiento debería comenzar. Después de que Axolotl descargue el modelo y los datos de entrenamiento, deberías ver una salida similar a esta:
[2024-12-02 11:22:34,798] [DEBUG] [axolotl.train.train:98] [PID:3813] [RANK:0] loading model
[2024-12-02 11:23:17,925] [INFO] [axolotl.train.train:178] [PID:3813] [RANK:0] Starting trainer...
El entrenamiento debería completarse en solo unos minutos, ya que se trata de un conjunto de datos pequeño de solo 264 filas. El modelo afinado se guardará en /workspace/dpo-output.
Subir el modelo a HuggingFace
Puedes subir tu modelo a HuggingFace utilizando la CLI:
- Instalar la CLI de HuggingFace Hub:
pip install huggingface_hub[cli]
- Subir el modelo:
huggingface-cli upload /workspace/dpo-output yourname/yourrepo
Reemplaza tu-nombre/tu-repositorio con tu nombre de usuario y nombre de repositorio reales de HuggingFace.
Evaluación de tu modelo afinado
Para la evaluación, se recomienda alojar tanto los modelos originales como los modelos afinados utilizando una herramienta como Inferencia de Generación de Texto (TGI). Luego, realiza inferencias en ambos modelos con una configuración de temperatura de 0 (para garantizar salidas determinísticas) y compara manualmente las respuestas de los dos modelos.
Este enfoque práctico proporciona una mejor comprensión que depender únicamente de las métricas de pérdida de evaluación del entrenamiento, que pueden no capturar los matices de la generación de lenguaje en los LLM.
Conclusión
El ajuste fino de un LLM utilizando DPO te permite personalizar modelos para adaptarlos mejor a las necesidades de tu aplicación, todo mientras mantienes los costos manejables. Siguiendo los pasos descritos en este artículo, puedes aprovechar el poder de las herramientas y conjuntos de datos de código abierto para crear un modelo que se alinee con tus requisitos específicos. Ya sea que busques ajustar el estilo de las respuestas o implementar medidas de seguridad, DPO ofrece un enfoque práctico para refinar tu LLM.
¡Feliz ajuste fino!
Source:
https://www.sitepoint.com/fine-tuning-llm-with-direct-preference-optimization-dpo/