Inicio / Artículos

Explicación del ajuste fino de GRPO: Enseñando a un LLM local a razonar

GRPO descarta la crítica de PPO y aprende a partir de comparaciones grupales. Se explican las cinco cantidades fundamentales, las funciones de recompensa y un breve script de entrenamiento para Unsloth y TRL.

Editor: REACTAPP.TOP11 min de lectura2471 palabras

Fuentes: Creating Reasoning Models with GRPO Finetuning

Los modelos centrados en el razonamiento, como DeepSeek-R1, han atraído mucha atención, y ahora muchas personas desean que un modelo más pequeño que puedan ejecutar por sí mismos tenga el mismo comportamiento. La técnica generalmente atribuida a esto es el ajuste fino GRPO. El ajuste fino supervisado (SFT) enseña a un modelo a imitar patrones en ejemplos. La Optimización de Políticas Relativas por Grupos (GRPO) utiliza el aprendizaje por refuerzo para guiar a un modelo hacia respuestas que realmente funcionen, lo cual está más cerca de enseñarle cómo pensar que cómo sonar.

Este artículo explica cuál es el lugar de GRPO entre los métodos RLHF, qué significan sus cinco cantidades clave y cómo se convierten en unas pocas decenas de líneas de código de entrenamiento.

El lugar de GRPO entre los métodos de ajuste por preferencias

RLHF, el aprendizaje por refuerzo a partir de retroalimentación humana, debe considerarse más bien como un término genérico. PPO, GRPO y DPO son optimizadores diferentes que apuntan al mismo objetivo: ajustar un modelo de acuerdo a lo que prefieren las personas.

Una comparación culinaria ayuda a entenderlo. RLHF consiste en mejorar un plato probándolo y haciendo ajustes. PPO es una receta más antigua y compleja que necesita un segundo modelo (un crítico) y mucha memoria de GPU. GRPO es una receta más moderna y sencilla que elimina al crítico y ahorra memoria al comparar las respuestas entre sí.

El ciclo de aprendizaje por refuerzo subyacente

El RL genérico funciona en un ciclo: el agente observa un estado, elige una acción, el entorno cambia, llega una recompensa y luego aparece un nuevo estado. Cuando PPO (Optimización de Políticas Proximal) se aplicó a los modelos de lenguaje, el modelo de lenguaje pasó a ser el agente, y la configuración incluía tres componentes:

  1. la política de generación, que es el modelo que se está entrenando actualmente
  2. la política de referencia, el modelo original mantenido congelado
  3. el modelo de valor, que estima una recompensa promedio

Un modelo de recompensas califica las salidas, y el entrenamiento busca elevar esa puntuación.

PPO sigue un diseño de tipo actor-critic, lo que significa que se entrenan dos redes separadas. El actor es el propio LLM. El critic es una red de valor de tamaño similar que predice la recompensa que debería obtener una respuesta. Tener ambos duplica aproximadamente la memoria necesaria durante el entrenamiento.

GRPO no cuenta con critic. Al eliminarlo, el uso de memoria disminuye a aproximadamente la mitad. Para la línea base, GRPO genera un grupo de respuestas al mismo prompt, califica cada una y utiliza el promedio del grupo como punto de referencia para determinar cuáles respuestas fueron mejores o peores que las demás.

DeepSeek presentó GRPO en su artículo DeepSeekMath de 2024, y posteriormente este método se integró en DeepSeek-R1.

Las cinco cantidades que sustentan a GRPO

El método se basa en cinco conceptos. Para cada uno de ellos, el objetivo es explicar qué mide y por qué se diseñó de esa manera.

1. La relación de políticas: ¿cuánto cambió la opinión del modelo?

Esta relación compara la probabilidad que el modelo actualizado asigna a una respuesta con la probabilidad que le daba el modelo anterior: la nueva probabilidad de respuesta y para el estímulo x, dividida por la antigua.

Si eliminamos los símbolos, lo que esta relación pregunta es cuán más o menos probable es ahora que el modelo genere esa respuesta en comparación con antes de este paso de entrenamiento.

Imagínese a un estudiante antes y después de pasar una noche repasando. Algunas respuestas ahora parecen más obvias y otras menos. La relación refleja ese cambio en la confianza.

  • Más de 1 significa que el modelo tiene más confianza en la respuesta que antes.
  • Menos de 1 significa que la confianza ha disminuido y el modelo se está alejando de esa respuesta.
  • Exactamente 1 significa que la actualización no cambió nada en esta respuesta.

¿Por qué es importante? En el aprendizaje por refuerzo tradicional podrías decir que una respuesta con alta recompensa merece un gran aumento en su probabilidad. Eso es arriesgado, porque forzar demasiado puede hacer que el modelo varíe de forma excesiva y pierda comportamientos positivos solo porque una respuesta tuvo suerte. La relación funciona como un límite de velocidad: GRPO limita los grandes cambios para que el modelo evolucione de manera gradual y no de forma errática.

2. La recompensa promedio: ¿cuál fue la puntuación promedio de este lote?

La media es la suma de las recompensas del grupo de G respuestas, dividida entre G. G es la cantidad de respuestas muestreadas para una pregunta, y cada respuesta recibe una puntuación del modelo de recompensas.

Imaginemos que le pedimos a un modelo que resuelva un problema de matemáticas y obtenemos cinco respuestas de forma aleatoria. Una es perfecta (recompensa 1.0), otra parcialmente correcta (0.5) y una tercera claramente incorrecta (0.0). La media indica qué tan bien lo hace el modelo en este problema en este momento.

El papel que desempeña es lo que hace tan interesante a GRPO. PPO necesitaba un crítico, una segunda red cuya única función era predecir la recompensa esperada, y entrenarla resultaba costoso, consumía mucha memoria y era propenso a errores. GRPO se pregunta por qué predecir el promedio cuando se puede calcular directamente. Al muestrear un grupo y promediar las recompensas reales se obtiene la línea de referencia de forma gratuita, sin necesidad de una red adicional ni uso innecesario de memoria. Este es el “grupo” en el nombre del método.

3. La desviación estándar: ¿qué tan dispersos están los resultados?

La desviación estándar mide cuán lejos se encuentra cada recompensa en relación con la media, tomando la raíz cuadrada de la diferencia promedio al cuadrado. Mientras que la media describe el rendimiento típico, esta métrica refleja la consistencia.

Un valor alto indica que las respuestas son muy variables, algunas excelentes y otras terribles. Un valor bajo significa que el modelo produce respuestas de calidad similar en cada ocasión.

Considérense dos estudiantes. El estudiante A obtiene calificaciones de 90, 10, 95, 5 y 88, con una media de 57.6 y una gran dispersión: extremadamente inconsistente. El estudiante B obtiene calificaciones de 58, 56, 60, 57 y 59, con una media de 58 y una dispersión mínima: consistentemente mediocre.

En GRPO, la desviación funciona como un normalizador. Cuando las respuestas varían mucho, las diferencias entre las recompensas contienen información relevante y justifican actualizaciones más significativas. Cuando el modelo ya es consistente, las pequeñas diferencias en las recompensas pueden ser ruido, por lo que las actualizaciones deben realizarse con más cautela.

4. La ventaja relativa al grupo: ¿superó esta respuesta a las demás?

Este es el núcleo del método. La ventaja de la respuesta i se calcula como su recompensa menos el promedio del grupo, dividido por la desviación estándar del grupo. Esto convierte las recompensas brutas en una puntuación relativa que impulsa el aprendizaje.

La resta indica cuán mejor o peor es la respuesta en comparación con el promedio. La división permite escalar las puntuaciones según la dispersión, de modo que sean comparables entre preguntas y a lo largo de los pasos de entrenamiento.

Imagínese calificar un examen muy difícil cuyo promedio de la clase es de 40 sobre 100. Un estudiante obtiene una puntuación de 60. Como marca bruta, eso suena mediocre, pero en relación con la clase está 20 puntos por encima del promedio, lo cual es excelente. La ventaja funciona de la misma manera: ignora los valores absolutos de las recompensas y pregunta si esta respuesta supera lo que el modelo suele producir para ese mismo estímulo.

Tres propiedades hacen que esto sea útil.

  1. Sin crítico. La ventaja de PPO dependía de que un crítico estimara la recompensa esperada. GRPO sustituye esa conjetura por un promedio empírico del grupo.
  2. Autocalibración. Si el modelo de recompensas está sesgado y califica todo de forma excesivamente alta o baja, la forma relativa cancela ese sesgo. Solo importa el ranking dentro del grupo.
  3. Estabilidad. Gracias a la normalización, la velocidad de aprendizaje se adapta. Cuando el modelo explora ampliamente, las actualizaciones son drásticas. A medida que converge, estas se suavizan.

5. La penalización KL: mantente reconociblemente tú mismo

Este es el freno de seguridad. Mientras que GRPO empuja al modelo hacia respuestas con altas recompensas, el término KL tira en la dirección opuesta y indica que no se debe convertir en otra persona. Compara el modelo actual con el modelo de referencia congelado, que suele ser el modelo base de antes de que comenzara el RL. La divergencia KL es una medida de cuán separadas están dos distribuciones de probabilidad. La fórmula que se muestra es una estimación por token comúnmente utilizada, basada en la relación entre las probabilidades de referencia y las actuales.

Imagínese el modelo base como un generalista muy culto que puede escribir poesía, depurar código y resumir noticias. Ahora se aplica RL para convertirlo en un genio de las matemáticas. Sin el término KL, podría obsesionarse tanto con las recompensas matemáticas que olvide todo lo demás, incluso generando tonterías con toque matemático para solicitudes no relacionadas.

Un valor bajo de KL significa que el modelo sigue pareciéndose a su versión original. Un valor alto indica que se ha desviado mucho, quizás por sobreajuste al modelo de recompensas o por pérdida de capacidad general.

Los modelos de recompensas son imperfectos y pueden ser manipulados. Un modelo sin término KL podría descubrir que comenzar con “Déjame pensar paso a paso” le genera una recompensa adicional incluso cuando no añade nada. El anclaje en los bloques de referencia facilita este tipo de manipulación de recompensas. En la práctica, el término KL se incluye en la función de pérdida con un peso pequeño, entre 0.01 y 0.04. No está allí para detener el progreso, sino solo para mantenerlo equilibrado.

La actualización completa en palabras sencillas

  1. Generar un grupo de respuestas a una pregunta.
  2. Evaluar cada una con el modelo de recompensas.
  3. Calcular la media y la desviación estándar de esas puntuaciones.
  4. Determinar la ventaja de cada respuesta, es decir, cuánto está por encima o por debajo del promedio.
  • Verifique la relación de políticas para observar cuánta confianza en cada respuesta ha cambiado.
  • Suprima los cambios grandes para que el modelo no varíe excesivamente.
  • Penalice la desviación con respecto a la referencia mediante el término KL.
  • Actualice el modelo para favorecer las respuestas con una alta ventaja relativa.
  • El resultado es un modelo que aprende a razonar, no memorizando respuestas correctas, sino descubriendo qué patrones de pensamiento superan regularmente su propio promedio.

    De las ecuaciones a trainer.train()

    Una vez cubiertas las matemáticas, aquí está el código que lo pone en práctica. Utiliza Unsloth para cargar un modelo Llama 3.2 3B Instruct de 4 bits con backend vLLM, adjunta adaptadores LoRA, impone un formato de razonamiento a través de una prompt de sistema y construye el conjunto de entrenamiento a partir de GSM8K. vLLM está presente porque GRPO necesita generar muchas completaciones por prompt de forma rápida.

    from unsloth import FastLanguageModel
    from datasets import load_dataset
    import re
    
    # 1. Load 4-bit model with vLLM backend for fast group generation
    model, tokenizer = FastLanguageModel.from_pretrained(
        model_name="unsloth/Llama-3.2-3B-Instruct",
        max_seq_length=1024,
        load_in_4bit=True,
        fast_inference=True,
        max_lora_rank=32,
        gpu_memory_utilization=0.6,
    )
    
    # 2. Attach LoRA adapters
    model = FastLanguageModel.get_peft_model(
        model,
        r=32,
        target_modules=["q_proj","k_proj","v_proj","o_proj","gate_proj","up_proj","down_proj"],
        lora_alpha=64,
        use_gradient_checkpointing="unsloth",
    )
    
    # 3. Enforcing reasoning format - GRPO needs structure to reward
    SYSTEM_PROMPT = "Respond in the following format:\n<reasoning>\n...\n</reasoning>\n<answer>\n...\n</answer>"
    
    # 4. Load GSM8K and wrap prompts
    dataset = load_dataset("openai/gsm8k", "main")["train"]
    dataset = dataset.map(lambda x: {
        "prompt": [
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": x["question"]}
        ],
        "answer": x["answer"].split("####")[1].strip()
    })
    #vLLM is used in GRPO because GRPO requires the AI to generate a ma
    

    Funciones de recompensa

    El diseño de las recompensas es la parte más delicada del ajuste fino de GRPO. Si se hace mal, el modelo aprende a manipular las reglas de puntuación en lugar de razonar. Las puntuaciones individuales se suman para obtener la recompensa bruta que sirve de base para el cálculo de ventaja. El conjunto a continuación incluye cinco funciones, cada una con un motivo para existir.

    1. correctness_reward es la señal principal. Extrae el texto dentro de las etiquetas de respuesta y asigna 2.0 cuando hay coincidencia con la solución correcta, y 0.0 en caso contrario. El peso se elige intencionadamente alto para que tener razón siempre supere la importancia de presentar un formato ordenado.
    2. int_reward funciona como red de seguridad. Al principio del entrenamiento casi todo está incorrecto, por lo que asigna 0.5 solo por producir un número válido, lo cual mantiene activo algún tipo de señal de aprendizaje hasta que el modelo comienza a resolver problemas.
  • soft_format_reward y strict_format_reward recompensan la estructura de etiquetas “razonamiento-luego-respuesta” con 0.5 cada una. La versión suave tolera diferencias en el diseño, mientras que la estricta exige una colocación exacta. Juntas ayudan a transformar la salida de desordenada a ordenada.
  • xmlcount_reward paga 0.125 por cada etiqueta en su lugar correcto y resta una pequeña cantidad por etiquetas duplicadas o texto adicional después de la respuesta. Es un detalle sutil que suma efecto con el tiempo.
  • Por separado, cada función es simple. En conjunto, la corrección guía el proceso, el formato proporciona orientación y los detalles se manejan solos.

    def extract_xml_answer(text: str) -> str:
        return text.split("<answer>")[-1].split("</answer>")[0].strip()
    
    # Primary signal: is the final answer correct?
    def correctness_reward(prompts, completions, answer, **kwargs):
        responses = [c[0]["content"] for c in completions]
        extracted = [extract_xml_answer(r) for r in responses]
        return [2.0 if r == a else 0.0 for r, a in zip(extracted, answer)]
    
    # Dense shaping rewards - keep learning signal alive even when answers are wrong
    def int_reward(completions, **kwargs):
        return [0.5 if extract_xml_answer(c[0]["content"]).isdigit() else 0.0 for c in completions]
    
    def strict_format_reward(completions, **kwargs):
        pattern = r"^<reasoning>\n.*?\n</reasoning>\n<answer>\n.*?\n</answer>\nquot;
        return [0.5 if re.match(pattern, c[0]["content"]) else 0.0 for c in completions]
    
    def soft_format_reward(completions, **kwargs):
        pattern = r"<reasoning>.*?</reasoning>\s*<answer>.*?</answer>"
        return [0.5 if re.match(pattern, c[0]["content"]) else 0.0 for c in completions]
    
    def xmlcount_reward(completions, **kwargs):
        def score(text):
            count = 0.0
            if text.count("<reasoning>\n") == 1: count += 0.125
            if text.count("\n</reasoning>\n") == 1: count += 0.125
            if text.count("\n<answer>\n") == 1:
                count += 0.125
                count -= len(text.split("\n</answer>\n")[-1]) * 0.001
            if text.count("\n</answer>") == 1:
                count += 0.125
                count -= (len(text.split("\n</answer>")[-1]) - 1) * 0.001
            return count
        return [score(c[0]["content"]) for c in completions]pyt
    

    El entrenador

    from trl import GRPOConfig, GRPOTrainer
    
    trainer = GRPOTrainer(
        model=model,
        processing_class=tokenizer,
        reward_funcs=[
            xmlcount_reward,      # tag quality
            soft_format_reward,   # structure (forgiving)
            strict_format_reward, # structure (exact)
            int_reward,           # partial credit
            correctness_reward,   # ground-truth match
        ],
        args=GRPOConfig(
            learning_rate=5e-6,
            per_device_train_batch_size=1,
            gradient_accumulation_steps=1,
            num_generations=8,          # G = group size
            max_prompt_length=256,
            max_completion_length=200,
            max_steps=250,
            warmup_ratio=0.1,
            max_grad_norm=0.1,
            output_dir="outputs",
        ),
        train_dataset=dataset,
    )
    
    trainer.train()
    

    En cada paso, GRPOTrainer realiza los cinco cálculos descritos anteriormente.

    Por qué DPO tiene dificultades con el razonamiento

    DPO es elegante porque evita por completo el aprendizaje por refuerzo. Reformula el problema como un problema de clasificación: dado un estímulo y dos respuestas, se aprende a preferir la ganadora. Esto funciona bien cuando las etiquetas de preferencia son precisas.

    No obstante, el razonamiento no es realmente un problema de preferencia; es un problema de búsqueda.

    Supongamos que se quiere que un modelo demuestre un teorema de geometría. DPO necesita a una persona o a un modelo más potente para indicar cuál de las dos demostraciones es mejor. ¿Qué pasa si ambas están equivocadas? ¿Y si la demostración correcta requiere 12 pasos y nunca se seleccionó? DPO solo aprende de las parejas que se le proporcionan y no puede descubrir una nueva estrategia de razonamiento.

    GRPO genera un grupo de respuestas a la misma pregunta, las califica y determina cuáles superan el promedio. Eso significa que explora; puede encontrar un razonamiento poco común, calificarlo bien y reforzarlo, sin que nadie haya seguido ese camino con anterioridad.

    En pocas palabras, DPO es más económico de ejecutar pero limita al modelo a la calidad de sus datos de preferencia. GRPO cuesta más por paso, pero puede ir más allá de los datos etiquetados por humanos para llegar a razonamientos verdaderamente nuevos.

    Pensamientos finales

    GRPO enseña a un modelo a razonar al aprender cuáles de sus propias respuestas superan su promedio. Eliminar al crítico reduce el uso de memoria manteniendo intacto la señal de aprendizaje, y con funciones de recompensa adecuadas además de muestreo por grupos se puede mejorar el razonamiento de un modelo local en una sola GPU. Recompense el comportamiento que realmente desea, mantenga al modelo estable y vigile el valor KL.

    Lecturas relacionadas