Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions chapters/es/_toctree.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,21 @@
- local: chapter8/2
title: ¿Qué hacer cuando se produce un error?

- title: 12. Construir modelos de razonamiento
subtitle: Aprende a construir modelos de razonamiento como DeepSeek R1
new: true
sections:
- local: chapter12/4
title: Implementación de GRPO en TRL
- local: chapter12/5
title: Ejercicio práctico para ajustar un modelo con GRPO
- local: chapter12/6
title: Ejercicio práctico con Unsloth
- local: chapter12/7
title: Próximamente...

- title: Glosario
sections:
- local: glossary/1
title: Glosario

224 changes: 224 additions & 0 deletions chapters/es/chapter12/4.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
# Implementación de GRPO en TRL[[implementacion-de-grpo-en-trl]]

En esta página aprenderemos a implementar Group Relative Policy Optimization (GRPO) utilizando la librería Transformer Reinforcement Learning (TRL). Nos centraremos en la implementación práctica con una cantidad mínima de código.

Exploraremos los conceptos centrales de GRPO tal como se incorporan en el `GRPOTrainer` de TRL, utilizando fragmentos de la documentación oficial de TRL como guía.

> [!TIP]
> Este capítulo está dirigido a principiantes en TRL. Si ya estás familiarizado con TRL, quizás también quieras consultar la [implementación de Open R1](https://github.com/huggingface/open-r1/blob/main/src/open_r1/grpo.py) de GRPO.

En primer lugar, recordemos algunos de los conceptos importantes del algoritmo GRPO:

- Formación de grupos: El modelo genera múltiples terminaciones para cada prompt.
- Aprendizaje de preferencias: El modelo aprende de una función de recompensa que compara grupos de terminaciones.
- Configuración del entrenamiento: El modelo utiliza una configuración para controlar el proceso de entrenamiento.

¿Qué necesitamos hacer para implementar GRPO?

- Definir un conjunto de datos de prompts.
- Definir una función de recompensa que tome una lista de terminaciones y devuelva una lista de recompensas.
- Configurar el proceso de entrenamiento con un `GRPOConfig`.
- Entrenar el modelo utilizando el `GRPOTrainer`.

Aquí tienes un ejemplo mínimo para comenzar con el entrenamiento de GRPO:

```python
from trl import GRPOTrainer, GRPOConfig
from datasets import load_dataset

# 1. Cargar tu conjunto de datos
dataset = load_dataset("your_dataset", split="train")


# 2. Definir una función de recompensa simple
def reward_func(completions, **kwargs):
"""Ejemplo: Recompensar terminaciones más largas"""
return [float(len(completion)) for completion in completions]


# 3. Configurar el entrenamiento
training_args = GRPOConfig(
output_dir="output",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=2,
logging_steps=10,
)

# 4. Inicializar y entrenar
trainer = GRPOTrainer(
model="your_model", # ej. "Qwen/Qwen2-0.5B-Instruct"
args=training_args,
train_dataset=dataset,
reward_funcs=reward_func,
)
trainer.train()
```

## Componentes clave

### 1. Formato del conjunto de datos

Tu conjunto de datos debe contener prompts a los que responderá el modelo. El entrenador de GRPO generará múltiples terminaciones para cada prompt y utilizará la función de recompensa para compararlas.

### 2. Función de recompensa

La función de recompensa es crucial: determina cómo aprende el modelo. Aquí hay dos ejemplos prácticos:

```python
# Ejemplo 1: Recompensa basada en la longitud de la terminación
def reward_length(completions, **kwargs):
return [float(len(completion)) for completion in completions]


# Ejemplo 2: Recompensa basada en coincidir con un patrón
import re


def reward_format(completions, **kwargs):
pattern = r"^<think>.*?</think><answer>.*?</answer>$"
return [1.0 if re.match(pattern, c) else 0.0 for c in completions]
```

### 3. Configuración del entrenamiento

Parámetros clave a considerar en `GRPOConfig`:

```python
training_args = GRPOConfig(
# Parámetros esenciales
output_dir="output",
num_train_epochs=3,
num_generations=4, # Número de terminaciones a generar para cada prompt
per_device_train_batch_size=4, # Queremos obtener todas las generaciones en un lote por dispositivo
# Opcionales pero útiles
gradient_accumulation_steps=2,
learning_rate=1e-5,
logging_steps=10,
# Específicos de GRPO (opcionales)
use_vllm=True, # Acelerar la generación
)
```

El parámetro `num_generations` es particularmente importante para GRPO ya que define el tamaño del grupo: cuántas terminaciones diferentes generará el modelo para cada prompt. Este es un diferenciador clave de otros métodos de RL:

- Demasiado pequeño (ej., 2-3): Puede no proporcionar suficiente diversidad para comparaciones significativas
- Recomendado (4-16): Proporciona un buen equilibrio entre diversidad y eficiencia computacional
- Valores mayores: Pueden mejorar el aprendizaje pero aumentan significativamente el costo computacional

El tamaño del grupo debe elegirse según tus recursos computacionales y la complejidad de tu tarea. Para tareas simples, grupos más pequeños (4-8) pueden ser suficientes, mientras que tareas de razonamiento más complejas podrían beneficiarse de grupos más grandes (8-16).

## Consejos para el éxito

1. **Gestión de memoria**: Ajusta `per_device_train_batch_size` y `gradient_accumulation_steps` en función de la memoria de tu GPU.
2. **Velocidad**: Habilita `use_vllm=True` para una generación más rápida si tu modelo es compatible.
3. **Monitoreo**: Observa las métricas registradas durante el entrenamiento:
- `reward`: Recompensa promedio en todas las terminaciones
- `reward_std`: Desviación estándar dentro de los grupos de recompensa
- `kl`: Divergencia KL del modelo de referencia

## Diseño de funciones de recompensa

El artículo de DeepSeek R1 demuestra varios enfoques eficaces para el diseño de funciones de recompensa que puedes adaptar para tu propia implementación de GRPO:

### 1. Recompensas basadas en la longitud

Una de las recompensas más fáciles de implementar es una recompensa basada en la longitud. Puedes penalizar terminaciones demasiado cortas o demasiado largas:

```python
def reward_len(completions, **kwargs):
ideal_length = 20
return [-abs(ideal_length - len(completion)) for completion in completions]
```

Esta función de recompensa penaliza las terminaciones que son demasiado cortas o demasiado largas, animando al modelo a generar respuestas cercanas a la longitud ideal de 20 tokens.

<iframe
src="https://marimo.app/gh/huggingface/notebooks/main/e?entrypoint=course%2Fen%2Fchapter13%2Fgrpo_length.py&embed=true&show-chrome=false"
title="Marimo Notebook"
width="100%"
height="800px"
frameBorder="0"
allow="clipboard-write"
></iframe>

## 2. Recompensas basadas en reglas para tareas verificables

Para tareas con respuestas objetivamente correctas (como matemáticas o programación), puedes implementar funciones de recompensa basadas en reglas:

```python
def problem_reward(completions, answers, **kwargs):
"""Función de recompensa para problemas matemáticos con respuestas verificables
completions: lista de terminaciones a evaluar
answers: lista de respuestas a los problemas del conjunto de datos
"""

rewards = []
for completion, correct_answer in zip(completions, answers):
# Extraer la respuesta de la terminación
try:
# Este es un ejemplo simplificado; necesitarías un análisis adecuado
answer = extract_final_answer(completion)
# Recompensa binaria: 1 para correcta, 0 para incorrecta
reward = 1.0 if answer == correct_answer else 0.0
rewards.append(reward)
except:
# Si no podemos analizar una respuesta, otorgamos una recompensa baja
rewards.append(0.0)

return rewards
```

<iframe
src="https://marimo.app/gh/huggingface/notebooks/main/e?entrypoint=course%2Fen%2Fchapter13%2Fgrpo_math.py&embed=true&show-chrome=false"
title="Marimo Notebook"
width="100%"
height="800px"
frameBorder="0"
allow="clipboard-write"
></iframe>

## 3. Recompensas basadas en formato

También puedes recompensar el formato adecuado, lo cual fue importante en el entrenamiento de DeepSeek R1:

```python
def format_reward(completions, **kwargs):
"""Recompensar las terminaciones que siguen el formato deseado"""
# Ejemplo: Comprobar si la terminación sigue un formato pensar-luego-responder
pattern = r"<think>(.*?)</think>\s*<answer>(.*?)</answer>"

rewards = []
for completion in completions:
match = re.search(pattern, completion, re.DOTALL)
if match:
# Comprobar si hay contenido sustancial en ambas secciones
think_content = match.group(1).strip()
answer_content = match.group(2).strip()

if len(think_content) > 20 and len(answer_content) > 0:
rewards.append(1.0)
else:
rewards.append(
0.5
) # Recompensa parcial por formato correcto pero contenido limitado
else:
rewards.append(0.0) # Sin recompensa por formato incorrecto

return rewards
```

<iframe
src="https://marimo.app/gh/huggingface/notebooks/main/e?entrypoint=course%2Fen%2Fchapter13%2Fgrpo_format.py&embed=true&show-chrome=false"
title="Marimo Notebook"
width="100%"
height="800px"
frameBorder="0"
allow="clipboard-write"
></iframe>

Estos ejemplos demuestran cómo puedes implementar funciones de recompensa inspiradas en el proceso de entrenamiento de DeepSeek R1, centrándote en la corrección, el formato y las señales combinadas.

## ¡Eso es todo!

En la siguiente sección, realizarás un ejercicio para implementar GRPO en TRL.
Loading
Loading