Em 20 de janeiro de 2025, a DeepSeek lançou o R1 — e a comunidade descobriu que o "segredo" do o1 da OpenAI não exigia bilhões em P&D fechada. GRPO (Group Relative Policy Optimization) + reward rule-based + paciência computacional bastam para desbloquear reasoning emergente. Este módulo destrincha o algoritmo, o paper e como reproduzir em 2026.
O paper que mudou o mercado
DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning (DeepSeek-AI, jan 2025 — arxiv.org/abs/2501.12948). Pontos-chave:
GRPO: a equação central
GRPO foi formalizado em DeepSeekMath (Shao et al. 2024). Para cada prompt q, sample G respostas {o_1, ..., o_G} de π_old, compute rewards {r_1, ..., r_G}, normalize dentro do grupo, otimize loss PPO-like com KL penalty contra π_ref:
A diferença vs PPO: sem L^VF (não há value head), sem GAE (advantage é direto do grupo). Em troca, exige G respostas por prompt — mas elas são processadas em paralelo (vLLM) amortizando KV-cache.
Reward rule-based: o que é verificável
| Domínio | Verificador | Reward |
|---|---|---|
| Math (AIME, MATH, GSM8K) | sympy parsing + comparação exata | +1 se correto, 0 caso contrário |
| Code (LiveCodeBench) | sandboxed execution + unit tests | +1 se todos passam, 0 senão |
| Lógica formal | theorem prover (Lean, Coq, Isabelle) | +1 se prova é aceita |
| Format | regex de tags <think></think> | +0.1 se formato correto |
| Helpfulness (R1 etapa 4) | RM neural treinado em preferences | score contínuo do RM |
Reward rule-based só funciona em domínios verificáveis. Para tasks subjetivas (criatividade, escrita, conversa), você precisa de RM neural — e aí volta o risco de reward hacking. R1 mistura: rule-based no reasoning, RM neural no SFT/etapa-4.
Pipeline DeepSeek-R1 completo
Reproduzindo R1-Zero com Unsloth
# Reprodução R1-Zero estilo Qwen2.5-7B em H100 80GB
# Baseado em unsloth.ai/blog/r1-reasoning (fev/2025)
from unsloth import FastLanguageModel, PatchFastRL
PatchFastRL("GRPO", FastLanguageModel)
from datasets import load_dataset
from trl import GRPOConfig, GRPOTrainer
import re
# 1. Modelo base
model, tokenizer = FastLanguageModel.from_pretrained(
"Qwen/Qwen2.5-7B-Instruct",
max_seq_length=2048,
load_in_4bit=False,
fast_inference=True, # habilita vLLM rollout
max_lora_rank=64,
gpu_memory_utilization=0.6,
)
# 2. Dataset matemático verificável (GSM8K)
dataset = load_dataset("openai/gsm8k", "main", split="train")
def format_prompt(example):
return {
"prompt": [
{"role": "system", "content": "Responda em <think>...</think> seguido da resposta final."},
{"role": "user", "content": example["question"]},
],
"answer": example["answer"].split("####")[-1].strip(),
}
dataset = dataset.map(format_prompt)
# 3. Reward functions (rule-based)
def correctness_reward(prompts, completions, answer, **kwargs):
rewards = []
for completion, ref in zip(completions, answer):
text = completion[0]["content"]
match = re.search(r"</think>\s*(.+)", text, re.DOTALL)
if match and match.group(1).strip() == ref:
rewards.append(1.0)
else:
rewards.append(0.0)
return rewards
def format_reward(completions, **kwargs):
pattern = r"<think>.+?</think>.+"
return [0.5 if re.search(pattern, c[0]["content"], re.DOTALL) else 0.0
for c in completions]
# 4. GRPO config
config = GRPOConfig(
output_dir="qwen-grpo",
learning_rate=5e-6,
num_generations=16, # G do grupo
max_prompt_length=512,
max_completion_length=1024,
per_device_train_batch_size=1,
gradient_accumulation_steps=4,
num_train_epochs=1,
beta=0.04, # KL penalty
)
trainer = GRPOTrainer(
model=model,
reward_funcs=[correctness_reward, format_reward],
args=config,
train_dataset=dataset,
tokenizer=tokenizer,
)
trainer.train()Em ~4–8h numa H100, esse loop reproduz qualitativamente os "aha moments": após algumas centenas de steps, o modelo começa a escrever CoTs mais longos, voltar atrás e reescrever, e o reward de correctness no GSM8K sobe de ~60% para ~85%+.
DPO/PPO/GRPO — comparativo
| Aspecto | PPO (RLHF) | DPO | GRPO |
|---|---|---|---|
| Reward Model | Neural, treinado | Implícito (sem RM) | Rule-based ou Neural |
| Value/Critic | Sim (value head) | Não | Não (group baseline) |
| Rollouts on-policy | Sim | Não (off-policy) | Sim (grupo de G) |
| Memória relativa | 4× modelo | 2× modelo | ~2× modelo |
| Hackeável? | Sim (RM hack) | Limitado | Não (se rule-based) |
| Reasoning emergente | Não tipicamente | Não | Sim (R1-Zero) |
| Custo total | Alto | Baixo | Médio |
📋 Você quer um modelo melhor em matemática/código. Tem GPUs e dataset verificável.
Domínios verificáveis (math, code, logic) são exatamente onde GRPO brilha. Reward não-hackeável + group advantage sem critic = reasoning emerge. Dispense PPO complexity.
Alt: SFT em CoTs do R1 —
Alt: DPO em pares (CoT bom vs CoT ruim) —
Linha do tempo
Perguntas frequentes
❓ GRPO funciona em tasks sem verificador rule-based?
❓ Por que group size = 16–64 e não 4 ou 256?
❓ GRPO precisa de SFT antes?
❓ Existe limite teórico para reasoning emergente via GRPO?